better-codex 0.1.0

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 (405) hide show
  1. package/README.md +26 -0
  2. package/apps/backend/README.md +46 -0
  3. package/apps/backend/bun.lock +64 -0
  4. package/apps/backend/package.json +18 -0
  5. package/apps/backend/scripts/generate-protocol.ts +32 -0
  6. package/apps/backend/src/analytics/service.ts +219 -0
  7. package/apps/backend/src/analytics/store.ts +284 -0
  8. package/apps/backend/src/config.ts +98 -0
  9. package/apps/backend/src/core/app-server.ts +131 -0
  10. package/apps/backend/src/core/jsonrpc.ts +166 -0
  11. package/apps/backend/src/protocol/AbsolutePathBuf.ts +14 -0
  12. package/apps/backend/src/protocol/AddConversationListenerParams.ts +6 -0
  13. package/apps/backend/src/protocol/AddConversationSubscriptionResponse.ts +5 -0
  14. package/apps/backend/src/protocol/AgentMessageContent.ts +5 -0
  15. package/apps/backend/src/protocol/AgentMessageContentDeltaEvent.ts +5 -0
  16. package/apps/backend/src/protocol/AgentMessageDeltaEvent.ts +5 -0
  17. package/apps/backend/src/protocol/AgentMessageEvent.ts +5 -0
  18. package/apps/backend/src/protocol/AgentMessageItem.ts +6 -0
  19. package/apps/backend/src/protocol/AgentReasoningDeltaEvent.ts +5 -0
  20. package/apps/backend/src/protocol/AgentReasoningEvent.ts +5 -0
  21. package/apps/backend/src/protocol/AgentReasoningRawContentDeltaEvent.ts +5 -0
  22. package/apps/backend/src/protocol/AgentReasoningRawContentEvent.ts +5 -0
  23. package/apps/backend/src/protocol/AgentReasoningSectionBreakEvent.ts +5 -0
  24. package/apps/backend/src/protocol/Annotations.ts +9 -0
  25. package/apps/backend/src/protocol/ApplyPatchApprovalParams.ts +21 -0
  26. package/apps/backend/src/protocol/ApplyPatchApprovalRequestEvent.ts +23 -0
  27. package/apps/backend/src/protocol/ApplyPatchApprovalResponse.ts +6 -0
  28. package/apps/backend/src/protocol/ArchiveConversationParams.ts +6 -0
  29. package/apps/backend/src/protocol/ArchiveConversationResponse.ts +5 -0
  30. package/apps/backend/src/protocol/AskForApproval.ts +9 -0
  31. package/apps/backend/src/protocol/AudioContent.ts +9 -0
  32. package/apps/backend/src/protocol/AuthMode.ts +5 -0
  33. package/apps/backend/src/protocol/AuthStatusChangeNotification.ts +9 -0
  34. package/apps/backend/src/protocol/BackgroundEventEvent.ts +5 -0
  35. package/apps/backend/src/protocol/BlobResourceContents.ts +5 -0
  36. package/apps/backend/src/protocol/CallToolResult.ts +10 -0
  37. package/apps/backend/src/protocol/CancelLoginChatGptParams.ts +5 -0
  38. package/apps/backend/src/protocol/CancelLoginChatGptResponse.ts +5 -0
  39. package/apps/backend/src/protocol/ClientInfo.ts +5 -0
  40. package/apps/backend/src/protocol/ClientNotification.ts +5 -0
  41. package/apps/backend/src/protocol/ClientRequest.ts +46 -0
  42. package/apps/backend/src/protocol/CodexErrorInfo.ts +8 -0
  43. package/apps/backend/src/protocol/ContentBlock.ts +10 -0
  44. package/apps/backend/src/protocol/ContentItem.ts +5 -0
  45. package/apps/backend/src/protocol/ContextCompactedEvent.ts +5 -0
  46. package/apps/backend/src/protocol/ConversationGitInfo.ts +5 -0
  47. package/apps/backend/src/protocol/ConversationId.ts +5 -0
  48. package/apps/backend/src/protocol/ConversationSummary.ts +8 -0
  49. package/apps/backend/src/protocol/CreditsSnapshot.ts +5 -0
  50. package/apps/backend/src/protocol/CustomPrompt.ts +5 -0
  51. package/apps/backend/src/protocol/DeprecationNoticeEvent.ts +13 -0
  52. package/apps/backend/src/protocol/ElicitationRequestEvent.ts +6 -0
  53. package/apps/backend/src/protocol/EmbeddedResource.ts +13 -0
  54. package/apps/backend/src/protocol/EmbeddedResourceResource.ts +7 -0
  55. package/apps/backend/src/protocol/ErrorEvent.ts +6 -0
  56. package/apps/backend/src/protocol/EventMsg.ts +60 -0
  57. package/apps/backend/src/protocol/ExecApprovalRequestEvent.ts +32 -0
  58. package/apps/backend/src/protocol/ExecCommandApprovalParams.ts +12 -0
  59. package/apps/backend/src/protocol/ExecCommandApprovalResponse.ts +6 -0
  60. package/apps/backend/src/protocol/ExecCommandBeginEvent.ts +35 -0
  61. package/apps/backend/src/protocol/ExecCommandEndEvent.ts +59 -0
  62. package/apps/backend/src/protocol/ExecCommandOutputDeltaEvent.ts +18 -0
  63. package/apps/backend/src/protocol/ExecCommandSource.ts +5 -0
  64. package/apps/backend/src/protocol/ExecOneOffCommandParams.ts +6 -0
  65. package/apps/backend/src/protocol/ExecOneOffCommandResponse.ts +5 -0
  66. package/apps/backend/src/protocol/ExecOutputStream.ts +5 -0
  67. package/apps/backend/src/protocol/ExecPolicyAmendment.ts +12 -0
  68. package/apps/backend/src/protocol/ExitedReviewModeEvent.ts +6 -0
  69. package/apps/backend/src/protocol/FileChange.ts +5 -0
  70. package/apps/backend/src/protocol/ForcedLoginMethod.ts +5 -0
  71. package/apps/backend/src/protocol/FunctionCallOutputContentItem.ts +9 -0
  72. package/apps/backend/src/protocol/FunctionCallOutputPayload.ts +15 -0
  73. package/apps/backend/src/protocol/FuzzyFileSearchParams.ts +5 -0
  74. package/apps/backend/src/protocol/FuzzyFileSearchResponse.ts +6 -0
  75. package/apps/backend/src/protocol/FuzzyFileSearchResult.ts +8 -0
  76. package/apps/backend/src/protocol/GetAuthStatusParams.ts +5 -0
  77. package/apps/backend/src/protocol/GetAuthStatusResponse.ts +6 -0
  78. package/apps/backend/src/protocol/GetConversationSummaryParams.ts +6 -0
  79. package/apps/backend/src/protocol/GetConversationSummaryResponse.ts +6 -0
  80. package/apps/backend/src/protocol/GetHistoryEntryResponseEvent.ts +10 -0
  81. package/apps/backend/src/protocol/GetUserAgentResponse.ts +5 -0
  82. package/apps/backend/src/protocol/GetUserSavedConfigResponse.ts +6 -0
  83. package/apps/backend/src/protocol/GhostCommit.ts +8 -0
  84. package/apps/backend/src/protocol/GitDiffToRemoteParams.ts +5 -0
  85. package/apps/backend/src/protocol/GitDiffToRemoteResponse.ts +6 -0
  86. package/apps/backend/src/protocol/GitSha.ts +5 -0
  87. package/apps/backend/src/protocol/HistoryEntry.ts +5 -0
  88. package/apps/backend/src/protocol/ImageContent.ts +9 -0
  89. package/apps/backend/src/protocol/InitializeParams.ts +6 -0
  90. package/apps/backend/src/protocol/InitializeResponse.ts +5 -0
  91. package/apps/backend/src/protocol/InputItem.ts +5 -0
  92. package/apps/backend/src/protocol/InterruptConversationParams.ts +6 -0
  93. package/apps/backend/src/protocol/InterruptConversationResponse.ts +6 -0
  94. package/apps/backend/src/protocol/ItemCompletedEvent.ts +7 -0
  95. package/apps/backend/src/protocol/ItemStartedEvent.ts +7 -0
  96. package/apps/backend/src/protocol/ListConversationsParams.ts +5 -0
  97. package/apps/backend/src/protocol/ListConversationsResponse.ts +6 -0
  98. package/apps/backend/src/protocol/ListCustomPromptsResponseEvent.ts +9 -0
  99. package/apps/backend/src/protocol/ListSkillsResponseEvent.ts +9 -0
  100. package/apps/backend/src/protocol/LocalShellAction.ts +6 -0
  101. package/apps/backend/src/protocol/LocalShellExecAction.ts +5 -0
  102. package/apps/backend/src/protocol/LocalShellStatus.ts +5 -0
  103. package/apps/backend/src/protocol/LoginApiKeyParams.ts +5 -0
  104. package/apps/backend/src/protocol/LoginApiKeyResponse.ts +5 -0
  105. package/apps/backend/src/protocol/LoginChatGptCompleteNotification.ts +8 -0
  106. package/apps/backend/src/protocol/LoginChatGptResponse.ts +5 -0
  107. package/apps/backend/src/protocol/LogoutChatGptResponse.ts +5 -0
  108. package/apps/backend/src/protocol/McpAuthStatus.ts +5 -0
  109. package/apps/backend/src/protocol/McpInvocation.ts +18 -0
  110. package/apps/backend/src/protocol/McpListToolsResponseEvent.ts +25 -0
  111. package/apps/backend/src/protocol/McpStartupCompleteEvent.ts +6 -0
  112. package/apps/backend/src/protocol/McpStartupFailure.ts +5 -0
  113. package/apps/backend/src/protocol/McpStartupStatus.ts +5 -0
  114. package/apps/backend/src/protocol/McpStartupUpdateEvent.ts +14 -0
  115. package/apps/backend/src/protocol/McpToolCallBeginEvent.ts +10 -0
  116. package/apps/backend/src/protocol/McpToolCallEndEvent.ts +15 -0
  117. package/apps/backend/src/protocol/NetworkAccess.ts +8 -0
  118. package/apps/backend/src/protocol/NewConversationParams.ts +8 -0
  119. package/apps/backend/src/protocol/NewConversationResponse.ts +7 -0
  120. package/apps/backend/src/protocol/ParsedCommand.ts +12 -0
  121. package/apps/backend/src/protocol/PatchApplyBeginEvent.ts +23 -0
  122. package/apps/backend/src/protocol/PatchApplyEndEvent.ts +31 -0
  123. package/apps/backend/src/protocol/PlanItemArg.ts +6 -0
  124. package/apps/backend/src/protocol/PlanType.ts +5 -0
  125. package/apps/backend/src/protocol/Profile.ts +9 -0
  126. package/apps/backend/src/protocol/README.md +11 -0
  127. package/apps/backend/src/protocol/RateLimitSnapshot.ts +8 -0
  128. package/apps/backend/src/protocol/RateLimitWindow.ts +17 -0
  129. package/apps/backend/src/protocol/RawResponseItemEvent.ts +6 -0
  130. package/apps/backend/src/protocol/ReasoningContentDeltaEvent.ts +5 -0
  131. package/apps/backend/src/protocol/ReasoningEffort.ts +8 -0
  132. package/apps/backend/src/protocol/ReasoningItem.ts +5 -0
  133. package/apps/backend/src/protocol/ReasoningItemContent.ts +5 -0
  134. package/apps/backend/src/protocol/ReasoningItemReasoningSummary.ts +5 -0
  135. package/apps/backend/src/protocol/ReasoningRawContentDeltaEvent.ts +5 -0
  136. package/apps/backend/src/protocol/ReasoningSummary.ts +10 -0
  137. package/apps/backend/src/protocol/RemoveConversationListenerParams.ts +5 -0
  138. package/apps/backend/src/protocol/RemoveConversationSubscriptionResponse.ts +5 -0
  139. package/apps/backend/src/protocol/RequestId.ts +5 -0
  140. package/apps/backend/src/protocol/Resource.ts +9 -0
  141. package/apps/backend/src/protocol/ResourceLink.ts +11 -0
  142. package/apps/backend/src/protocol/ResourceTemplate.ts +9 -0
  143. package/apps/backend/src/protocol/ResponseItem.ts +17 -0
  144. package/apps/backend/src/protocol/ResumeConversationParams.ts +8 -0
  145. package/apps/backend/src/protocol/ResumeConversationResponse.ts +7 -0
  146. package/apps/backend/src/protocol/ReviewCodeLocation.ts +9 -0
  147. package/apps/backend/src/protocol/ReviewDecision.ts +9 -0
  148. package/apps/backend/src/protocol/ReviewFinding.ts +9 -0
  149. package/apps/backend/src/protocol/ReviewLineRange.ts +8 -0
  150. package/apps/backend/src/protocol/ReviewOutputEvent.ts +9 -0
  151. package/apps/backend/src/protocol/ReviewRequest.ts +9 -0
  152. package/apps/backend/src/protocol/ReviewTarget.ts +9 -0
  153. package/apps/backend/src/protocol/Role.ts +8 -0
  154. package/apps/backend/src/protocol/SandboxMode.ts +5 -0
  155. package/apps/backend/src/protocol/SandboxPolicy.ts +35 -0
  156. package/apps/backend/src/protocol/SandboxSettings.ts +6 -0
  157. package/apps/backend/src/protocol/SendUserMessageParams.ts +7 -0
  158. package/apps/backend/src/protocol/SendUserMessageResponse.ts +5 -0
  159. package/apps/backend/src/protocol/SendUserTurnParams.ts +11 -0
  160. package/apps/backend/src/protocol/SendUserTurnResponse.ts +5 -0
  161. package/apps/backend/src/protocol/ServerNotification.ts +36 -0
  162. package/apps/backend/src/protocol/ServerRequest.ts +13 -0
  163. package/apps/backend/src/protocol/SessionConfiguredEvent.ts +48 -0
  164. package/apps/backend/src/protocol/SessionConfiguredNotification.ts +8 -0
  165. package/apps/backend/src/protocol/SessionSource.ts +6 -0
  166. package/apps/backend/src/protocol/SetDefaultModelParams.ts +6 -0
  167. package/apps/backend/src/protocol/SetDefaultModelResponse.ts +5 -0
  168. package/apps/backend/src/protocol/SkillErrorInfo.ts +5 -0
  169. package/apps/backend/src/protocol/SkillMetadata.ts +6 -0
  170. package/apps/backend/src/protocol/SkillScope.ts +5 -0
  171. package/apps/backend/src/protocol/SkillsListEntry.ts +7 -0
  172. package/apps/backend/src/protocol/StepStatus.ts +5 -0
  173. package/apps/backend/src/protocol/StreamErrorEvent.ts +6 -0
  174. package/apps/backend/src/protocol/SubAgentSource.ts +5 -0
  175. package/apps/backend/src/protocol/TaskCompleteEvent.ts +5 -0
  176. package/apps/backend/src/protocol/TaskStartedEvent.ts +5 -0
  177. package/apps/backend/src/protocol/TerminalInteractionEvent.ts +17 -0
  178. package/apps/backend/src/protocol/TextContent.ts +9 -0
  179. package/apps/backend/src/protocol/TextResourceContents.ts +5 -0
  180. package/apps/backend/src/protocol/TokenCountEvent.ts +7 -0
  181. package/apps/backend/src/protocol/TokenUsage.ts +5 -0
  182. package/apps/backend/src/protocol/TokenUsageInfo.ts +6 -0
  183. package/apps/backend/src/protocol/Tool.ts +11 -0
  184. package/apps/backend/src/protocol/ToolAnnotations.ts +15 -0
  185. package/apps/backend/src/protocol/ToolInputSchema.ts +9 -0
  186. package/apps/backend/src/protocol/ToolOutputSchema.ts +10 -0
  187. package/apps/backend/src/protocol/Tools.ts +5 -0
  188. package/apps/backend/src/protocol/TurnAbortReason.ts +5 -0
  189. package/apps/backend/src/protocol/TurnAbortedEvent.ts +6 -0
  190. package/apps/backend/src/protocol/TurnDiffEvent.ts +5 -0
  191. package/apps/backend/src/protocol/TurnItem.ts +9 -0
  192. package/apps/backend/src/protocol/UndoCompletedEvent.ts +5 -0
  193. package/apps/backend/src/protocol/UndoStartedEvent.ts +5 -0
  194. package/apps/backend/src/protocol/UpdatePlanArgs.ts +6 -0
  195. package/apps/backend/src/protocol/UserInfoResponse.ts +5 -0
  196. package/apps/backend/src/protocol/UserInput.ts +8 -0
  197. package/apps/backend/src/protocol/UserMessageEvent.ts +5 -0
  198. package/apps/backend/src/protocol/UserMessageItem.ts +6 -0
  199. package/apps/backend/src/protocol/UserSavedConfig.ts +14 -0
  200. package/apps/backend/src/protocol/Verbosity.ts +9 -0
  201. package/apps/backend/src/protocol/ViewImageToolCallEvent.ts +13 -0
  202. package/apps/backend/src/protocol/WarningEvent.ts +5 -0
  203. package/apps/backend/src/protocol/WebSearchAction.ts +5 -0
  204. package/apps/backend/src/protocol/WebSearchBeginEvent.ts +5 -0
  205. package/apps/backend/src/protocol/WebSearchEndEvent.ts +5 -0
  206. package/apps/backend/src/protocol/WebSearchItem.ts +5 -0
  207. package/apps/backend/src/protocol/index.ts +198 -0
  208. package/apps/backend/src/protocol/serde_json/JsonValue.ts +5 -0
  209. package/apps/backend/src/protocol/v2/Account.ts +6 -0
  210. package/apps/backend/src/protocol/v2/AccountLoginCompletedNotification.ts +5 -0
  211. package/apps/backend/src/protocol/v2/AccountRateLimitsUpdatedNotification.ts +6 -0
  212. package/apps/backend/src/protocol/v2/AccountUpdatedNotification.ts +6 -0
  213. package/apps/backend/src/protocol/v2/AgentMessageDeltaNotification.ts +5 -0
  214. package/apps/backend/src/protocol/v2/ApprovalDecision.ts +6 -0
  215. package/apps/backend/src/protocol/v2/AskForApproval.ts +5 -0
  216. package/apps/backend/src/protocol/v2/CancelLoginAccountParams.ts +5 -0
  217. package/apps/backend/src/protocol/v2/CancelLoginAccountResponse.ts +6 -0
  218. package/apps/backend/src/protocol/v2/CancelLoginAccountStatus.ts +5 -0
  219. package/apps/backend/src/protocol/v2/CodexErrorInfo.ts +11 -0
  220. package/apps/backend/src/protocol/v2/CommandAction.ts +5 -0
  221. package/apps/backend/src/protocol/v2/CommandExecParams.ts +6 -0
  222. package/apps/backend/src/protocol/v2/CommandExecResponse.ts +5 -0
  223. package/apps/backend/src/protocol/v2/CommandExecutionOutputDeltaNotification.ts +5 -0
  224. package/apps/backend/src/protocol/v2/CommandExecutionRequestApprovalParams.ts +14 -0
  225. package/apps/backend/src/protocol/v2/CommandExecutionRequestApprovalResponse.ts +6 -0
  226. package/apps/backend/src/protocol/v2/CommandExecutionStatus.ts +5 -0
  227. package/apps/backend/src/protocol/v2/Config.ts +15 -0
  228. package/apps/backend/src/protocol/v2/ConfigBatchWriteParams.ts +10 -0
  229. package/apps/backend/src/protocol/v2/ConfigEdit.ts +7 -0
  230. package/apps/backend/src/protocol/v2/ConfigLayer.ts +7 -0
  231. package/apps/backend/src/protocol/v2/ConfigLayerMetadata.ts +6 -0
  232. package/apps/backend/src/protocol/v2/ConfigLayerSource.ts +6 -0
  233. package/apps/backend/src/protocol/v2/ConfigReadParams.ts +5 -0
  234. package/apps/backend/src/protocol/v2/ConfigReadResponse.ts +8 -0
  235. package/apps/backend/src/protocol/v2/ConfigValueWriteParams.ts +11 -0
  236. package/apps/backend/src/protocol/v2/ConfigWriteResponse.ts +12 -0
  237. package/apps/backend/src/protocol/v2/ContextCompactedNotification.ts +5 -0
  238. package/apps/backend/src/protocol/v2/CreditsSnapshot.ts +5 -0
  239. package/apps/backend/src/protocol/v2/DeprecationNoticeNotification.ts +13 -0
  240. package/apps/backend/src/protocol/v2/ErrorNotification.ts +6 -0
  241. package/apps/backend/src/protocol/v2/ExecPolicyAmendment.ts +5 -0
  242. package/apps/backend/src/protocol/v2/FeedbackUploadParams.ts +5 -0
  243. package/apps/backend/src/protocol/v2/FeedbackUploadResponse.ts +5 -0
  244. package/apps/backend/src/protocol/v2/FileChangeOutputDeltaNotification.ts +5 -0
  245. package/apps/backend/src/protocol/v2/FileChangeRequestApprovalParams.ts +14 -0
  246. package/apps/backend/src/protocol/v2/FileChangeRequestApprovalResponse.ts +6 -0
  247. package/apps/backend/src/protocol/v2/FileUpdateChange.ts +6 -0
  248. package/apps/backend/src/protocol/v2/GetAccountParams.ts +5 -0
  249. package/apps/backend/src/protocol/v2/GetAccountRateLimitsResponse.ts +6 -0
  250. package/apps/backend/src/protocol/v2/GetAccountResponse.ts +6 -0
  251. package/apps/backend/src/protocol/v2/GitInfo.ts +5 -0
  252. package/apps/backend/src/protocol/v2/ItemCompletedNotification.ts +6 -0
  253. package/apps/backend/src/protocol/v2/ItemStartedNotification.ts +6 -0
  254. package/apps/backend/src/protocol/v2/ListMcpServerStatusParams.ts +13 -0
  255. package/apps/backend/src/protocol/v2/ListMcpServerStatusResponse.ts +11 -0
  256. package/apps/backend/src/protocol/v2/LoginAccountParams.ts +5 -0
  257. package/apps/backend/src/protocol/v2/LoginAccountResponse.ts +9 -0
  258. package/apps/backend/src/protocol/v2/LogoutAccountResponse.ts +5 -0
  259. package/apps/backend/src/protocol/v2/McpAuthStatus.ts +5 -0
  260. package/apps/backend/src/protocol/v2/McpServerOauthLoginCompletedNotification.ts +5 -0
  261. package/apps/backend/src/protocol/v2/McpServerOauthLoginParams.ts +5 -0
  262. package/apps/backend/src/protocol/v2/McpServerOauthLoginResponse.ts +5 -0
  263. package/apps/backend/src/protocol/v2/McpServerStatus.ts +9 -0
  264. package/apps/backend/src/protocol/v2/McpToolCallError.ts +5 -0
  265. package/apps/backend/src/protocol/v2/McpToolCallProgressNotification.ts +5 -0
  266. package/apps/backend/src/protocol/v2/McpToolCallResult.ts +7 -0
  267. package/apps/backend/src/protocol/v2/McpToolCallStatus.ts +5 -0
  268. package/apps/backend/src/protocol/v2/MergeStrategy.ts +5 -0
  269. package/apps/backend/src/protocol/v2/Model.ts +7 -0
  270. package/apps/backend/src/protocol/v2/ModelListParams.ts +13 -0
  271. package/apps/backend/src/protocol/v2/ModelListResponse.ts +11 -0
  272. package/apps/backend/src/protocol/v2/NetworkAccess.ts +5 -0
  273. package/apps/backend/src/protocol/v2/OverriddenMetadata.ts +7 -0
  274. package/apps/backend/src/protocol/v2/PatchApplyStatus.ts +5 -0
  275. package/apps/backend/src/protocol/v2/PatchChangeKind.ts +5 -0
  276. package/apps/backend/src/protocol/v2/ProfileV2.ts +10 -0
  277. package/apps/backend/src/protocol/v2/RateLimitSnapshot.ts +8 -0
  278. package/apps/backend/src/protocol/v2/RateLimitWindow.ts +5 -0
  279. package/apps/backend/src/protocol/v2/RawResponseItemCompletedNotification.ts +6 -0
  280. package/apps/backend/src/protocol/v2/ReasoningEffortOption.ts +6 -0
  281. package/apps/backend/src/protocol/v2/ReasoningSummaryPartAddedNotification.ts +5 -0
  282. package/apps/backend/src/protocol/v2/ReasoningSummaryTextDeltaNotification.ts +5 -0
  283. package/apps/backend/src/protocol/v2/ReasoningTextDeltaNotification.ts +5 -0
  284. package/apps/backend/src/protocol/v2/ReviewDelivery.ts +5 -0
  285. package/apps/backend/src/protocol/v2/ReviewStartParams.ts +12 -0
  286. package/apps/backend/src/protocol/v2/ReviewStartResponse.ts +13 -0
  287. package/apps/backend/src/protocol/v2/ReviewTarget.ts +9 -0
  288. package/apps/backend/src/protocol/v2/SandboxMode.ts +5 -0
  289. package/apps/backend/src/protocol/v2/SandboxPolicy.ts +7 -0
  290. package/apps/backend/src/protocol/v2/SandboxWorkspaceWrite.ts +5 -0
  291. package/apps/backend/src/protocol/v2/SessionSource.ts +5 -0
  292. package/apps/backend/src/protocol/v2/SkillErrorInfo.ts +5 -0
  293. package/apps/backend/src/protocol/v2/SkillMetadata.ts +6 -0
  294. package/apps/backend/src/protocol/v2/SkillScope.ts +5 -0
  295. package/apps/backend/src/protocol/v2/SkillsListEntry.ts +7 -0
  296. package/apps/backend/src/protocol/v2/SkillsListParams.ts +13 -0
  297. package/apps/backend/src/protocol/v2/SkillsListResponse.ts +6 -0
  298. package/apps/backend/src/protocol/v2/TerminalInteractionNotification.ts +5 -0
  299. package/apps/backend/src/protocol/v2/Thread.ts +46 -0
  300. package/apps/backend/src/protocol/v2/ThreadArchiveParams.ts +5 -0
  301. package/apps/backend/src/protocol/v2/ThreadArchiveResponse.ts +5 -0
  302. package/apps/backend/src/protocol/v2/ThreadItem.ts +48 -0
  303. package/apps/backend/src/protocol/v2/ThreadListParams.ts +18 -0
  304. package/apps/backend/src/protocol/v2/ThreadListResponse.ts +11 -0
  305. package/apps/backend/src/protocol/v2/ThreadResumeParams.ts +35 -0
  306. package/apps/backend/src/protocol/v2/ThreadResumeResponse.ts +9 -0
  307. package/apps/backend/src/protocol/v2/ThreadStartParams.ts +15 -0
  308. package/apps/backend/src/protocol/v2/ThreadStartResponse.ts +9 -0
  309. package/apps/backend/src/protocol/v2/ThreadStartedNotification.ts +6 -0
  310. package/apps/backend/src/protocol/v2/ThreadTokenUsage.ts +6 -0
  311. package/apps/backend/src/protocol/v2/ThreadTokenUsageUpdatedNotification.ts +6 -0
  312. package/apps/backend/src/protocol/v2/TokenUsageBreakdown.ts +5 -0
  313. package/apps/backend/src/protocol/v2/ToolsV2.ts +5 -0
  314. package/apps/backend/src/protocol/v2/Turn.ts +18 -0
  315. package/apps/backend/src/protocol/v2/TurnCompletedNotification.ts +6 -0
  316. package/apps/backend/src/protocol/v2/TurnDiffUpdatedNotification.ts +9 -0
  317. package/apps/backend/src/protocol/v2/TurnError.ts +6 -0
  318. package/apps/backend/src/protocol/v2/TurnInterruptParams.ts +5 -0
  319. package/apps/backend/src/protocol/v2/TurnInterruptResponse.ts +5 -0
  320. package/apps/backend/src/protocol/v2/TurnPlanStep.ts +6 -0
  321. package/apps/backend/src/protocol/v2/TurnPlanStepStatus.ts +5 -0
  322. package/apps/backend/src/protocol/v2/TurnPlanUpdatedNotification.ts +6 -0
  323. package/apps/backend/src/protocol/v2/TurnStartParams.ts +34 -0
  324. package/apps/backend/src/protocol/v2/TurnStartResponse.ts +6 -0
  325. package/apps/backend/src/protocol/v2/TurnStartedNotification.ts +6 -0
  326. package/apps/backend/src/protocol/v2/TurnStatus.ts +5 -0
  327. package/apps/backend/src/protocol/v2/UserInput.ts +5 -0
  328. package/apps/backend/src/protocol/v2/WindowsWorldWritableWarningNotification.ts +5 -0
  329. package/apps/backend/src/protocol/v2/WriteStatus.ts +5 -0
  330. package/apps/backend/src/protocol/v2/index.ts +123 -0
  331. package/apps/backend/src/reviews/service.ts +27 -0
  332. package/apps/backend/src/reviews/store.ts +124 -0
  333. package/apps/backend/src/server.ts +531 -0
  334. package/apps/backend/src/services/profile-store.ts +114 -0
  335. package/apps/backend/src/services/supervisor.ts +102 -0
  336. package/apps/backend/src/thread-index/service.ts +75 -0
  337. package/apps/backend/src/thread-index/store.ts +195 -0
  338. package/apps/backend/src/ws/messages.ts +73 -0
  339. package/apps/backend/tsconfig.json +20 -0
  340. package/apps/web/README.md +24 -0
  341. package/apps/web/bun.lock +1062 -0
  342. package/apps/web/eslint.config.js +23 -0
  343. package/apps/web/index.html +16 -0
  344. package/apps/web/package.json +38 -0
  345. package/apps/web/src/app.tsx +83 -0
  346. package/apps/web/src/components/composer/slash-command-menu.tsx +47 -0
  347. package/apps/web/src/components/index.ts +2 -0
  348. package/apps/web/src/components/layout/account-usage-panel.tsx +167 -0
  349. package/apps/web/src/components/layout/analytics-view.tsx +296 -0
  350. package/apps/web/src/components/layout/index.ts +7 -0
  351. package/apps/web/src/components/layout/mobile-header.tsx +56 -0
  352. package/apps/web/src/components/layout/reviews-view.tsx +848 -0
  353. package/apps/web/src/components/layout/session-view.tsx +1374 -0
  354. package/apps/web/src/components/layout/settings-dialog.tsx +322 -0
  355. package/apps/web/src/components/layout/side-bar.tsx +417 -0
  356. package/apps/web/src/components/layout/thread-list.tsx +488 -0
  357. package/apps/web/src/components/layout/virtualized-message-list.tsx +748 -0
  358. package/apps/web/src/components/loading/startup-ascii.ts +652 -0
  359. package/apps/web/src/components/loading/startup-loader.tsx +37 -0
  360. package/apps/web/src/components/session-view/file-mention-menu.tsx +46 -0
  361. package/apps/web/src/components/session-view/session-auth-banner.tsx +61 -0
  362. package/apps/web/src/components/session-view/session-composer.tsx +328 -0
  363. package/apps/web/src/components/session-view/session-dialogs.tsx +280 -0
  364. package/apps/web/src/components/session-view/session-empty.tsx +47 -0
  365. package/apps/web/src/components/session-view/session-header.tsx +49 -0
  366. package/apps/web/src/components/ui/avatar.tsx +19 -0
  367. package/apps/web/src/components/ui/badge.tsx +21 -0
  368. package/apps/web/src/components/ui/button.tsx +47 -0
  369. package/apps/web/src/components/ui/collapsible-content.tsx +114 -0
  370. package/apps/web/src/components/ui/contribution-graph.tsx +182 -0
  371. package/apps/web/src/components/ui/dialog-box.tsx +203 -0
  372. package/apps/web/src/components/ui/icon-button.tsx +32 -0
  373. package/apps/web/src/components/ui/icons.tsx +187 -0
  374. package/apps/web/src/components/ui/index.tsx +15 -0
  375. package/apps/web/src/components/ui/input.tsx +43 -0
  376. package/apps/web/src/components/ui/markdown-stream.tsx +21 -0
  377. package/apps/web/src/components/ui/mobile-drawer.tsx +124 -0
  378. package/apps/web/src/components/ui/section-header.tsx +13 -0
  379. package/apps/web/src/components/ui/select.tsx +217 -0
  380. package/apps/web/src/components/ui/shimmer.tsx +138 -0
  381. package/apps/web/src/components/ui/status-dot.tsx +24 -0
  382. package/apps/web/src/config.ts +5 -0
  383. package/apps/web/src/hooks/index.ts +3 -0
  384. package/apps/web/src/hooks/use-analytics.ts +122 -0
  385. package/apps/web/src/hooks/use-hub-connection.ts +587 -0
  386. package/apps/web/src/hooks/use-mobile.ts +76 -0
  387. package/apps/web/src/hooks/use-thread-history.ts +210 -0
  388. package/apps/web/src/index.css +269 -0
  389. package/apps/web/src/main.tsx +10 -0
  390. package/apps/web/src/services/hub-client.ts +358 -0
  391. package/apps/web/src/store/index.ts +528 -0
  392. package/apps/web/src/types/index.ts +119 -0
  393. package/apps/web/src/utils/account-refresh.ts +168 -0
  394. package/apps/web/src/utils/approval-policy.ts +53 -0
  395. package/apps/web/src/utils/init-prompt.ts +41 -0
  396. package/apps/web/src/utils/item-format.ts +170 -0
  397. package/apps/web/src/utils/prompt-expander.ts +62 -0
  398. package/apps/web/src/utils/reasoning-summary.ts +48 -0
  399. package/apps/web/src/utils/slash-commands.ts +98 -0
  400. package/apps/web/tsconfig.app.json +28 -0
  401. package/apps/web/tsconfig.json +7 -0
  402. package/apps/web/tsconfig.node.json +26 -0
  403. package/apps/web/vite.config.ts +8 -0
  404. package/bin/better-codex.cjs +199 -0
  405. package/package.json +20 -0
@@ -0,0 +1,102 @@
1
+ import { EventEmitter } from 'node:events'
2
+ import { CodexAppServer } from '../core/app-server'
3
+ import type { HubConfig } from '../config'
4
+ import type { Profile } from './profile-store'
5
+
6
+ type SupervisorEvents = {
7
+ notification: (payload: {
8
+ profileId: string
9
+ method: string
10
+ params?: unknown
11
+ }) => void
12
+ serverRequest: (payload: {
13
+ profileId: string
14
+ id: number
15
+ method: string
16
+ params?: unknown
17
+ }) => void
18
+ diagnostic: (payload: { profileId: string; message: string }) => void
19
+ exit: (payload: { profileId: string; code: number | null }) => void
20
+ error: (payload: { profileId: string; error: Error }) => void
21
+ }
22
+
23
+ export class CodexSupervisor extends EventEmitter {
24
+ private readonly processes = new Map<string, CodexAppServer>()
25
+
26
+ constructor(private readonly config: HubConfig) {
27
+ super()
28
+ }
29
+
30
+ async start(profile: Profile): Promise<CodexAppServer> {
31
+ const existing = this.processes.get(profile.id)
32
+ if (existing) {
33
+ return existing
34
+ }
35
+
36
+ const server = new CodexAppServer({
37
+ codexBin: this.config.codexBin,
38
+ codexArgs: this.config.codexArgs,
39
+ appServerArgs: this.config.codexAppServerArgs,
40
+ codexHome: profile.codexHome,
41
+ clientInfo: this.config.clientInfo,
42
+ cwd: this.config.defaultCwd,
43
+ })
44
+
45
+ server.on('notification', (message) => {
46
+ this.emit('notification', {
47
+ profileId: profile.id,
48
+ method: message.method,
49
+ params: message.params,
50
+ })
51
+ })
52
+ server.on('serverRequest', (message) => {
53
+ this.emit('serverRequest', {
54
+ profileId: profile.id,
55
+ id: message.id,
56
+ method: message.method,
57
+ params: message.params,
58
+ })
59
+ })
60
+ server.on('stderr', (message) => {
61
+ this.emit('diagnostic', { profileId: profile.id, message })
62
+ })
63
+ server.on('exit', (code) => {
64
+ this.processes.delete(profile.id)
65
+ this.emit('exit', { profileId: profile.id, code })
66
+ })
67
+ server.on('error', (error) => {
68
+ this.emit('error', { profileId: profile.id, error })
69
+ })
70
+
71
+ await server.start()
72
+ this.processes.set(profile.id, server)
73
+ return server
74
+ }
75
+
76
+ async stop(profileId: string): Promise<void> {
77
+ const server = this.processes.get(profileId)
78
+ if (!server) {
79
+ return
80
+ }
81
+ await server.stop()
82
+ this.processes.delete(profileId)
83
+ }
84
+
85
+ async request(profileId: string, method: string, params?: unknown): Promise<unknown> {
86
+ const server = this.processes.get(profileId)
87
+ if (!server) {
88
+ throw new Error('profile app-server not running')
89
+ }
90
+ return server.request(method, params)
91
+ }
92
+
93
+ respond(profileId: string, id: number, result?: unknown, error?: { code?: number; message: string }): void {
94
+ const server = this.processes.get(profileId)
95
+ if (!server) {
96
+ return
97
+ }
98
+ server.respond(id, result, error)
99
+ }
100
+ }
101
+
102
+ export type CodexSupervisorEventsMap = SupervisorEvents
@@ -0,0 +1,75 @@
1
+ import { ThreadIndexStore, type ThreadIndexRow, type ThreadSearchQuery } from './store'
2
+
3
+ export type ThreadListItem = {
4
+ id: string
5
+ preview?: string
6
+ modelProvider?: string
7
+ createdAt?: number
8
+ path?: string
9
+ cwd?: string
10
+ cliVersion?: string
11
+ source?: string
12
+ }
13
+
14
+ export class ThreadIndexService {
15
+ constructor(private readonly store: ThreadIndexStore) {}
16
+
17
+ init(): void {
18
+ this.store.init()
19
+ }
20
+
21
+ recordThreadList(profileId: string, threads: ThreadListItem[], fetchedAt = Date.now()): void {
22
+ threads.forEach((thread) => {
23
+ this.store.upsertThread(this.toRow(profileId, thread, fetchedAt))
24
+ })
25
+ }
26
+
27
+ recordThreadStart(profileId: string, thread?: ThreadListItem): void {
28
+ if (!thread?.id) {
29
+ return
30
+ }
31
+ this.store.upsertThread(this.toRow(profileId, thread, Date.now()))
32
+ }
33
+
34
+ recordThreadResume(profileId: string, thread?: ThreadListItem): void {
35
+ if (!thread?.id) {
36
+ return
37
+ }
38
+ this.store.upsertThread(this.toRow(profileId, thread, Date.now()))
39
+ }
40
+
41
+ recordThreadArchive(profileId: string, threadId: string): void {
42
+ this.store.markArchived(profileId, threadId)
43
+ }
44
+
45
+ search(query: ThreadSearchQuery): ThreadIndexRow[] {
46
+ return this.store.search(query)
47
+ }
48
+
49
+ private toRow(profileId: string, thread: ThreadListItem, fetchedAt: number): ThreadIndexRow {
50
+ return {
51
+ threadId: thread.id,
52
+ profileId,
53
+ preview: thread.preview ?? null,
54
+ modelProvider: thread.modelProvider ?? null,
55
+ createdAt: normalizeTimestamp(thread.createdAt),
56
+ path: thread.path ?? null,
57
+ cwd: thread.cwd ?? null,
58
+ source: thread.source ?? null,
59
+ cliVersion: thread.cliVersion ?? null,
60
+ status: 'active',
61
+ archivedAt: null,
62
+ lastSeenAt: fetchedAt,
63
+ }
64
+ }
65
+ }
66
+
67
+ const normalizeTimestamp = (value?: number): number | null => {
68
+ if (!value) {
69
+ return null
70
+ }
71
+ if (value > 1000000000000) {
72
+ return Math.floor(value / 1000)
73
+ }
74
+ return value
75
+ }
@@ -0,0 +1,195 @@
1
+ import { Database } from 'bun:sqlite'
2
+
3
+ export type ThreadIndexRow = {
4
+ threadId: string
5
+ profileId: string
6
+ preview: string | null
7
+ modelProvider: string | null
8
+ createdAt: number | null
9
+ path: string | null
10
+ cwd: string | null
11
+ source: string | null
12
+ cliVersion: string | null
13
+ status: 'active' | 'archived'
14
+ archivedAt: number | null
15
+ lastSeenAt: number | null
16
+ }
17
+
18
+ export type ThreadSearchQuery = {
19
+ query?: string
20
+ profileId?: string
21
+ model?: string
22
+ status?: 'active' | 'archived'
23
+ createdAfter?: number
24
+ createdBefore?: number
25
+ limit?: number
26
+ offset?: number
27
+ }
28
+
29
+ export class ThreadIndexStore {
30
+ private readonly db: Database
31
+
32
+ constructor(private readonly dbPath: string) {
33
+ this.db = new Database(dbPath)
34
+ }
35
+
36
+ init(): void {
37
+ this.db.exec(`
38
+ pragma journal_mode = wal;
39
+ create table if not exists thread_index (
40
+ thread_id text primary key,
41
+ profile_id text not null,
42
+ preview text,
43
+ model_provider text,
44
+ created_at integer,
45
+ path text,
46
+ cwd text,
47
+ source text,
48
+ cli_version text,
49
+ status text not null default 'active',
50
+ archived_at integer,
51
+ last_seen_at integer
52
+ );
53
+ create index if not exists thread_index_profile on thread_index(profile_id);
54
+ create index if not exists thread_index_model on thread_index(model_provider);
55
+ create index if not exists thread_index_created on thread_index(created_at);
56
+ create index if not exists thread_index_status on thread_index(status);
57
+
58
+ create virtual table if not exists thread_index_fts using fts5(
59
+ thread_id,
60
+ preview,
61
+ path,
62
+ cwd,
63
+ model_provider,
64
+ profile_id
65
+ );
66
+ `)
67
+ }
68
+
69
+ upsertThread(row: ThreadIndexRow): void {
70
+ this.db
71
+ .prepare(
72
+ `insert into thread_index
73
+ (thread_id, profile_id, preview, model_provider, created_at, path, cwd, source, cli_version, status, archived_at, last_seen_at)
74
+ values
75
+ ($thread_id, $profile_id, $preview, $model_provider, $created_at, $path, $cwd, $source, $cli_version, $status, $archived_at, $last_seen_at)
76
+ on conflict(thread_id) do update set
77
+ profile_id = excluded.profile_id,
78
+ preview = excluded.preview,
79
+ model_provider = excluded.model_provider,
80
+ created_at = excluded.created_at,
81
+ path = excluded.path,
82
+ cwd = excluded.cwd,
83
+ source = excluded.source,
84
+ cli_version = excluded.cli_version,
85
+ status = excluded.status,
86
+ archived_at = excluded.archived_at,
87
+ last_seen_at = excluded.last_seen_at
88
+ `
89
+ )
90
+ .run({
91
+ $thread_id: row.threadId,
92
+ $profile_id: row.profileId,
93
+ $preview: row.preview,
94
+ $model_provider: row.modelProvider,
95
+ $created_at: row.createdAt,
96
+ $path: row.path,
97
+ $cwd: row.cwd,
98
+ $source: row.source,
99
+ $cli_version: row.cliVersion,
100
+ $status: row.status,
101
+ $archived_at: row.archivedAt,
102
+ $last_seen_at: row.lastSeenAt,
103
+ })
104
+
105
+ this.db
106
+ .prepare('delete from thread_index_fts where thread_id = $thread_id')
107
+ .run({ $thread_id: row.threadId })
108
+ this.db
109
+ .prepare(
110
+ `insert into thread_index_fts (thread_id, preview, path, cwd, model_provider, profile_id)
111
+ values ($thread_id, $preview, $path, $cwd, $model_provider, $profile_id)
112
+ `
113
+ )
114
+ .run({
115
+ $thread_id: row.threadId,
116
+ $preview: row.preview ?? '',
117
+ $path: row.path ?? '',
118
+ $cwd: row.cwd ?? '',
119
+ $model_provider: row.modelProvider ?? '',
120
+ $profile_id: row.profileId,
121
+ })
122
+ }
123
+
124
+ markArchived(profileId: string, threadId: string): void {
125
+ const timestamp = Date.now()
126
+ this.db
127
+ .prepare(
128
+ `update thread_index
129
+ set status = 'archived', archived_at = $archived_at
130
+ where thread_id = $thread_id and profile_id = $profile_id
131
+ `
132
+ )
133
+ .run({
134
+ $thread_id: threadId,
135
+ $profile_id: profileId,
136
+ $archived_at: timestamp,
137
+ })
138
+ }
139
+
140
+ search(query: ThreadSearchQuery): ThreadIndexRow[] {
141
+ const limit = Math.min(200, Math.max(1, query.limit ?? 50))
142
+ const offset = Math.max(0, query.offset ?? 0)
143
+ const filters: string[] = []
144
+ // bun's Statement typing does not currently accept named params; values are string | number | null
145
+ const params: Record<string, string | number | null> = {
146
+ $limit: limit,
147
+ $offset: offset,
148
+ $profile_id: query.profileId ?? null,
149
+ $model: query.model ?? null,
150
+ $status: query.status ?? null,
151
+ $created_after: query.createdAfter ?? null,
152
+ $created_before: query.createdBefore ?? null,
153
+ }
154
+
155
+ if (query.profileId) {
156
+ filters.push('t.profile_id = $profile_id')
157
+ }
158
+ if (query.model) {
159
+ filters.push('t.model_provider = $model')
160
+ }
161
+ if (query.status) {
162
+ filters.push('t.status = $status')
163
+ }
164
+ if (query.createdAfter) {
165
+ filters.push('t.created_at >= $created_after')
166
+ }
167
+ if (query.createdBefore) {
168
+ filters.push('t.created_at <= $created_before')
169
+ }
170
+
171
+ const filterSql = filters.length ? `and ${filters.join(' and ')}` : ''
172
+
173
+ if (query.query && query.query.trim()) {
174
+ params.$query = query.query
175
+ const sql = `
176
+ select t.* from thread_index t
177
+ join thread_index_fts f on t.thread_id = f.thread_id
178
+ where f.thread_index_fts match $query
179
+ ${filterSql}
180
+ order by t.created_at desc
181
+ limit $limit offset $offset
182
+ `
183
+ return this.db.prepare(sql).all(params as any) as ThreadIndexRow[]
184
+ }
185
+
186
+ const sql = `
187
+ select t.* from thread_index t
188
+ where 1 = 1
189
+ ${filterSql}
190
+ order by t.created_at desc
191
+ limit $limit offset $offset
192
+ `
193
+ return this.db.prepare(sql).all(params as any) as ThreadIndexRow[]
194
+ }
195
+ }
@@ -0,0 +1,73 @@
1
+ export type WsRequest =
2
+ | {
3
+ type: 'profile.start'
4
+ profileId: string
5
+ }
6
+ | {
7
+ type: 'profile.stop'
8
+ profileId: string
9
+ }
10
+ | {
11
+ type: 'rpc.request'
12
+ requestId: string
13
+ profileId: string
14
+ method: string
15
+ params?: unknown
16
+ }
17
+ | {
18
+ type: 'rpc.response'
19
+ profileId: string
20
+ id: number
21
+ result?: unknown
22
+ error?: { code?: number; message: string }
23
+ }
24
+
25
+ export type WsEvent =
26
+ | {
27
+ type: 'rpc.event'
28
+ profileId: string
29
+ method: string
30
+ params?: unknown
31
+ }
32
+ | {
33
+ type: 'rpc.serverRequest'
34
+ profileId: string
35
+ id: number
36
+ method: string
37
+ params?: unknown
38
+ }
39
+ | {
40
+ type: 'profile.diagnostic'
41
+ profileId: string
42
+ message: string
43
+ }
44
+ | {
45
+ type: 'profile.exit'
46
+ profileId: string
47
+ code: number | null
48
+ }
49
+ | {
50
+ type: 'profile.error'
51
+ profileId: string
52
+ message: string
53
+ }
54
+
55
+ export type WsResponse =
56
+ | {
57
+ type: 'rpc.response'
58
+ requestId: string
59
+ result?: unknown
60
+ error?: string
61
+ }
62
+ | {
63
+ type: 'profile.started'
64
+ profileId: string
65
+ }
66
+ | {
67
+ type: 'profile.stopped'
68
+ profileId: string
69
+ }
70
+ | {
71
+ type: 'error'
72
+ message: string
73
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": [
4
+ "ESNext"
5
+ ],
6
+ "module": "ESNext",
7
+ "target": "ESNext",
8
+ "moduleResolution": "bundler",
9
+ "strict": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "moduleDetection": "force",
14
+ "noUncheckedIndexedAccess": true,
15
+ "noEmit": true,
16
+ "types": [
17
+ "bun"
18
+ ]
19
+ }
20
+ }
@@ -0,0 +1,24 @@
1
+ # Codex Hub Web UI
2
+
3
+ Frontend for the multi-account Codex hub. It connects to the local backend over
4
+ REST + WebSocket.
5
+
6
+ ## Setup
7
+
8
+ 1. Install dependencies
9
+ ```bash
10
+ bun install
11
+ ```
12
+ 2. Start the dev server
13
+ ```bash
14
+ bun run dev
15
+ ```
16
+
17
+ ## Environment variables
18
+
19
+ Create a `.env` file with:
20
+
21
+ ```bash
22
+ VITE_CODEX_HUB_URL=http://127.0.0.1:7711
23
+ VITE_CODEX_HUB_TOKEN=... # printed by the backend on boot
24
+ ```