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,182 @@
1
+ import { useMemo } from 'react'
2
+ import type { DailyDataPoint } from '../../hooks/use-analytics'
3
+
4
+ interface ContributionGraphProps {
5
+ data: DailyDataPoint[]
6
+ days?: number
7
+ label?: string
8
+ colorScheme?: 'green' | 'blue' | 'purple'
9
+ }
10
+
11
+ const COLOR_SCHEMES = {
12
+ green: ['bg-bg-elevated', 'bg-emerald-900/50', 'bg-emerald-700/70', 'bg-emerald-500/80', 'bg-emerald-400'],
13
+ blue: ['bg-bg-elevated', 'bg-blue-900/50', 'bg-blue-700/70', 'bg-blue-500/80', 'bg-blue-400'],
14
+ purple: ['bg-bg-elevated', 'bg-purple-900/50', 'bg-purple-700/70', 'bg-purple-500/80', 'bg-purple-400'],
15
+ }
16
+
17
+ const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
18
+ const DAYS = ['', 'Mon', '', 'Wed', '', 'Fri', '']
19
+
20
+ export function ContributionGraph({
21
+ data,
22
+ days = 365,
23
+ label = 'contributions',
24
+ colorScheme = 'green'
25
+ }: ContributionGraphProps) {
26
+ const { grid, monthLabels, totalCount, maxCount } = useMemo(() => {
27
+ const dataMap = new Map<string, number>()
28
+ for (const point of data) {
29
+ dataMap.set(point.date, point.count)
30
+ }
31
+
32
+ const today = new Date()
33
+ const endDate = new Date(today.getFullYear(), today.getMonth(), today.getDate())
34
+ const startDate = new Date(endDate)
35
+ startDate.setDate(startDate.getDate() - days + 1)
36
+
37
+ const dayOfWeek = startDate.getDay()
38
+ startDate.setDate(startDate.getDate() - dayOfWeek)
39
+
40
+ const weeks: Array<Array<{ date: string; count: number; isInRange: boolean }>> = []
41
+ const monthLabels: Array<{ label: string; weekIndex: number }> = []
42
+ let currentDate = new Date(startDate)
43
+ let lastMonth = -1
44
+ let totalCount = 0
45
+ let maxCount = 0
46
+
47
+ while (currentDate <= endDate) {
48
+ const week: Array<{ date: string; count: number; isInRange: boolean }> = []
49
+
50
+ for (let d = 0; d < 7; d++) {
51
+ const dateKey = formatDate(currentDate)
52
+ const count = dataMap.get(dateKey) ?? 0
53
+ const isInRange = currentDate >= startDate && currentDate <= endDate
54
+
55
+ if (isInRange && currentDate.getMonth() !== lastMonth) {
56
+ monthLabels.push({ label: MONTHS[currentDate.getMonth()], weekIndex: weeks.length })
57
+ lastMonth = currentDate.getMonth()
58
+ }
59
+
60
+ week.push({ date: dateKey, count, isInRange })
61
+
62
+ if (isInRange) {
63
+ totalCount += count
64
+ maxCount = Math.max(maxCount, count)
65
+ }
66
+
67
+ currentDate.setDate(currentDate.getDate() + 1)
68
+ }
69
+
70
+ weeks.push(week)
71
+ }
72
+
73
+ return { grid: weeks, monthLabels, totalCount, maxCount }
74
+ }, [data, days])
75
+
76
+ const colors = COLOR_SCHEMES[colorScheme]
77
+
78
+ const getColorLevel = (count: number): number => {
79
+ if (count === 0) return 0
80
+ if (maxCount === 0) return 0
81
+ const ratio = count / maxCount
82
+ if (ratio <= 0.25) return 1
83
+ if (ratio <= 0.5) return 2
84
+ if (ratio <= 0.75) return 3
85
+ return 4
86
+ }
87
+
88
+ return (
89
+ <div className="space-y-2">
90
+ <div className="flex items-center justify-between">
91
+ <span className="text-sm text-text-primary font-medium">
92
+ {totalCount.toLocaleString()} {label} in the last {days === 365 ? 'year' : `${days} days`}
93
+ </span>
94
+ </div>
95
+
96
+ <div className="overflow-x-auto">
97
+ <div className="inline-block">
98
+ <div className="flex text-[10px] text-text-muted mb-1 pl-7">
99
+ {monthLabels.map((month, i) => (
100
+ <div
101
+ key={i}
102
+ className="absolute"
103
+ style={{ marginLeft: `${month.weekIndex * 12}px` }}
104
+ >
105
+ {month.label}
106
+ </div>
107
+ ))}
108
+ </div>
109
+
110
+ <div className="flex gap-0.5 relative mt-4">
111
+ <div className="flex flex-col gap-0.5 text-[10px] text-text-muted pr-1 w-6">
112
+ {DAYS.map((day, i) => (
113
+ <div key={i} className="h-[10px] flex items-center justify-end">
114
+ {day}
115
+ </div>
116
+ ))}
117
+ </div>
118
+
119
+ {grid.map((week, weekIndex) => (
120
+ <div key={weekIndex} className="flex flex-col gap-0.5">
121
+ {week.map((day, dayIndex) => (
122
+ <div
123
+ key={dayIndex}
124
+ className={`w-[10px] h-[10px] rounded-sm ${
125
+ day.isInRange ? colors[getColorLevel(day.count)] : 'bg-transparent'
126
+ }`}
127
+ title={day.isInRange ? `${day.date}: ${day.count} ${label}` : undefined}
128
+ />
129
+ ))}
130
+ </div>
131
+ ))}
132
+ </div>
133
+
134
+ <div className="flex items-center justify-end gap-1 mt-2 text-[10px] text-text-muted">
135
+ <span>Less</span>
136
+ {colors.map((color, i) => (
137
+ <div key={i} className={`w-[10px] h-[10px] rounded-sm ${color}`} />
138
+ ))}
139
+ <span>More</span>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ </div>
144
+ )
145
+ }
146
+
147
+ function formatDate(date: Date): string {
148
+ const year = date.getFullYear()
149
+ const month = String(date.getMonth() + 1).padStart(2, '0')
150
+ const day = String(date.getDate()).padStart(2, '0')
151
+ return `${year}-${month}-${day}`
152
+ }
153
+
154
+ interface StatCardProps {
155
+ label: string
156
+ value: number | string
157
+ change?: number
158
+ icon?: React.ReactNode
159
+ }
160
+
161
+ export function StatCard({ label, value, change, icon }: StatCardProps) {
162
+ return (
163
+ <div className="bg-bg-elevated border border-border rounded-lg p-4">
164
+ <div className="flex items-start justify-between">
165
+ <div>
166
+ <p className="text-xs text-text-muted mb-1">{label}</p>
167
+ <p className="text-2xl font-semibold text-text-primary">{value}</p>
168
+ {change !== undefined && (
169
+ <p className={`text-xs mt-1 ${change >= 0 ? 'text-success' : 'text-error'}`}>
170
+ {change >= 0 ? '+' : ''}{change}% from last period
171
+ </p>
172
+ )}
173
+ </div>
174
+ {icon && (
175
+ <div className="p-2 bg-bg-hover rounded-lg text-text-muted">
176
+ {icon}
177
+ </div>
178
+ )}
179
+ </div>
180
+ </div>
181
+ )
182
+ }
@@ -0,0 +1,203 @@
1
+ import { useEffect, useRef, type ReactNode } from 'react'
2
+ import { Icons } from './icons'
3
+ import { Button } from './button'
4
+
5
+ interface DialogProps {
6
+ open: boolean
7
+ onClose: () => void
8
+ title?: string
9
+ children: ReactNode
10
+ size?: 'small' | 'medium' | 'large'
11
+ }
12
+
13
+ export function Dialog({ open, onClose, title, children, size = 'medium' }: DialogProps) {
14
+ const dialogRef = useRef<HTMLDivElement>(null)
15
+
16
+ useEffect(() => {
17
+ if (!open) return
18
+
19
+ const handleEscape = (e: KeyboardEvent) => {
20
+ if (e.key === 'Escape') onClose()
21
+ }
22
+
23
+ document.addEventListener('keydown', handleEscape)
24
+ document.body.style.overflow = 'hidden'
25
+
26
+ return () => {
27
+ document.removeEventListener('keydown', handleEscape)
28
+ document.body.style.overflow = ''
29
+ }
30
+ }, [open, onClose])
31
+
32
+ if (!open) return null
33
+
34
+ const sizeClasses = {
35
+ small: 'max-w-md',
36
+ medium: 'max-w-lg',
37
+ large: 'max-w-4xl',
38
+ }
39
+
40
+ return (
41
+ <div className="fixed inset-0 z-50 flex items-center justify-center p-4 sm:p-6">
42
+ <div
43
+ className="absolute inset-0 bg-black/60 backdrop-blur-sm"
44
+ onClick={onClose}
45
+ />
46
+
47
+ <div
48
+ ref={dialogRef}
49
+ role="dialog"
50
+ aria-modal="true"
51
+ className={`relative bg-bg-secondary border border-border rounded-xl shadow-2xl w-full ${sizeClasses[size]} max-h-[85vh] overflow-y-auto touch-scroll`}
52
+ >
53
+ {title && (
54
+ <div className="flex items-center justify-between px-4 py-3 border-b border-border">
55
+ <h2 className="text-sm font-semibold text-text-primary">{title}</h2>
56
+ <button
57
+ onClick={onClose}
58
+ className="p-1 rounded-md hover:bg-bg-hover transition-colors"
59
+ >
60
+ <Icons.X className="w-4 h-4 text-text-muted" />
61
+ </button>
62
+ </div>
63
+ )}
64
+ {!title && (
65
+ <button
66
+ onClick={onClose}
67
+ className="absolute top-3 right-3 z-10 p-1 rounded-md hover:bg-bg-hover transition-colors"
68
+ >
69
+ <Icons.X className="w-4 h-4 text-text-muted" />
70
+ </button>
71
+ )}
72
+
73
+ <div className={title ? 'p-4' : ''}>{children}</div>
74
+ </div>
75
+ </div>
76
+ )
77
+ }
78
+
79
+ interface AlertDialogProps {
80
+ open: boolean
81
+ onClose: () => void
82
+ title: string
83
+ message: string
84
+ variant?: 'info' | 'warning' | 'error'
85
+ }
86
+
87
+ export function AlertDialog({ open, onClose, title, message, variant = 'info' }: AlertDialogProps) {
88
+ const iconColors = {
89
+ info: 'text-accent-blue bg-accent-blue/10',
90
+ warning: 'text-yellow-500 bg-yellow-500/10',
91
+ error: 'text-accent-red bg-accent-red/10',
92
+ }
93
+
94
+ return (
95
+ <Dialog open={open} onClose={onClose} title={title}>
96
+ <div className="flex gap-3">
97
+ <div className={`shrink-0 w-10 h-10 rounded-lg flex items-center justify-center ${iconColors[variant]}`}>
98
+ <Icons.Warning className="w-5 h-5" />
99
+ </div>
100
+ <div className="flex-1">
101
+ <p className="text-sm text-text-secondary leading-relaxed mb-4">{message}</p>
102
+ <div className="flex justify-end">
103
+ <Button variant="primary" size="sm" onClick={onClose}>
104
+ OK
105
+ </Button>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </Dialog>
110
+ )
111
+ }
112
+
113
+ interface PromptDialogProps {
114
+ open: boolean
115
+ onClose: () => void
116
+ onSubmit: (value: string) => void
117
+ title: string
118
+ placeholder?: string
119
+ submitLabel?: string
120
+ defaultValue?: string
121
+ }
122
+
123
+ export function PromptDialog({
124
+ open,
125
+ onClose,
126
+ onSubmit,
127
+ title,
128
+ placeholder = '',
129
+ submitLabel = 'Submit',
130
+ defaultValue = '',
131
+ }: PromptDialogProps) {
132
+ const inputRef = useRef<HTMLInputElement>(null)
133
+
134
+ useEffect(() => {
135
+ if (open && inputRef.current) {
136
+ inputRef.current.focus()
137
+ inputRef.current.value = defaultValue
138
+ }
139
+ }, [open, defaultValue])
140
+
141
+ const handleSubmit = (e: React.FormEvent) => {
142
+ e.preventDefault()
143
+ const value = inputRef.current?.value.trim()
144
+ if (value) {
145
+ onSubmit(value)
146
+ onClose()
147
+ }
148
+ }
149
+
150
+ return (
151
+ <Dialog open={open} onClose={onClose} title={title}>
152
+ <form onSubmit={handleSubmit}>
153
+ <input
154
+ ref={inputRef}
155
+ type="text"
156
+ placeholder={placeholder}
157
+ className="w-full bg-bg-tertiary border border-border rounded-lg px-3 py-2 text-sm text-text-primary placeholder:text-text-muted outline-none focus:border-text-muted transition-colors mb-4"
158
+ />
159
+ <div className="flex justify-end gap-2">
160
+ <Button variant="ghost" size="sm" onClick={onClose}>
161
+ Cancel
162
+ </Button>
163
+ <Button variant="primary" size="sm">
164
+ {submitLabel}
165
+ </Button>
166
+ </div>
167
+ </form>
168
+ </Dialog>
169
+ )
170
+ }
171
+
172
+ interface CopyDialogProps {
173
+ open: boolean
174
+ onClose: () => void
175
+ title: string
176
+ message: string
177
+ copyText: string
178
+ }
179
+
180
+ export function CopyDialog({ open, onClose, title, message, copyText }: CopyDialogProps) {
181
+ const handleCopy = async () => {
182
+ await navigator.clipboard.writeText(copyText)
183
+ onClose()
184
+ }
185
+
186
+ return (
187
+ <Dialog open={open} onClose={onClose} title={title}>
188
+ <p className="text-sm text-text-secondary leading-relaxed mb-3">{message}</p>
189
+ <div className="bg-bg-primary border border-border rounded-lg p-3 mb-4">
190
+ <code className="text-xs text-accent-blue break-all">{copyText}</code>
191
+ </div>
192
+ <div className="flex justify-end gap-2">
193
+ <Button variant="ghost" size="sm" onClick={onClose}>
194
+ Close
195
+ </Button>
196
+ <Button variant="primary" size="sm" onClick={handleCopy}>
197
+ <Icons.Copy className="w-3.5 h-3.5" />
198
+ Copy URL
199
+ </Button>
200
+ </div>
201
+ </Dialog>
202
+ )
203
+ }
@@ -0,0 +1,32 @@
1
+ import type { ReactNode, MouseEvent } from 'react'
2
+
3
+ export interface IconButtonProps {
4
+ icon: ReactNode
5
+ onClick?: (e?: MouseEvent<HTMLButtonElement>) => void
6
+ className?: string
7
+ size?: 'sm' | 'md'
8
+ disabled?: boolean
9
+ }
10
+
11
+ export function IconButton({
12
+ icon,
13
+ onClick,
14
+ className = '',
15
+ size = 'md',
16
+ disabled = false,
17
+ }: IconButtonProps) {
18
+ const sizeStyles = {
19
+ sm: 'p-1.5',
20
+ md: 'p-2',
21
+ }
22
+
23
+ return (
24
+ <button
25
+ onClick={onClick}
26
+ disabled={disabled}
27
+ className={`rounded-lg transition-colors ${sizeStyles[size]} ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-bg-hover'} ${className}`}
28
+ >
29
+ {icon}
30
+ </button>
31
+ )
32
+ }
@@ -0,0 +1,187 @@
1
+ interface IconProps {
2
+ className?: string
3
+ }
4
+
5
+ export const Icons = {
6
+ Plus: ({ className }: IconProps) => (
7
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
8
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 4v16m8-8H4" />
9
+ </svg>
10
+ ),
11
+
12
+ Search: ({ className }: IconProps) => (
13
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
14
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
15
+ </svg>
16
+ ),
17
+
18
+ Settings: ({ className }: IconProps) => (
19
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
20
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
21
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
22
+ </svg>
23
+ ),
24
+
25
+ Help: ({ className }: IconProps) => (
26
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
27
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
28
+ </svg>
29
+ ),
30
+
31
+ Grid: ({ className }: IconProps) => (
32
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
33
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" />
34
+ </svg>
35
+ ),
36
+
37
+ Clipboard: ({ className }: IconProps) => (
38
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
39
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
40
+ </svg>
41
+ ),
42
+
43
+ Archive: ({ className }: IconProps) => (
44
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
45
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" />
46
+ </svg>
47
+ ),
48
+
49
+ Bolt: ({ className }: IconProps) => (
50
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
51
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M13 10V3L4 14h7v7l9-11h-7z" />
52
+ </svg>
53
+ ),
54
+
55
+ BarChart: ({ className }: IconProps) => (
56
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
57
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
58
+ </svg>
59
+ ),
60
+
61
+ ChevronDown: ({ className }: IconProps) => (
62
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
63
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
64
+ </svg>
65
+ ),
66
+
67
+ ChevronUp: ({ className }: IconProps) => (
68
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
69
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 15l7-7 7 7" />
70
+ </svg>
71
+ ),
72
+
73
+ Copy: ({ className }: IconProps) => (
74
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
75
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
76
+ </svg>
77
+ ),
78
+
79
+ MoreVertical: ({ className }: IconProps) => (
80
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
81
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" />
82
+ </svg>
83
+ ),
84
+
85
+ Paperclip: ({ className }: IconProps) => (
86
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
87
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13" />
88
+ </svg>
89
+ ),
90
+
91
+ Microphone: ({ className }: IconProps) => (
92
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
93
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z" />
94
+ </svg>
95
+ ),
96
+
97
+ Send: ({ className }: IconProps) => (
98
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
99
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 10l7-7m0 0l7 7m-7-7v18" />
100
+ </svg>
101
+ ),
102
+
103
+ Warning: ({ className }: IconProps) => (
104
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
105
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
106
+ </svg>
107
+ ),
108
+
109
+ Check: ({ className }: IconProps) => (
110
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
111
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
112
+ </svg>
113
+ ),
114
+
115
+ X: ({ className }: IconProps) => (
116
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
117
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
118
+ </svg>
119
+ ),
120
+
121
+ Trash: ({ className }: IconProps) => (
122
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
123
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M6 7h12M9 7V5a1 1 0 011-1h4a1 1 0 011 1v2m-7 0l1 12a1 1 0 001 1h4a1 1 0 001-1l1-12" />
124
+ </svg>
125
+ ),
126
+
127
+ ArrowUp: ({ className }: IconProps) => (
128
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
129
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 10l7-7m0 0l7 7m-7-7v18" />
130
+ </svg>
131
+ ),
132
+
133
+ Loader: ({ className }: IconProps) => (
134
+ <svg className={`animate-spin ${className}`} fill="none" viewBox="0 0 24 24">
135
+ <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
136
+ <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
137
+ </svg>
138
+ ),
139
+
140
+ Sparkles: ({ className }: IconProps) => (
141
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
142
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" />
143
+ </svg>
144
+ ),
145
+
146
+ Terminal: ({ className }: IconProps) => (
147
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
148
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
149
+ </svg>
150
+ ),
151
+
152
+ File: ({ className }: IconProps) => (
153
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
154
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
155
+ </svg>
156
+ ),
157
+
158
+ Globe: ({ className }: IconProps) => (
159
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
160
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
161
+ </svg>
162
+ ),
163
+
164
+ Menu: ({ className }: IconProps) => (
165
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
166
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M4 6h16M4 12h16M4 18h16" />
167
+ </svg>
168
+ ),
169
+
170
+ List: ({ className }: IconProps) => (
171
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
172
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M4 6h16M4 10h16M4 14h16M4 18h16" />
173
+ </svg>
174
+ ),
175
+
176
+ ChevronLeft: ({ className }: IconProps) => (
177
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
178
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
179
+ </svg>
180
+ ),
181
+
182
+ ChevronRight: ({ className }: IconProps) => (
183
+ <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor">
184
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
185
+ </svg>
186
+ ),
187
+ }
@@ -0,0 +1,15 @@
1
+ export { Icons } from './icons'
2
+ export { Button } from './button'
3
+ export { IconButton } from './icon-button'
4
+ export { Avatar } from './avatar'
5
+ export { StatusDot } from './status-dot'
6
+ export { Badge } from './badge'
7
+ export { Input } from './input'
8
+ export { Select, type SelectOption } from './select'
9
+ export { SectionHeader } from './section-header'
10
+ export { Dialog, AlertDialog, PromptDialog, CopyDialog } from './dialog-box'
11
+ export { Markdown } from './markdown-stream'
12
+ export { ShimmerText, ShimmerDots, ThinkingIndicator, PulsingDot } from './shimmer'
13
+ export { CollapsibleContent, CollapsibleCodeBlock } from './collapsible-content'
14
+ export { MobileDrawer, MobileSheet } from './mobile-drawer'
15
+ export { ContributionGraph, StatCard } from './contribution-graph'
@@ -0,0 +1,43 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ interface InputProps {
4
+ placeholder?: string
5
+ value?: string
6
+ onChange?: (value: string) => void
7
+ onFocus?: () => void
8
+ onBlur?: () => void
9
+ onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void
10
+ className?: string
11
+ icon?: ReactNode
12
+ }
13
+
14
+ export function Input({
15
+ placeholder,
16
+ value,
17
+ onChange,
18
+ onFocus,
19
+ onBlur,
20
+ onKeyDown,
21
+ className = '',
22
+ icon,
23
+ }: InputProps) {
24
+ return (
25
+ <div className={`relative ${className}`}>
26
+ {icon && (
27
+ <div className="absolute left-3 top-1/2 -translate-y-1/2 text-text-muted">
28
+ {icon}
29
+ </div>
30
+ )}
31
+ <input
32
+ type="text"
33
+ placeholder={placeholder}
34
+ value={value}
35
+ onChange={(e) => onChange?.(e.target.value)}
36
+ onFocus={onFocus}
37
+ onBlur={onBlur}
38
+ onKeyDown={onKeyDown}
39
+ className={`w-full bg-bg-tertiary border border-border rounded-lg py-2 text-sm text-text-primary placeholder:text-text-muted outline-none focus:border-text-muted transition-colors ${icon ? 'pl-10 pr-4' : 'px-4'}`}
40
+ />
41
+ </div>
42
+ )
43
+ }
@@ -0,0 +1,21 @@
1
+ import { Streamdown } from 'streamdown'
2
+
3
+ interface MarkdownProps {
4
+ content: string
5
+ className?: string
6
+ streaming?: boolean
7
+ }
8
+
9
+ export function Markdown({ content, className = '', streaming = false }: MarkdownProps) {
10
+ return (
11
+ <div className={`markdown-content ${className}`}>
12
+ <Streamdown
13
+ mode={streaming ? 'streaming' : 'static'}
14
+ controls={false}
15
+ shikiTheme={['tokyo-night', 'tokyo-night']}
16
+ >
17
+ {content}
18
+ </Streamdown>
19
+ </div>
20
+ )
21
+ }