@seqyuan/annodex 0.1.11 → 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/chunks/0b9a0da7.9075af772487e743.js +0 -62
  356. package/.next/static/chunks/1413.922d232de90c0c41.js +0 -115
  357. package/.next/static/chunks/1643.467a526a1f24f54d.js +0 -24
  358. package/.next/static/chunks/1852.5543122f11aa7fed.js +0 -1
  359. package/.next/static/chunks/1960.b1e26436d7a5f586.js +0 -1
  360. package/.next/static/chunks/2170a4aa.4213bb2183c9cdf9.js +0 -1
  361. package/.next/static/chunks/2274.6cd173f80a1405a2.js +0 -21
  362. package/.next/static/chunks/2419.347fdfe3c170854d.js +0 -166
  363. package/.next/static/chunks/2619.9aac8983f30c7c8a.js +0 -1
  364. package/.next/static/chunks/2623.d20fabd8e18197c6.js +0 -287
  365. package/.next/static/chunks/2729.f5365061a849d659.js +0 -34
  366. package/.next/static/chunks/2821.934bcf60fbdc28c6.js +0 -1
  367. package/.next/static/chunks/2918becc.abff2ece1de37bc1.js +0 -153
  368. package/.next/static/chunks/2947.114e51cb06d1c01a.js +0 -23
  369. package/.next/static/chunks/3079.4c511fa1144e3adf.js +0 -79
  370. package/.next/static/chunks/3274.208ca44844cd7d95.js +0 -148
  371. package/.next/static/chunks/3308.465a94263d04bfea.js +0 -73
  372. package/.next/static/chunks/3325.e4bfe1ca657f3b5b.js +0 -80
  373. package/.next/static/chunks/3506.2a7eaa08b9f55337.js +0 -90
  374. package/.next/static/chunks/363642f4-043c1475ab9af70e.js +0 -1
  375. package/.next/static/chunks/3794-123fdf632563f469.js +0 -32
  376. package/.next/static/chunks/3837.a755ccfe6f9c1c1c.js +0 -5
  377. package/.next/static/chunks/394.91597771688df6d0.js +0 -1
  378. package/.next/static/chunks/3997.1009c06025691712.js +0 -1
  379. package/.next/static/chunks/4453.91a357dc43c21745.js +0 -1
  380. package/.next/static/chunks/4491.44fdf20580ac72bd.js +0 -24
  381. package/.next/static/chunks/4829.cf1d50e43e6d9db5.js +0 -1
  382. package/.next/static/chunks/498.fe1d9da9ecad6c36.js +0 -1
  383. package/.next/static/chunks/4bd1b696-e356ca5ba0218e27.js +0 -1
  384. package/.next/static/chunks/5019.b5a1a2b8daf17525.js +0 -1
  385. package/.next/static/chunks/5034.8f16c3fa3ce75411.js +0 -1
  386. package/.next/static/chunks/5074.d16651da01ec4e02.js +0 -1
  387. package/.next/static/chunks/51fb665c.0950e1b79671348d.js +0 -45
  388. package/.next/static/chunks/532.5956ed631aff722b.js +0 -9
  389. package/.next/static/chunks/5326.69460442bdcd6cd3.js +0 -1
  390. package/.next/static/chunks/5403.ff110bf5bf600758.js +0 -64
  391. package/.next/static/chunks/547.902a733488cfe3f7.js +0 -77
  392. package/.next/static/chunks/5567.540d7fc108ad6ee5.js +0 -215
  393. package/.next/static/chunks/5590.ef62922166d308b4.js +0 -1
  394. package/.next/static/chunks/5690.9d6eb1edb1399995.js +0 -1
  395. package/.next/static/chunks/5749.25faee4a1e55b854.js +0 -226
  396. package/.next/static/chunks/58bb9007.1ccb6bba34b4c635.js +0 -80
  397. package/.next/static/chunks/6121.f3f43f1896ea0cd9.js +0 -1
  398. package/.next/static/chunks/6600.583c88eef37aa524.js +0 -1
  399. package/.next/static/chunks/6696.a41aec266e657d54.js +0 -141
  400. package/.next/static/chunks/6922.42148793782d2fe7.js +0 -1
  401. package/.next/static/chunks/7006.e191611ffc2b9528.js +0 -43
  402. package/.next/static/chunks/7343.9fbb58204d8ac681.js +0 -1
  403. package/.next/static/chunks/73972abe.25a4cffa03b2bcef.js +0 -119
  404. package/.next/static/chunks/7547.58bda8a2aabba0d4.js +0 -93
  405. package/.next/static/chunks/7648.4ae2f183b4db0353.js +0 -1
  406. package/.next/static/chunks/7874.8db6929b94cdf697.js +0 -1
  407. package/.next/static/chunks/7959.1f20a35df316216a.js +0 -104
  408. package/.next/static/chunks/83.85d62d7fc9850b75.js +0 -29
  409. package/.next/static/chunks/8436.cab94b59cca0a8ff.js +0 -1
  410. package/.next/static/chunks/8451.ff6ff72b57dc52e1.js +0 -1
  411. package/.next/static/chunks/8489.45f22859734f514f.js +0 -36
  412. package/.next/static/chunks/8568.f85d8b36fc9a9037.js +0 -1
  413. package/.next/static/chunks/8771-3e14b6810486df1f.js +0 -1
  414. package/.next/static/chunks/8863.be51033a67436277.js +0 -1
  415. package/.next/static/chunks/90542734.dc1a2723e4f6affb.js +0 -1
  416. package/.next/static/chunks/9500.1488aec06ee78127.js +0 -1
  417. package/.next/static/chunks/9633.155548b5fca6e580.js +0 -1
  418. package/.next/static/chunks/9779.673004a62d70e36a.js +0 -1
  419. package/.next/static/chunks/app/_global-error/page-cc518af6b1ffb191.js +0 -1
  420. package/.next/static/chunks/app/_not-found/page-c72daab99269beff.js +0 -1
  421. package/.next/static/chunks/app/api/agent/[id]/events/route-cc518af6b1ffb191.js +0 -1
  422. package/.next/static/chunks/app/api/agent/[id]/route-cc518af6b1ffb191.js +0 -1
  423. package/.next/static/chunks/app/api/agent/new/route-cc518af6b1ffb191.js +0 -1
  424. package/.next/static/chunks/app/api/auth/all-providers/route-cc518af6b1ffb191.js +0 -1
  425. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-cc518af6b1ffb191.js +0 -1
  426. package/.next/static/chunks/app/api/auth/login/[provider]/route-cc518af6b1ffb191.js +0 -1
  427. package/.next/static/chunks/app/api/auth/login/route-cc518af6b1ffb191.js +0 -1
  428. package/.next/static/chunks/app/api/auth/logout/[provider]/route-cc518af6b1ffb191.js +0 -1
  429. package/.next/static/chunks/app/api/auth/providers/route-cc518af6b1ffb191.js +0 -1
  430. package/.next/static/chunks/app/api/auth/status/route-cc518af6b1ffb191.js +0 -1
  431. package/.next/static/chunks/app/api/default-cwd/route-cc518af6b1ffb191.js +0 -1
  432. package/.next/static/chunks/app/api/files/[...path]/route-cc518af6b1ffb191.js +0 -1
  433. package/.next/static/chunks/app/api/harness/route-cc518af6b1ffb191.js +0 -1
  434. package/.next/static/chunks/app/api/home/route-cc518af6b1ffb191.js +0 -1
  435. package/.next/static/chunks/app/api/internal/runtime/route-cc518af6b1ffb191.js +0 -1
  436. package/.next/static/chunks/app/api/models/route-cc518af6b1ffb191.js +0 -1
  437. package/.next/static/chunks/app/api/models-config/discover/route-cc518af6b1ffb191.js +0 -1
  438. package/.next/static/chunks/app/api/models-config/route-cc518af6b1ffb191.js +0 -1
  439. package/.next/static/chunks/app/api/models-config/test/route-cc518af6b1ffb191.js +0 -1
  440. package/.next/static/chunks/app/api/projects/browse/route-cc518af6b1ffb191.js +0 -1
  441. package/.next/static/chunks/app/api/projects/route-cc518af6b1ffb191.js +0 -1
  442. package/.next/static/chunks/app/api/reports/[id]/route-cc518af6b1ffb191.js +0 -1
  443. package/.next/static/chunks/app/api/search/route-cc518af6b1ffb191.js +0 -1
  444. package/.next/static/chunks/app/api/sessions/[id]/context/route-cc518af6b1ffb191.js +0 -1
  445. package/.next/static/chunks/app/api/sessions/[id]/route-cc518af6b1ffb191.js +0 -1
  446. package/.next/static/chunks/app/api/sessions/new/route-cc518af6b1ffb191.js +0 -1
  447. package/.next/static/chunks/app/api/sessions/route-cc518af6b1ffb191.js +0 -1
  448. package/.next/static/chunks/app/api/settings/route-cc518af6b1ffb191.js +0 -1
  449. package/.next/static/chunks/app/api/skills/install/route-cc518af6b1ffb191.js +0 -1
  450. package/.next/static/chunks/app/api/skills/route-cc518af6b1ffb191.js +0 -1
  451. package/.next/static/chunks/app/api/skills/search/route-cc518af6b1ffb191.js +0 -1
  452. package/.next/static/chunks/app/api/soul/route-cc518af6b1ffb191.js +0 -1
  453. package/.next/static/chunks/app/api/version/route-cc518af6b1ffb191.js +0 -1
  454. package/.next/static/chunks/app/layout-be148b7ae915b22a.js +0 -1
  455. package/.next/static/chunks/app/login/page-ebf0e6de99062783.js +0 -1
  456. package/.next/static/chunks/app/page-a4bfb7d711561cb3.js +0 -260
  457. package/.next/static/chunks/d3ac728e.7964f816a1ca64e5.js +0 -1
  458. package/.next/static/chunks/framework-711ef29bc66f648c.js +0 -1
  459. package/.next/static/chunks/main-app-45a0f19af99d61b6.js +0 -1
  460. package/.next/static/chunks/main-f74964b7ae52493e.js +0 -5
  461. package/.next/static/chunks/next/dist/client/components/builtin/app-error-cc518af6b1ffb191.js +0 -1
  462. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-cc518af6b1ffb191.js +0 -1
  463. package/.next/static/chunks/next/dist/client/components/builtin/global-error-9bfa08b9491621f2.js +0 -1
  464. package/.next/static/chunks/next/dist/client/components/builtin/not-found-cc518af6b1ffb191.js +0 -1
  465. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-cc518af6b1ffb191.js +0 -1
  466. package/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  467. package/.next/static/chunks/webpack-fcf4a889ecbd753c.js +0 -1
  468. package/.next/static/css/45029451a1d7255d.css +0 -3
  469. package/.next/static/lFCcFmLd1ThQXTFUP6olh/_buildManifest.js +0 -1
  470. package/.next/static/lFCcFmLd1ThQXTFUP6olh/_ssgManifest.js +0 -1
  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,796 @@
1
+ /**
2
+ * Codex App-Server Process Manager
3
+ *
4
+ * Manages the lifecycle of `codex app-server` sub-processes — one per workspace (cwd).
5
+ * Provides WebSocket JSON-RPC connections to the app-server.
6
+ *
7
+ * Protocol: JSON-RPC 2.0 over WebSocket
8
+ * - codex app-server --listen ws://127.0.0.1:{port}
9
+ * - annodex connects as JSON-RPC client
10
+ *
11
+ * Key methods:
12
+ * thread/start - start new conversation thread
13
+ * thread/resume - continue existing thread
14
+ * thread/fork - branch from a point in history
15
+ * thread/rollback - navigate to a previous point
16
+ * thread/compact/start - compact context
17
+ * thread/list - list all threads
18
+ * thread/read - read thread details
19
+ * thread/name/set - rename thread
20
+ */
21
+
22
+ import { spawn, ChildProcess, execSync } from "child_process";
23
+ import { WebSocket } from "ws";
24
+ import { existsSync } from "fs";
25
+ import { join } from "path";
26
+ import { createServer } from "net";
27
+ import { CompatProxy, chatCompletionsUrl, needsCompatProxy } from "./codex-compat-proxy";
28
+ import type { ReasoningConfig } from "./provider-api";
29
+ import type { ProviderConfig } from "./annodex-config";
30
+ import { APP_NAME } from "./brand";
31
+ import { normalizeProviderApi } from "./provider-api";
32
+ import packageJson from "../package.json";
33
+
34
+ // ============================================================================
35
+ // Types
36
+ // ============================================================================
37
+
38
+ export interface JsonRpcRequest {
39
+ jsonrpc: "2.0";
40
+ id: string | number;
41
+ method: string;
42
+ params?: unknown;
43
+ }
44
+
45
+ export interface JsonRpcResponse {
46
+ jsonrpc: "2.0";
47
+ id: string | number;
48
+ result?: unknown;
49
+ error?: { code: number; message: string; data?: unknown };
50
+ }
51
+
52
+ export interface JsonRpcNotification {
53
+ jsonrpc: "2.0";
54
+ method: string;
55
+ params?: unknown;
56
+ }
57
+
58
+ export type JsonRpcMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;
59
+
60
+ export type CodexUserInput =
61
+ | { type: "text"; text: string; text_elements: unknown[] }
62
+ | { type: "image"; url: string }
63
+ | { type: "localImage"; path: string }
64
+ | { type: "skill"; name: string; path: string }
65
+ | { type: "mention"; name: string; path: string };
66
+
67
+ export type CodexThreadItem =
68
+ | { type: "userMessage"; id: string; content: CodexUserInput[] }
69
+ | { type: "hookPrompt"; id: string; fragments: unknown[] }
70
+ | { type: "agentMessage"; id: string; text: string; phase?: string | null; memoryCitation?: unknown }
71
+ | { type: "reasoning"; id: string; summary?: string[]; content?: string[] }
72
+ | { type: "plan"; id: string; text: string }
73
+ | {
74
+ type: "commandExecution";
75
+ id: string;
76
+ command: string;
77
+ cwd?: string;
78
+ status?: string;
79
+ aggregatedOutput?: string | null;
80
+ exitCode?: number | null;
81
+ durationMs?: number | null;
82
+ }
83
+ | { type: "fileChange"; id: string; changes?: unknown[]; status?: string }
84
+ | {
85
+ type: "mcpToolCall";
86
+ id: string;
87
+ server: string;
88
+ tool: string;
89
+ status?: string;
90
+ arguments?: unknown;
91
+ result?: unknown;
92
+ error?: unknown;
93
+ }
94
+ | {
95
+ type: "dynamicToolCall";
96
+ id: string;
97
+ tool: string;
98
+ arguments?: unknown;
99
+ status?: string;
100
+ contentItems?: unknown[] | null;
101
+ success?: boolean | null;
102
+ }
103
+ | {
104
+ type: "collabAgentToolCall";
105
+ id: string;
106
+ tool: unknown;
107
+ status?: string;
108
+ senderThreadId?: string;
109
+ receiverThreadIds?: string[];
110
+ prompt?: string | null;
111
+ model?: string | null;
112
+ reasoningEffort?: unknown;
113
+ agentsStates?: unknown;
114
+ }
115
+ | { type: "webSearch"; id: string; query: string; action?: unknown }
116
+ | { type: "imageView"; id: string; path: string }
117
+ | { type: "imageGeneration"; id: string; status: string; revisedPrompt?: string | null; result?: string; savedPath?: string }
118
+ | { type: "enteredReviewMode"; id: string; review: string }
119
+ | { type: "exitedReviewMode"; id: string; review: string }
120
+ | { type: "contextCompaction"; id: string }
121
+ | { type: "unknown"; id: string; [key: string]: unknown };
122
+
123
+ export interface CodexTurn {
124
+ id: string;
125
+ items: CodexThreadItem[];
126
+ status: "completed" | "interrupted" | "failed" | "inProgress" | string;
127
+ error?: { message?: string } | null;
128
+ }
129
+
130
+ export interface CodexThread {
131
+ id: string;
132
+ preview?: string;
133
+ name?: string | null;
134
+ cwd: string;
135
+ path?: string | null;
136
+ createdAt: number;
137
+ updatedAt: number;
138
+ modelProvider?: string;
139
+ status?: unknown;
140
+ turns?: CodexTurn[];
141
+ model?: string;
142
+ }
143
+
144
+ // ============================================================================
145
+ // Codex app-server connection
146
+ // ============================================================================
147
+
148
+ interface PendingRequest {
149
+ resolve: (value: unknown) => void;
150
+ reject: (error: Error) => void;
151
+ timer: ReturnType<typeof setTimeout>;
152
+ }
153
+
154
+ export class CodexServerConnection {
155
+ private ws: WebSocket | null = null;
156
+ private pending = new Map<string | number, PendingRequest>();
157
+ private nextId = 1;
158
+ private notificationHandlers = new Map<string, Array<(params: unknown) => void>>();
159
+ private reconnectAttempts = 0;
160
+ private maxReconnectAttempts = 5;
161
+ private reconnectDelay = 1000;
162
+ private _closed = false;
163
+
164
+ constructor(
165
+ public readonly cwd: string,
166
+ private readonly url: string,
167
+ public readonly serverKey: string,
168
+ ) {}
169
+
170
+ isConnected(): boolean {
171
+ return this.ws?.readyState === WebSocket.OPEN;
172
+ }
173
+
174
+ isClosed(): boolean {
175
+ return this._closed;
176
+ }
177
+
178
+ async connect(): Promise<void> {
179
+ // Dynamic import ws to avoid issues with Next.js bundling
180
+ const { default: WS } = await import("ws");
181
+ const wsUrl = this.url;
182
+ this._closed = false;
183
+
184
+ return new Promise((resolve, reject) => {
185
+ const ws = new WS(wsUrl);
186
+ this.ws = ws;
187
+
188
+ ws.on("open", () => {
189
+ this.reconnectAttempts = 0;
190
+ this.initialize().then(resolve).catch(reject);
191
+ });
192
+
193
+ ws.on("message", (data: Buffer) => {
194
+ try {
195
+ const msg = JSON.parse(data.toString()) as JsonRpcMessage;
196
+ this.handleMessage(msg);
197
+ } catch {
198
+ // ignore parse errors
199
+ }
200
+ });
201
+
202
+ ws.on("close", () => {
203
+ this.handleDisconnect();
204
+ });
205
+
206
+ ws.on("error", (err: Error) => {
207
+ if (this.reconnectAttempts === 0) {
208
+ reject(err);
209
+ }
210
+ });
211
+ });
212
+ }
213
+
214
+ private async initialize(): Promise<void> {
215
+ const result = await this.request("initialize", {
216
+ clientInfo: {
217
+ name: "annodex",
218
+ title: APP_NAME,
219
+ version: packageJson.version,
220
+ },
221
+ capabilities: {
222
+ experimentalApi: true,
223
+ },
224
+ }) as {
225
+ userAgent?: string;
226
+ codexHome?: string;
227
+ };
228
+ // Store server info for later use
229
+ (this as { serverInfo?: unknown }).serverInfo = result;
230
+ }
231
+
232
+ request(method: string, params?: unknown, timeoutMs = 300_000): Promise<unknown> {
233
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
234
+ return Promise.reject(new Error(`Codex server not connected (method: ${method})`));
235
+ }
236
+
237
+ const id = this.nextId++;
238
+ return new Promise((resolve, reject) => {
239
+ const timer = setTimeout(() => {
240
+ this.pending.delete(id);
241
+ reject(new Error(`Request timeout: ${method}`));
242
+ }, timeoutMs);
243
+
244
+ this.pending.set(id, { resolve, reject, timer });
245
+
246
+ const request: JsonRpcRequest = {
247
+ jsonrpc: "2.0",
248
+ id,
249
+ method,
250
+ params,
251
+ };
252
+
253
+ this.ws!.send(JSON.stringify(request));
254
+ });
255
+ }
256
+
257
+ onNotification(method: string, handler: (params: unknown) => void): () => void {
258
+ const handlers = this.notificationHandlers.get(method) ?? [];
259
+ handlers.push(handler);
260
+ this.notificationHandlers.set(method, handlers);
261
+ return () => {
262
+ const list = this.notificationHandlers.get(method);
263
+ if (list) {
264
+ const idx = list.indexOf(handler);
265
+ if (idx !== -1) list.splice(idx, 1);
266
+ }
267
+ };
268
+ }
269
+
270
+ private handleMessage(msg: JsonRpcMessage): void {
271
+ if ("method" in msg && "id" in msg) {
272
+ this.respondToServerRequest(msg);
273
+ return;
274
+ }
275
+
276
+ if ("method" in msg && !("id" in msg)) {
277
+ // Notification
278
+ const handlers = this.notificationHandlers.get(msg.method);
279
+ if (handlers) {
280
+ for (const h of [...handlers]) h(msg.params);
281
+ }
282
+ return;
283
+ }
284
+
285
+ if ("id" in msg && ("result" in msg || "error" in msg)) {
286
+ // Response to our request
287
+ const pending = this.pending.get(msg.id);
288
+ if (pending) {
289
+ clearTimeout(pending.timer);
290
+ this.pending.delete(msg.id);
291
+ if ("error" in msg && msg.error) {
292
+ pending.reject(new Error(msg.error.message ?? "JSON-RPC error"));
293
+ } else {
294
+ pending.resolve(msg.result);
295
+ }
296
+ }
297
+ }
298
+ }
299
+
300
+ private respondToServerRequest(msg: JsonRpcRequest): void {
301
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;
302
+
303
+ const result = defaultServerRequestResult(msg.method);
304
+ const response: JsonRpcResponse = {
305
+ jsonrpc: "2.0",
306
+ id: msg.id,
307
+ result,
308
+ };
309
+ this.ws.send(JSON.stringify(response));
310
+ }
311
+
312
+ private handleDisconnect(): void {
313
+ // Reject all pending requests
314
+ for (const [, pending] of this.pending) {
315
+ clearTimeout(pending.timer);
316
+ pending.reject(new Error("Codex server disconnected"));
317
+ }
318
+ this.pending.clear();
319
+
320
+ if (this._closed) return;
321
+
322
+ // Auto-reconnect
323
+ if (this.reconnectAttempts < this.maxReconnectAttempts) {
324
+ this.reconnectAttempts++;
325
+ const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
326
+ setTimeout(() => {
327
+ if (!this._closed) {
328
+ this.connect().catch(() => {});
329
+ }
330
+ }, delay);
331
+ }
332
+ }
333
+
334
+ close(): void {
335
+ this._closed = true;
336
+ this.ws?.close();
337
+ this.ws = null;
338
+ }
339
+ }
340
+
341
+ function defaultServerRequestResult(method: string): unknown {
342
+ switch (method) {
343
+ case "item/commandExecution/requestApproval":
344
+ return { decision: "decline" };
345
+ case "item/fileChange/requestApproval":
346
+ return { decision: "decline" };
347
+ case "applyPatchApproval":
348
+ case "execCommandApproval":
349
+ return { decision: "denied" };
350
+ case "item/tool/requestUserInput":
351
+ return { answers: {} };
352
+ case "mcpServer/elicitation/request":
353
+ return { action: "decline", content: null, _meta: null };
354
+ case "item/permissions/requestApproval":
355
+ return { permissions: {}, scope: "turn" };
356
+ case "item/tool/call":
357
+ return { contentItems: [], success: false };
358
+ case "account/chatgptAuthTokens/refresh":
359
+ return { accessToken: "", chatgptAccountId: "", chatgptPlanType: null };
360
+ default:
361
+ return {};
362
+ }
363
+ }
364
+
365
+ // ============================================================================
366
+ // Server process manager
367
+ // ============================================================================
368
+
369
+ interface ServerInstance {
370
+ process: ChildProcess;
371
+ connection: CodexServerConnection;
372
+ compatProxy: CompatProxy | null;
373
+ port: number;
374
+ cwd: string;
375
+ refCount: number;
376
+ startPromise: Promise<CodexServerConnection> | null;
377
+ }
378
+
379
+ declare global {
380
+ var __codexServers: Map<string, ServerInstance> | undefined;
381
+ }
382
+
383
+ function stopInstance(instance: ServerInstance): void {
384
+ instance.connection?.close();
385
+ if (instance.process?.pid) {
386
+ try {
387
+ if (process.platform !== "win32") process.kill(-instance.process.pid, "SIGTERM");
388
+ else instance.process.kill("SIGTERM");
389
+ } catch {
390
+ try { instance.process.kill("SIGTERM"); } catch { /* ignore */ }
391
+ }
392
+ }
393
+ instance.compatProxy?.stop().catch(() => {});
394
+ }
395
+
396
+ function getServerRegistry(): Map<string, ServerInstance> {
397
+ if (!globalThis.__codexServers) {
398
+ globalThis.__codexServers = new Map();
399
+ const cleanup = () => {
400
+ globalThis.__codexServers?.forEach((inst) => {
401
+ stopInstance(inst);
402
+ });
403
+ };
404
+ process.once("exit", cleanup);
405
+ process.once("SIGINT", cleanup);
406
+ process.once("SIGTERM", cleanup);
407
+ }
408
+ return globalThis.__codexServers;
409
+ }
410
+
411
+ function findFreePort(): Promise<number> {
412
+ return new Promise((resolve, reject) => {
413
+ const server = createServer();
414
+ server.unref();
415
+ server.on("error", reject);
416
+ server.listen(0, "127.0.0.1", () => {
417
+ const addr = server.address();
418
+ server.close(() => {
419
+ if (addr && typeof addr === "object") resolve(addr.port);
420
+ else reject(new Error("Failed to allocate a local port"));
421
+ });
422
+ });
423
+ });
424
+ }
425
+
426
+ interface CodexExecutableOptions {
427
+ customPath?: string;
428
+ }
429
+
430
+ function getCodexExecutablePath(opts?: CodexExecutableOptions): string {
431
+ if (opts?.customPath) return opts.customPath;
432
+
433
+ // Try npm bin directory first (node_modules/.bin/codex)
434
+ const cwd = process.cwd();
435
+ const npmBinPaths = [
436
+ join(cwd, "node_modules", ".bin", "codex"),
437
+ join(cwd, "..", "..", "node_modules", ".bin", "codex"),
438
+ ];
439
+
440
+ for (const p of npmBinPaths) {
441
+ if (existsSync(p)) return p;
442
+ }
443
+
444
+ // Fall back to system path
445
+ return "codex";
446
+ }
447
+
448
+ export interface CodexServerEnv {
449
+ apiKey?: string;
450
+ baseUrl?: string;
451
+ api?: string;
452
+ contextWindow?: number;
453
+ maxTokens?: number;
454
+ providerId?: string;
455
+ modelId?: string;
456
+ requiresOpenAiAuth?: boolean;
457
+ thinkingLevel?: string;
458
+ reasoningConfig?: ReasoningConfig;
459
+ }
460
+
461
+ function serverKeyFor(cwd: string, env?: CodexServerEnv): string {
462
+ const normalizedCwd = cwd.replace(/\/+$/, "") || cwd;
463
+ const providerKey = env?.providerId || env?.baseUrl || "default";
464
+ const baseUrlKey = env?.baseUrl?.replace(/\/+$/, "") || "default";
465
+ const protocolKey = env?.api || "default";
466
+ const apiKey = env?.apiKey || "default";
467
+ const contextKey = env?.contextWindow ? String(env.contextWindow) : "default";
468
+ // Include reasoning config fingerprint so switching models with different
469
+ // thinking params creates a new compat proxy instead of reusing a stale one.
470
+ const reasoningKey = env?.reasoningConfig
471
+ ? `${env.reasoningConfig.thinkingParam ?? ""}|${env.reasoningConfig.effortParam ?? ""}|${env.reasoningConfig.effortValueMode ?? ""}`
472
+ : "default";
473
+ return `${normalizedCwd}\0${providerKey}\0${baseUrlKey}\0${protocolKey}\0${apiKey}\0${contextKey}\0${reasoningKey}`;
474
+ }
475
+
476
+ /** Build CodexServerEnv from a provider + model config. Shared between
477
+ * rpc-manager (session start / model switch) and session-reader
478
+ * (context loading). */
479
+ export function codexServerEnvForModel(
480
+ providerConfig: ProviderConfig,
481
+ modelId: string | undefined,
482
+ thinkingLevel: string | undefined,
483
+ ): CodexServerEnv {
484
+ const modelDef = providerConfig.models.find((m) => m.id === modelId);
485
+ const api = modelDef?.api ?? providerConfig.api;
486
+ const reasoningConfig = modelDef?.reasoningConfig ?? providerConfig.reasoningConfig;
487
+ return {
488
+ apiKey: providerConfig.apiKey || undefined,
489
+ baseUrl: providerConfig.baseUrl || undefined,
490
+ api: api || undefined,
491
+ contextWindow: modelDef?.contextWindow || undefined,
492
+ providerId: providerConfig.id,
493
+ modelId,
494
+ requiresOpenAiAuth: providerConfig.requiresOpenAiAuth,
495
+ thinkingLevel,
496
+ reasoningConfig,
497
+ };
498
+ }
499
+
500
+ function resolveApiKey(value?: string): string | undefined {
501
+ const trimmed = value?.trim();
502
+ if (!trimmed) return undefined;
503
+ if (trimmed.startsWith("!")) {
504
+ try {
505
+ return execSync(trimmed.slice(1), {
506
+ encoding: "utf8",
507
+ stdio: ["ignore", "pipe", "ignore"],
508
+ timeout: 10_000,
509
+ }).trim() || undefined;
510
+ } catch {
511
+ return undefined;
512
+ }
513
+ }
514
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(trimmed) && process.env[trimmed]) {
515
+ return process.env[trimmed];
516
+ }
517
+ return trimmed;
518
+ }
519
+
520
+ function tomlString(value: string): string {
521
+ return JSON.stringify(value);
522
+ }
523
+
524
+ function tomlKeySegment(value: string): string {
525
+ return /^[A-Za-z0-9_-]+$/.test(value) ? value : tomlString(value);
526
+ }
527
+
528
+ function wireApiFor(api: string | undefined, usingCompatProxy: boolean): "responses" | "chat" | null {
529
+ if (usingCompatProxy) return "responses";
530
+ const normalized = normalizeProviderApi(api);
531
+ if (normalized === "openai-responses") return "responses";
532
+ if (normalized === "openai-completions") return "chat";
533
+ return null;
534
+ }
535
+
536
+ export async function getOrCreateCodexServer(
537
+ cwd: string,
538
+ env?: CodexServerEnv,
539
+ ): Promise<CodexServerConnection> {
540
+ const registry = getServerRegistry();
541
+ const normalizedCwd = cwd.replace(/\/+$/, "") || cwd;
542
+ const registryKey = serverKeyFor(normalizedCwd, env);
543
+
544
+ const existing = registry.get(registryKey);
545
+ if (existing?.connection?.isConnected()) {
546
+ existing.refCount++;
547
+ return existing.connection;
548
+ }
549
+
550
+ // If there's a starting promise, wait for it
551
+ if (existing?.startPromise) {
552
+ try {
553
+ const connection = await existing.startPromise;
554
+ const started = registry.get(registryKey);
555
+ if (started) started.refCount++;
556
+ return connection;
557
+ } catch {
558
+ // Start failed, try again
559
+ }
560
+ } else if (existing) {
561
+ stopInstance(existing);
562
+ registry.delete(registryKey);
563
+ }
564
+
565
+ const port = await findFreePort();
566
+ const wsUrl = `ws://127.0.0.1:${port}`;
567
+ const executable = getCodexExecutablePath();
568
+
569
+ const startPromise = (async (): Promise<CodexServerConnection> => {
570
+ // Start compat proxy if the baseUrl needs Responses→Chat translation
571
+ let compatProxy: CompatProxy | null = null;
572
+ let actualBaseUrl = env?.baseUrl || undefined;
573
+ const resolvedApiKey = resolveApiKey(env?.apiKey);
574
+ const requiresOpenAiAuth = env?.requiresOpenAiAuth ?? Boolean(resolvedApiKey);
575
+ const normalizedApi = normalizeProviderApi(env?.api, actualBaseUrl, env?.providerId);
576
+ const usesChatApi = normalizedApi === "openai-completions";
577
+ let usingCompatProxy = false;
578
+ if (usesChatApi && actualBaseUrl && resolvedApiKey && needsCompatProxy(actualBaseUrl)) {
579
+ const chatUrl = chatCompletionsUrl(actualBaseUrl);
580
+ compatProxy = new CompatProxy({
581
+ targetUrl: chatUrl,
582
+ apiKey: resolvedApiKey,
583
+ defaultThinking: env?.thinkingLevel ?? "disabled",
584
+ reasoningConfig: env?.reasoningConfig,
585
+ });
586
+ try {
587
+ await compatProxy.start();
588
+ actualBaseUrl = compatProxy.getBaseUrl();
589
+ usingCompatProxy = true;
590
+ console.log(`[codex-server] Compat proxy started on port ${compatProxy.getPort()} for ${chatUrl}`);
591
+ } catch (err) {
592
+ console.error(`[codex-server] Failed to start compat proxy:`, err);
593
+ compatProxy = null;
594
+ }
595
+ }
596
+
597
+ // Build env for codex subprocess
598
+ const childEnv: NodeJS.ProcessEnv = { ...process.env };
599
+ if (resolvedApiKey) childEnv.OPENAI_API_KEY = resolvedApiKey;
600
+ if (actualBaseUrl) childEnv.OPENAI_BASE_URL = actualBaseUrl;
601
+
602
+ // Start the app-server process. Workspace selection is passed per request.
603
+ // Global -c config overrides MUST come BEFORE the `app-server` subcommand.
604
+ // Build -c flags first, then prepend app-server args.
605
+ const configFlags: string[] = [];
606
+ // Pass model context window if known (codex uses this for token budgeting)
607
+ if (env?.contextWindow && env.contextWindow > 0) {
608
+ configFlags.push("-c", `model_context_window=${env.contextWindow}`);
609
+ }
610
+ if (env?.providerId && actualBaseUrl) {
611
+ const providerKey = tomlKeySegment(env.providerId);
612
+ const wireApi = wireApiFor(normalizedApi, usingCompatProxy);
613
+ configFlags.push("-c", `model_provider=${tomlString(env.providerId)}`);
614
+ configFlags.push("-c", `model_providers.${providerKey}.name=${tomlString(env.providerId)}`);
615
+ configFlags.push("-c", `model_providers.${providerKey}.base_url=${tomlString(actualBaseUrl.replace(/\/+$/, ""))}`);
616
+ if (wireApi) {
617
+ configFlags.push("-c", `model_providers.${providerKey}.wire_api=${tomlString(wireApi)}`);
618
+ }
619
+ configFlags.push("-c", `model_providers.${providerKey}.requires_openai_auth=${requiresOpenAiAuth ? "true" : "false"}`);
620
+ }
621
+ const appServerArgs: string[] = [
622
+ ...configFlags,
623
+ "app-server",
624
+ "--listen", wsUrl,
625
+ ];
626
+ let connection: CodexServerConnection | null = null;
627
+ const proc = spawn(executable, appServerArgs, {
628
+ cwd: normalizedCwd,
629
+ stdio: ["ignore", "pipe", "pipe"],
630
+ env: childEnv,
631
+ detached: process.platform !== "win32",
632
+ });
633
+
634
+ // Collect stderr for debugging
635
+ const stderrChunks: string[] = [];
636
+ proc.stderr?.on("data", (chunk: Buffer) => {
637
+ stderrChunks.push(chunk.toString());
638
+ });
639
+
640
+ proc.stdout?.on("data", () => {
641
+ // Codex app-server may output info to stdout
642
+ });
643
+
644
+ proc.on("error", (err) => {
645
+ console.error(`[codex-server] Process error for ${normalizedCwd}:`, err.message);
646
+ });
647
+ proc.on("exit", () => {
648
+ const current = registry.get(registryKey);
649
+ if (current?.process === proc) {
650
+ registry.delete(registryKey);
651
+ compatProxy?.stop().catch(() => {});
652
+ connection?.close();
653
+ }
654
+ });
655
+
656
+ // Wait for the server to be ready, then connect
657
+ // Give it a moment to start listening
658
+ await new Promise((resolve) => setTimeout(resolve, 500));
659
+
660
+ connection = new CodexServerConnection(normalizedCwd, wsUrl, registryKey);
661
+
662
+ // Retry connecting a few times
663
+ for (let attempt = 0; attempt < 10; attempt++) {
664
+ try {
665
+ await connection.connect();
666
+ break;
667
+ } catch {
668
+ if (attempt < 9) {
669
+ await new Promise((r) => setTimeout(r, 500));
670
+ } else {
671
+ // Kill the process and throw
672
+ try {
673
+ if (process.platform !== "win32") process.kill(-proc.pid!, "SIGTERM");
674
+ else proc.kill("SIGTERM");
675
+ } catch {
676
+ proc.kill("SIGTERM");
677
+ }
678
+ await compatProxy?.stop().catch(() => {});
679
+ const stderr = stderrChunks.join("");
680
+ throw new Error(
681
+ `Failed to connect to codex app-server after 10 attempts.\n` +
682
+ `stderr: ${stderr.slice(-500)}`
683
+ );
684
+ }
685
+ }
686
+ }
687
+
688
+ // Register the instance
689
+ const instance: ServerInstance = {
690
+ process: proc,
691
+ connection,
692
+ compatProxy,
693
+ port,
694
+ cwd: normalizedCwd,
695
+ refCount: 1,
696
+ startPromise: null,
697
+ };
698
+ registry.set(registryKey, instance);
699
+
700
+ return connection;
701
+ })();
702
+
703
+ // Store the promise so concurrent callers can wait
704
+ const tempInstance: ServerInstance = {
705
+ process: null!,
706
+ connection: null!,
707
+ compatProxy: null,
708
+ port,
709
+ cwd: normalizedCwd,
710
+ refCount: 0,
711
+ startPromise,
712
+ };
713
+ registry.set(registryKey, tempInstance);
714
+
715
+ try {
716
+ return await startPromise;
717
+ } catch (err) {
718
+ registry.delete(registryKey);
719
+ throw err;
720
+ }
721
+ }
722
+
723
+ export function releaseCodexServer(cwd: string, env?: CodexServerEnv): void {
724
+ const registry = getServerRegistry();
725
+ const normalizedCwd = cwd.replace(/\/+$/, "") || cwd;
726
+ const instance = registry.get(serverKeyFor(normalizedCwd, env));
727
+ if (!instance) return;
728
+
729
+ instance.refCount--;
730
+ if (instance.refCount <= 0) {
731
+ stopInstance(instance);
732
+ registry.delete(serverKeyFor(normalizedCwd, env));
733
+ }
734
+ }
735
+
736
+ export function releaseCodexServerConnection(connection: CodexServerConnection): void {
737
+ const registry = getServerRegistry();
738
+ const instance = registry.get(connection.serverKey);
739
+ if (!instance) return;
740
+
741
+ instance.refCount--;
742
+ if (instance.refCount <= 0) {
743
+ stopInstance(instance);
744
+ registry.delete(connection.serverKey);
745
+ }
746
+ }
747
+
748
+ /**
749
+ * Get thread listing from a codex server connection.
750
+ */
751
+ export async function listThreads(connection: CodexServerConnection, cwd?: string): Promise<CodexThread[]> {
752
+ const threads: CodexThread[] = [];
753
+ let cursor: string | null | undefined = null;
754
+ do {
755
+ const result = await connection.request("thread/list", {
756
+ ...(cursor ? { cursor } : {}),
757
+ ...(cwd ? { cwd } : {}),
758
+ limit: 100,
759
+ sortKey: "updated_at",
760
+ archived: false,
761
+ }) as { data?: CodexThread[]; nextCursor?: string | null };
762
+ threads.push(...(result.data ?? []));
763
+ cursor = result.nextCursor ?? null;
764
+ } while (cursor);
765
+ return threads;
766
+ }
767
+
768
+ /**
769
+ * Read full thread details (messages, items, etc.)
770
+ */
771
+ export async function readThread(connection: CodexServerConnection, threadId: string): Promise<CodexThread | null> {
772
+ const result = await connection.request("thread/read", { threadId, includeTurns: true }) as {
773
+ thread?: CodexThread;
774
+ };
775
+ return result.thread ?? null;
776
+ }
777
+
778
+ export function getServerForCwd(cwd: string): CodexServerConnection | undefined {
779
+ const registry = getServerRegistry();
780
+ const normalizedCwd = cwd.replace(/\/+$/, "") || cwd;
781
+ for (const instance of registry.values()) {
782
+ if (instance.cwd === normalizedCwd && instance.connection?.isConnected()) return instance.connection;
783
+ }
784
+ return undefined;
785
+ }
786
+
787
+ /**
788
+ * Shutdown all codex server instances gracefully.
789
+ */
790
+ export function shutdownAllCodexServers(): void {
791
+ const registry = getServerRegistry();
792
+ for (const [, inst] of registry) {
793
+ stopInstance(inst);
794
+ }
795
+ registry.clear();
796
+ }