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.
- package/README.md +26 -0
- package/apps/backend/README.md +46 -0
- package/apps/backend/bun.lock +64 -0
- package/apps/backend/package.json +18 -0
- package/apps/backend/scripts/generate-protocol.ts +32 -0
- package/apps/backend/src/analytics/service.ts +219 -0
- package/apps/backend/src/analytics/store.ts +284 -0
- package/apps/backend/src/config.ts +98 -0
- package/apps/backend/src/core/app-server.ts +131 -0
- package/apps/backend/src/core/jsonrpc.ts +166 -0
- package/apps/backend/src/protocol/AbsolutePathBuf.ts +14 -0
- package/apps/backend/src/protocol/AddConversationListenerParams.ts +6 -0
- package/apps/backend/src/protocol/AddConversationSubscriptionResponse.ts +5 -0
- package/apps/backend/src/protocol/AgentMessageContent.ts +5 -0
- package/apps/backend/src/protocol/AgentMessageContentDeltaEvent.ts +5 -0
- package/apps/backend/src/protocol/AgentMessageDeltaEvent.ts +5 -0
- package/apps/backend/src/protocol/AgentMessageEvent.ts +5 -0
- package/apps/backend/src/protocol/AgentMessageItem.ts +6 -0
- package/apps/backend/src/protocol/AgentReasoningDeltaEvent.ts +5 -0
- package/apps/backend/src/protocol/AgentReasoningEvent.ts +5 -0
- package/apps/backend/src/protocol/AgentReasoningRawContentDeltaEvent.ts +5 -0
- package/apps/backend/src/protocol/AgentReasoningRawContentEvent.ts +5 -0
- package/apps/backend/src/protocol/AgentReasoningSectionBreakEvent.ts +5 -0
- package/apps/backend/src/protocol/Annotations.ts +9 -0
- package/apps/backend/src/protocol/ApplyPatchApprovalParams.ts +21 -0
- package/apps/backend/src/protocol/ApplyPatchApprovalRequestEvent.ts +23 -0
- package/apps/backend/src/protocol/ApplyPatchApprovalResponse.ts +6 -0
- package/apps/backend/src/protocol/ArchiveConversationParams.ts +6 -0
- package/apps/backend/src/protocol/ArchiveConversationResponse.ts +5 -0
- package/apps/backend/src/protocol/AskForApproval.ts +9 -0
- package/apps/backend/src/protocol/AudioContent.ts +9 -0
- package/apps/backend/src/protocol/AuthMode.ts +5 -0
- package/apps/backend/src/protocol/AuthStatusChangeNotification.ts +9 -0
- package/apps/backend/src/protocol/BackgroundEventEvent.ts +5 -0
- package/apps/backend/src/protocol/BlobResourceContents.ts +5 -0
- package/apps/backend/src/protocol/CallToolResult.ts +10 -0
- package/apps/backend/src/protocol/CancelLoginChatGptParams.ts +5 -0
- package/apps/backend/src/protocol/CancelLoginChatGptResponse.ts +5 -0
- package/apps/backend/src/protocol/ClientInfo.ts +5 -0
- package/apps/backend/src/protocol/ClientNotification.ts +5 -0
- package/apps/backend/src/protocol/ClientRequest.ts +46 -0
- package/apps/backend/src/protocol/CodexErrorInfo.ts +8 -0
- package/apps/backend/src/protocol/ContentBlock.ts +10 -0
- package/apps/backend/src/protocol/ContentItem.ts +5 -0
- package/apps/backend/src/protocol/ContextCompactedEvent.ts +5 -0
- package/apps/backend/src/protocol/ConversationGitInfo.ts +5 -0
- package/apps/backend/src/protocol/ConversationId.ts +5 -0
- package/apps/backend/src/protocol/ConversationSummary.ts +8 -0
- package/apps/backend/src/protocol/CreditsSnapshot.ts +5 -0
- package/apps/backend/src/protocol/CustomPrompt.ts +5 -0
- package/apps/backend/src/protocol/DeprecationNoticeEvent.ts +13 -0
- package/apps/backend/src/protocol/ElicitationRequestEvent.ts +6 -0
- package/apps/backend/src/protocol/EmbeddedResource.ts +13 -0
- package/apps/backend/src/protocol/EmbeddedResourceResource.ts +7 -0
- package/apps/backend/src/protocol/ErrorEvent.ts +6 -0
- package/apps/backend/src/protocol/EventMsg.ts +60 -0
- package/apps/backend/src/protocol/ExecApprovalRequestEvent.ts +32 -0
- package/apps/backend/src/protocol/ExecCommandApprovalParams.ts +12 -0
- package/apps/backend/src/protocol/ExecCommandApprovalResponse.ts +6 -0
- package/apps/backend/src/protocol/ExecCommandBeginEvent.ts +35 -0
- package/apps/backend/src/protocol/ExecCommandEndEvent.ts +59 -0
- package/apps/backend/src/protocol/ExecCommandOutputDeltaEvent.ts +18 -0
- package/apps/backend/src/protocol/ExecCommandSource.ts +5 -0
- package/apps/backend/src/protocol/ExecOneOffCommandParams.ts +6 -0
- package/apps/backend/src/protocol/ExecOneOffCommandResponse.ts +5 -0
- package/apps/backend/src/protocol/ExecOutputStream.ts +5 -0
- package/apps/backend/src/protocol/ExecPolicyAmendment.ts +12 -0
- package/apps/backend/src/protocol/ExitedReviewModeEvent.ts +6 -0
- package/apps/backend/src/protocol/FileChange.ts +5 -0
- package/apps/backend/src/protocol/ForcedLoginMethod.ts +5 -0
- package/apps/backend/src/protocol/FunctionCallOutputContentItem.ts +9 -0
- package/apps/backend/src/protocol/FunctionCallOutputPayload.ts +15 -0
- package/apps/backend/src/protocol/FuzzyFileSearchParams.ts +5 -0
- package/apps/backend/src/protocol/FuzzyFileSearchResponse.ts +6 -0
- package/apps/backend/src/protocol/FuzzyFileSearchResult.ts +8 -0
- package/apps/backend/src/protocol/GetAuthStatusParams.ts +5 -0
- package/apps/backend/src/protocol/GetAuthStatusResponse.ts +6 -0
- package/apps/backend/src/protocol/GetConversationSummaryParams.ts +6 -0
- package/apps/backend/src/protocol/GetConversationSummaryResponse.ts +6 -0
- package/apps/backend/src/protocol/GetHistoryEntryResponseEvent.ts +10 -0
- package/apps/backend/src/protocol/GetUserAgentResponse.ts +5 -0
- package/apps/backend/src/protocol/GetUserSavedConfigResponse.ts +6 -0
- package/apps/backend/src/protocol/GhostCommit.ts +8 -0
- package/apps/backend/src/protocol/GitDiffToRemoteParams.ts +5 -0
- package/apps/backend/src/protocol/GitDiffToRemoteResponse.ts +6 -0
- package/apps/backend/src/protocol/GitSha.ts +5 -0
- package/apps/backend/src/protocol/HistoryEntry.ts +5 -0
- package/apps/backend/src/protocol/ImageContent.ts +9 -0
- package/apps/backend/src/protocol/InitializeParams.ts +6 -0
- package/apps/backend/src/protocol/InitializeResponse.ts +5 -0
- package/apps/backend/src/protocol/InputItem.ts +5 -0
- package/apps/backend/src/protocol/InterruptConversationParams.ts +6 -0
- package/apps/backend/src/protocol/InterruptConversationResponse.ts +6 -0
- package/apps/backend/src/protocol/ItemCompletedEvent.ts +7 -0
- package/apps/backend/src/protocol/ItemStartedEvent.ts +7 -0
- package/apps/backend/src/protocol/ListConversationsParams.ts +5 -0
- package/apps/backend/src/protocol/ListConversationsResponse.ts +6 -0
- package/apps/backend/src/protocol/ListCustomPromptsResponseEvent.ts +9 -0
- package/apps/backend/src/protocol/ListSkillsResponseEvent.ts +9 -0
- package/apps/backend/src/protocol/LocalShellAction.ts +6 -0
- package/apps/backend/src/protocol/LocalShellExecAction.ts +5 -0
- package/apps/backend/src/protocol/LocalShellStatus.ts +5 -0
- package/apps/backend/src/protocol/LoginApiKeyParams.ts +5 -0
- package/apps/backend/src/protocol/LoginApiKeyResponse.ts +5 -0
- package/apps/backend/src/protocol/LoginChatGptCompleteNotification.ts +8 -0
- package/apps/backend/src/protocol/LoginChatGptResponse.ts +5 -0
- package/apps/backend/src/protocol/LogoutChatGptResponse.ts +5 -0
- package/apps/backend/src/protocol/McpAuthStatus.ts +5 -0
- package/apps/backend/src/protocol/McpInvocation.ts +18 -0
- package/apps/backend/src/protocol/McpListToolsResponseEvent.ts +25 -0
- package/apps/backend/src/protocol/McpStartupCompleteEvent.ts +6 -0
- package/apps/backend/src/protocol/McpStartupFailure.ts +5 -0
- package/apps/backend/src/protocol/McpStartupStatus.ts +5 -0
- package/apps/backend/src/protocol/McpStartupUpdateEvent.ts +14 -0
- package/apps/backend/src/protocol/McpToolCallBeginEvent.ts +10 -0
- package/apps/backend/src/protocol/McpToolCallEndEvent.ts +15 -0
- package/apps/backend/src/protocol/NetworkAccess.ts +8 -0
- package/apps/backend/src/protocol/NewConversationParams.ts +8 -0
- package/apps/backend/src/protocol/NewConversationResponse.ts +7 -0
- package/apps/backend/src/protocol/ParsedCommand.ts +12 -0
- package/apps/backend/src/protocol/PatchApplyBeginEvent.ts +23 -0
- package/apps/backend/src/protocol/PatchApplyEndEvent.ts +31 -0
- package/apps/backend/src/protocol/PlanItemArg.ts +6 -0
- package/apps/backend/src/protocol/PlanType.ts +5 -0
- package/apps/backend/src/protocol/Profile.ts +9 -0
- package/apps/backend/src/protocol/README.md +11 -0
- package/apps/backend/src/protocol/RateLimitSnapshot.ts +8 -0
- package/apps/backend/src/protocol/RateLimitWindow.ts +17 -0
- package/apps/backend/src/protocol/RawResponseItemEvent.ts +6 -0
- package/apps/backend/src/protocol/ReasoningContentDeltaEvent.ts +5 -0
- package/apps/backend/src/protocol/ReasoningEffort.ts +8 -0
- package/apps/backend/src/protocol/ReasoningItem.ts +5 -0
- package/apps/backend/src/protocol/ReasoningItemContent.ts +5 -0
- package/apps/backend/src/protocol/ReasoningItemReasoningSummary.ts +5 -0
- package/apps/backend/src/protocol/ReasoningRawContentDeltaEvent.ts +5 -0
- package/apps/backend/src/protocol/ReasoningSummary.ts +10 -0
- package/apps/backend/src/protocol/RemoveConversationListenerParams.ts +5 -0
- package/apps/backend/src/protocol/RemoveConversationSubscriptionResponse.ts +5 -0
- package/apps/backend/src/protocol/RequestId.ts +5 -0
- package/apps/backend/src/protocol/Resource.ts +9 -0
- package/apps/backend/src/protocol/ResourceLink.ts +11 -0
- package/apps/backend/src/protocol/ResourceTemplate.ts +9 -0
- package/apps/backend/src/protocol/ResponseItem.ts +17 -0
- package/apps/backend/src/protocol/ResumeConversationParams.ts +8 -0
- package/apps/backend/src/protocol/ResumeConversationResponse.ts +7 -0
- package/apps/backend/src/protocol/ReviewCodeLocation.ts +9 -0
- package/apps/backend/src/protocol/ReviewDecision.ts +9 -0
- package/apps/backend/src/protocol/ReviewFinding.ts +9 -0
- package/apps/backend/src/protocol/ReviewLineRange.ts +8 -0
- package/apps/backend/src/protocol/ReviewOutputEvent.ts +9 -0
- package/apps/backend/src/protocol/ReviewRequest.ts +9 -0
- package/apps/backend/src/protocol/ReviewTarget.ts +9 -0
- package/apps/backend/src/protocol/Role.ts +8 -0
- package/apps/backend/src/protocol/SandboxMode.ts +5 -0
- package/apps/backend/src/protocol/SandboxPolicy.ts +35 -0
- package/apps/backend/src/protocol/SandboxSettings.ts +6 -0
- package/apps/backend/src/protocol/SendUserMessageParams.ts +7 -0
- package/apps/backend/src/protocol/SendUserMessageResponse.ts +5 -0
- package/apps/backend/src/protocol/SendUserTurnParams.ts +11 -0
- package/apps/backend/src/protocol/SendUserTurnResponse.ts +5 -0
- package/apps/backend/src/protocol/ServerNotification.ts +36 -0
- package/apps/backend/src/protocol/ServerRequest.ts +13 -0
- package/apps/backend/src/protocol/SessionConfiguredEvent.ts +48 -0
- package/apps/backend/src/protocol/SessionConfiguredNotification.ts +8 -0
- package/apps/backend/src/protocol/SessionSource.ts +6 -0
- package/apps/backend/src/protocol/SetDefaultModelParams.ts +6 -0
- package/apps/backend/src/protocol/SetDefaultModelResponse.ts +5 -0
- package/apps/backend/src/protocol/SkillErrorInfo.ts +5 -0
- package/apps/backend/src/protocol/SkillMetadata.ts +6 -0
- package/apps/backend/src/protocol/SkillScope.ts +5 -0
- package/apps/backend/src/protocol/SkillsListEntry.ts +7 -0
- package/apps/backend/src/protocol/StepStatus.ts +5 -0
- package/apps/backend/src/protocol/StreamErrorEvent.ts +6 -0
- package/apps/backend/src/protocol/SubAgentSource.ts +5 -0
- package/apps/backend/src/protocol/TaskCompleteEvent.ts +5 -0
- package/apps/backend/src/protocol/TaskStartedEvent.ts +5 -0
- package/apps/backend/src/protocol/TerminalInteractionEvent.ts +17 -0
- package/apps/backend/src/protocol/TextContent.ts +9 -0
- package/apps/backend/src/protocol/TextResourceContents.ts +5 -0
- package/apps/backend/src/protocol/TokenCountEvent.ts +7 -0
- package/apps/backend/src/protocol/TokenUsage.ts +5 -0
- package/apps/backend/src/protocol/TokenUsageInfo.ts +6 -0
- package/apps/backend/src/protocol/Tool.ts +11 -0
- package/apps/backend/src/protocol/ToolAnnotations.ts +15 -0
- package/apps/backend/src/protocol/ToolInputSchema.ts +9 -0
- package/apps/backend/src/protocol/ToolOutputSchema.ts +10 -0
- package/apps/backend/src/protocol/Tools.ts +5 -0
- package/apps/backend/src/protocol/TurnAbortReason.ts +5 -0
- package/apps/backend/src/protocol/TurnAbortedEvent.ts +6 -0
- package/apps/backend/src/protocol/TurnDiffEvent.ts +5 -0
- package/apps/backend/src/protocol/TurnItem.ts +9 -0
- package/apps/backend/src/protocol/UndoCompletedEvent.ts +5 -0
- package/apps/backend/src/protocol/UndoStartedEvent.ts +5 -0
- package/apps/backend/src/protocol/UpdatePlanArgs.ts +6 -0
- package/apps/backend/src/protocol/UserInfoResponse.ts +5 -0
- package/apps/backend/src/protocol/UserInput.ts +8 -0
- package/apps/backend/src/protocol/UserMessageEvent.ts +5 -0
- package/apps/backend/src/protocol/UserMessageItem.ts +6 -0
- package/apps/backend/src/protocol/UserSavedConfig.ts +14 -0
- package/apps/backend/src/protocol/Verbosity.ts +9 -0
- package/apps/backend/src/protocol/ViewImageToolCallEvent.ts +13 -0
- package/apps/backend/src/protocol/WarningEvent.ts +5 -0
- package/apps/backend/src/protocol/WebSearchAction.ts +5 -0
- package/apps/backend/src/protocol/WebSearchBeginEvent.ts +5 -0
- package/apps/backend/src/protocol/WebSearchEndEvent.ts +5 -0
- package/apps/backend/src/protocol/WebSearchItem.ts +5 -0
- package/apps/backend/src/protocol/index.ts +198 -0
- package/apps/backend/src/protocol/serde_json/JsonValue.ts +5 -0
- package/apps/backend/src/protocol/v2/Account.ts +6 -0
- package/apps/backend/src/protocol/v2/AccountLoginCompletedNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/AccountRateLimitsUpdatedNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/AccountUpdatedNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/AgentMessageDeltaNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/ApprovalDecision.ts +6 -0
- package/apps/backend/src/protocol/v2/AskForApproval.ts +5 -0
- package/apps/backend/src/protocol/v2/CancelLoginAccountParams.ts +5 -0
- package/apps/backend/src/protocol/v2/CancelLoginAccountResponse.ts +6 -0
- package/apps/backend/src/protocol/v2/CancelLoginAccountStatus.ts +5 -0
- package/apps/backend/src/protocol/v2/CodexErrorInfo.ts +11 -0
- package/apps/backend/src/protocol/v2/CommandAction.ts +5 -0
- package/apps/backend/src/protocol/v2/CommandExecParams.ts +6 -0
- package/apps/backend/src/protocol/v2/CommandExecResponse.ts +5 -0
- package/apps/backend/src/protocol/v2/CommandExecutionOutputDeltaNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/CommandExecutionRequestApprovalParams.ts +14 -0
- package/apps/backend/src/protocol/v2/CommandExecutionRequestApprovalResponse.ts +6 -0
- package/apps/backend/src/protocol/v2/CommandExecutionStatus.ts +5 -0
- package/apps/backend/src/protocol/v2/Config.ts +15 -0
- package/apps/backend/src/protocol/v2/ConfigBatchWriteParams.ts +10 -0
- package/apps/backend/src/protocol/v2/ConfigEdit.ts +7 -0
- package/apps/backend/src/protocol/v2/ConfigLayer.ts +7 -0
- package/apps/backend/src/protocol/v2/ConfigLayerMetadata.ts +6 -0
- package/apps/backend/src/protocol/v2/ConfigLayerSource.ts +6 -0
- package/apps/backend/src/protocol/v2/ConfigReadParams.ts +5 -0
- package/apps/backend/src/protocol/v2/ConfigReadResponse.ts +8 -0
- package/apps/backend/src/protocol/v2/ConfigValueWriteParams.ts +11 -0
- package/apps/backend/src/protocol/v2/ConfigWriteResponse.ts +12 -0
- package/apps/backend/src/protocol/v2/ContextCompactedNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/CreditsSnapshot.ts +5 -0
- package/apps/backend/src/protocol/v2/DeprecationNoticeNotification.ts +13 -0
- package/apps/backend/src/protocol/v2/ErrorNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/ExecPolicyAmendment.ts +5 -0
- package/apps/backend/src/protocol/v2/FeedbackUploadParams.ts +5 -0
- package/apps/backend/src/protocol/v2/FeedbackUploadResponse.ts +5 -0
- package/apps/backend/src/protocol/v2/FileChangeOutputDeltaNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/FileChangeRequestApprovalParams.ts +14 -0
- package/apps/backend/src/protocol/v2/FileChangeRequestApprovalResponse.ts +6 -0
- package/apps/backend/src/protocol/v2/FileUpdateChange.ts +6 -0
- package/apps/backend/src/protocol/v2/GetAccountParams.ts +5 -0
- package/apps/backend/src/protocol/v2/GetAccountRateLimitsResponse.ts +6 -0
- package/apps/backend/src/protocol/v2/GetAccountResponse.ts +6 -0
- package/apps/backend/src/protocol/v2/GitInfo.ts +5 -0
- package/apps/backend/src/protocol/v2/ItemCompletedNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/ItemStartedNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/ListMcpServerStatusParams.ts +13 -0
- package/apps/backend/src/protocol/v2/ListMcpServerStatusResponse.ts +11 -0
- package/apps/backend/src/protocol/v2/LoginAccountParams.ts +5 -0
- package/apps/backend/src/protocol/v2/LoginAccountResponse.ts +9 -0
- package/apps/backend/src/protocol/v2/LogoutAccountResponse.ts +5 -0
- package/apps/backend/src/protocol/v2/McpAuthStatus.ts +5 -0
- package/apps/backend/src/protocol/v2/McpServerOauthLoginCompletedNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/McpServerOauthLoginParams.ts +5 -0
- package/apps/backend/src/protocol/v2/McpServerOauthLoginResponse.ts +5 -0
- package/apps/backend/src/protocol/v2/McpServerStatus.ts +9 -0
- package/apps/backend/src/protocol/v2/McpToolCallError.ts +5 -0
- package/apps/backend/src/protocol/v2/McpToolCallProgressNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/McpToolCallResult.ts +7 -0
- package/apps/backend/src/protocol/v2/McpToolCallStatus.ts +5 -0
- package/apps/backend/src/protocol/v2/MergeStrategy.ts +5 -0
- package/apps/backend/src/protocol/v2/Model.ts +7 -0
- package/apps/backend/src/protocol/v2/ModelListParams.ts +13 -0
- package/apps/backend/src/protocol/v2/ModelListResponse.ts +11 -0
- package/apps/backend/src/protocol/v2/NetworkAccess.ts +5 -0
- package/apps/backend/src/protocol/v2/OverriddenMetadata.ts +7 -0
- package/apps/backend/src/protocol/v2/PatchApplyStatus.ts +5 -0
- package/apps/backend/src/protocol/v2/PatchChangeKind.ts +5 -0
- package/apps/backend/src/protocol/v2/ProfileV2.ts +10 -0
- package/apps/backend/src/protocol/v2/RateLimitSnapshot.ts +8 -0
- package/apps/backend/src/protocol/v2/RateLimitWindow.ts +5 -0
- package/apps/backend/src/protocol/v2/RawResponseItemCompletedNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/ReasoningEffortOption.ts +6 -0
- package/apps/backend/src/protocol/v2/ReasoningSummaryPartAddedNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/ReasoningSummaryTextDeltaNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/ReasoningTextDeltaNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/ReviewDelivery.ts +5 -0
- package/apps/backend/src/protocol/v2/ReviewStartParams.ts +12 -0
- package/apps/backend/src/protocol/v2/ReviewStartResponse.ts +13 -0
- package/apps/backend/src/protocol/v2/ReviewTarget.ts +9 -0
- package/apps/backend/src/protocol/v2/SandboxMode.ts +5 -0
- package/apps/backend/src/protocol/v2/SandboxPolicy.ts +7 -0
- package/apps/backend/src/protocol/v2/SandboxWorkspaceWrite.ts +5 -0
- package/apps/backend/src/protocol/v2/SessionSource.ts +5 -0
- package/apps/backend/src/protocol/v2/SkillErrorInfo.ts +5 -0
- package/apps/backend/src/protocol/v2/SkillMetadata.ts +6 -0
- package/apps/backend/src/protocol/v2/SkillScope.ts +5 -0
- package/apps/backend/src/protocol/v2/SkillsListEntry.ts +7 -0
- package/apps/backend/src/protocol/v2/SkillsListParams.ts +13 -0
- package/apps/backend/src/protocol/v2/SkillsListResponse.ts +6 -0
- package/apps/backend/src/protocol/v2/TerminalInteractionNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/Thread.ts +46 -0
- package/apps/backend/src/protocol/v2/ThreadArchiveParams.ts +5 -0
- package/apps/backend/src/protocol/v2/ThreadArchiveResponse.ts +5 -0
- package/apps/backend/src/protocol/v2/ThreadItem.ts +48 -0
- package/apps/backend/src/protocol/v2/ThreadListParams.ts +18 -0
- package/apps/backend/src/protocol/v2/ThreadListResponse.ts +11 -0
- package/apps/backend/src/protocol/v2/ThreadResumeParams.ts +35 -0
- package/apps/backend/src/protocol/v2/ThreadResumeResponse.ts +9 -0
- package/apps/backend/src/protocol/v2/ThreadStartParams.ts +15 -0
- package/apps/backend/src/protocol/v2/ThreadStartResponse.ts +9 -0
- package/apps/backend/src/protocol/v2/ThreadStartedNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/ThreadTokenUsage.ts +6 -0
- package/apps/backend/src/protocol/v2/ThreadTokenUsageUpdatedNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/TokenUsageBreakdown.ts +5 -0
- package/apps/backend/src/protocol/v2/ToolsV2.ts +5 -0
- package/apps/backend/src/protocol/v2/Turn.ts +18 -0
- package/apps/backend/src/protocol/v2/TurnCompletedNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/TurnDiffUpdatedNotification.ts +9 -0
- package/apps/backend/src/protocol/v2/TurnError.ts +6 -0
- package/apps/backend/src/protocol/v2/TurnInterruptParams.ts +5 -0
- package/apps/backend/src/protocol/v2/TurnInterruptResponse.ts +5 -0
- package/apps/backend/src/protocol/v2/TurnPlanStep.ts +6 -0
- package/apps/backend/src/protocol/v2/TurnPlanStepStatus.ts +5 -0
- package/apps/backend/src/protocol/v2/TurnPlanUpdatedNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/TurnStartParams.ts +34 -0
- package/apps/backend/src/protocol/v2/TurnStartResponse.ts +6 -0
- package/apps/backend/src/protocol/v2/TurnStartedNotification.ts +6 -0
- package/apps/backend/src/protocol/v2/TurnStatus.ts +5 -0
- package/apps/backend/src/protocol/v2/UserInput.ts +5 -0
- package/apps/backend/src/protocol/v2/WindowsWorldWritableWarningNotification.ts +5 -0
- package/apps/backend/src/protocol/v2/WriteStatus.ts +5 -0
- package/apps/backend/src/protocol/v2/index.ts +123 -0
- package/apps/backend/src/reviews/service.ts +27 -0
- package/apps/backend/src/reviews/store.ts +124 -0
- package/apps/backend/src/server.ts +531 -0
- package/apps/backend/src/services/profile-store.ts +114 -0
- package/apps/backend/src/services/supervisor.ts +102 -0
- package/apps/backend/src/thread-index/service.ts +75 -0
- package/apps/backend/src/thread-index/store.ts +195 -0
- package/apps/backend/src/ws/messages.ts +73 -0
- package/apps/backend/tsconfig.json +20 -0
- package/apps/web/README.md +24 -0
- package/apps/web/bun.lock +1062 -0
- package/apps/web/eslint.config.js +23 -0
- package/apps/web/index.html +16 -0
- package/apps/web/package.json +38 -0
- package/apps/web/src/app.tsx +83 -0
- package/apps/web/src/components/composer/slash-command-menu.tsx +47 -0
- package/apps/web/src/components/index.ts +2 -0
- package/apps/web/src/components/layout/account-usage-panel.tsx +167 -0
- package/apps/web/src/components/layout/analytics-view.tsx +296 -0
- package/apps/web/src/components/layout/index.ts +7 -0
- package/apps/web/src/components/layout/mobile-header.tsx +56 -0
- package/apps/web/src/components/layout/reviews-view.tsx +848 -0
- package/apps/web/src/components/layout/session-view.tsx +1374 -0
- package/apps/web/src/components/layout/settings-dialog.tsx +322 -0
- package/apps/web/src/components/layout/side-bar.tsx +417 -0
- package/apps/web/src/components/layout/thread-list.tsx +488 -0
- package/apps/web/src/components/layout/virtualized-message-list.tsx +748 -0
- package/apps/web/src/components/loading/startup-ascii.ts +652 -0
- package/apps/web/src/components/loading/startup-loader.tsx +37 -0
- package/apps/web/src/components/session-view/file-mention-menu.tsx +46 -0
- package/apps/web/src/components/session-view/session-auth-banner.tsx +61 -0
- package/apps/web/src/components/session-view/session-composer.tsx +328 -0
- package/apps/web/src/components/session-view/session-dialogs.tsx +280 -0
- package/apps/web/src/components/session-view/session-empty.tsx +47 -0
- package/apps/web/src/components/session-view/session-header.tsx +49 -0
- package/apps/web/src/components/ui/avatar.tsx +19 -0
- package/apps/web/src/components/ui/badge.tsx +21 -0
- package/apps/web/src/components/ui/button.tsx +47 -0
- package/apps/web/src/components/ui/collapsible-content.tsx +114 -0
- package/apps/web/src/components/ui/contribution-graph.tsx +182 -0
- package/apps/web/src/components/ui/dialog-box.tsx +203 -0
- package/apps/web/src/components/ui/icon-button.tsx +32 -0
- package/apps/web/src/components/ui/icons.tsx +187 -0
- package/apps/web/src/components/ui/index.tsx +15 -0
- package/apps/web/src/components/ui/input.tsx +43 -0
- package/apps/web/src/components/ui/markdown-stream.tsx +21 -0
- package/apps/web/src/components/ui/mobile-drawer.tsx +124 -0
- package/apps/web/src/components/ui/section-header.tsx +13 -0
- package/apps/web/src/components/ui/select.tsx +217 -0
- package/apps/web/src/components/ui/shimmer.tsx +138 -0
- package/apps/web/src/components/ui/status-dot.tsx +24 -0
- package/apps/web/src/config.ts +5 -0
- package/apps/web/src/hooks/index.ts +3 -0
- package/apps/web/src/hooks/use-analytics.ts +122 -0
- package/apps/web/src/hooks/use-hub-connection.ts +587 -0
- package/apps/web/src/hooks/use-mobile.ts +76 -0
- package/apps/web/src/hooks/use-thread-history.ts +210 -0
- package/apps/web/src/index.css +269 -0
- package/apps/web/src/main.tsx +10 -0
- package/apps/web/src/services/hub-client.ts +358 -0
- package/apps/web/src/store/index.ts +528 -0
- package/apps/web/src/types/index.ts +119 -0
- package/apps/web/src/utils/account-refresh.ts +168 -0
- package/apps/web/src/utils/approval-policy.ts +53 -0
- package/apps/web/src/utils/init-prompt.ts +41 -0
- package/apps/web/src/utils/item-format.ts +170 -0
- package/apps/web/src/utils/prompt-expander.ts +62 -0
- package/apps/web/src/utils/reasoning-summary.ts +48 -0
- package/apps/web/src/utils/slash-commands.ts +98 -0
- package/apps/web/tsconfig.app.json +28 -0
- package/apps/web/tsconfig.json +7 -0
- package/apps/web/tsconfig.node.json +26 -0
- package/apps/web/vite.config.ts +8 -0
- package/bin/better-codex.cjs +199 -0
- package/package.json +20 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { Account, AccountStatus, AccountUsage, ModelInfo } from '../types'
|
|
2
|
+
import { hubClient } from '../services/hub-client'
|
|
3
|
+
|
|
4
|
+
export type AccountReadResult = {
|
|
5
|
+
account?: {
|
|
6
|
+
type: string
|
|
7
|
+
email?: string
|
|
8
|
+
planType?: string
|
|
9
|
+
} | null
|
|
10
|
+
requiresOpenaiAuth?: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type RateLimitWindowRaw = {
|
|
14
|
+
used_percent?: number
|
|
15
|
+
usedPercent?: number
|
|
16
|
+
window_minutes?: number | null
|
|
17
|
+
windowDurationMins?: number | null
|
|
18
|
+
resets_at?: number | null
|
|
19
|
+
resetsAt?: number | null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type CreditsSnapshotRaw = {
|
|
23
|
+
has_credits?: boolean
|
|
24
|
+
hasCredits?: boolean
|
|
25
|
+
unlimited?: boolean
|
|
26
|
+
balance?: string | null
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type RateLimitResult = {
|
|
30
|
+
rateLimits?: {
|
|
31
|
+
primary?: RateLimitWindowRaw | null
|
|
32
|
+
secondary?: RateLimitWindowRaw | null
|
|
33
|
+
credits?: CreditsSnapshotRaw | null
|
|
34
|
+
plan_type?: string | null
|
|
35
|
+
planType?: string | null
|
|
36
|
+
} | null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type ModelListResult = {
|
|
40
|
+
data?: ModelInfo[]
|
|
41
|
+
nextCursor?: string | null
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const readNumber = (...values: Array<number | null | undefined>) => {
|
|
45
|
+
for (const value of values) {
|
|
46
|
+
if (typeof value === 'number') {
|
|
47
|
+
return value
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return 0
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const readNumberOrNull = (...values: Array<number | null | undefined>) => {
|
|
54
|
+
for (const value of values) {
|
|
55
|
+
if (typeof value === 'number') {
|
|
56
|
+
return value
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return null
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const parseUsage = (result: RateLimitResult): AccountUsage | undefined => {
|
|
63
|
+
const limits = result.rateLimits
|
|
64
|
+
if (!limits) return undefined
|
|
65
|
+
return {
|
|
66
|
+
primary: limits.primary ? {
|
|
67
|
+
usedPercent: readNumber(limits.primary.usedPercent, limits.primary.used_percent),
|
|
68
|
+
windowMinutes: readNumberOrNull(
|
|
69
|
+
limits.primary.windowDurationMins,
|
|
70
|
+
limits.primary.window_minutes
|
|
71
|
+
),
|
|
72
|
+
resetsAt: readNumberOrNull(limits.primary.resetsAt, limits.primary.resets_at),
|
|
73
|
+
} : null,
|
|
74
|
+
secondary: limits.secondary ? {
|
|
75
|
+
usedPercent: readNumber(limits.secondary.usedPercent, limits.secondary.used_percent),
|
|
76
|
+
windowMinutes: readNumberOrNull(
|
|
77
|
+
limits.secondary.windowDurationMins,
|
|
78
|
+
limits.secondary.window_minutes
|
|
79
|
+
),
|
|
80
|
+
resetsAt: readNumberOrNull(limits.secondary.resetsAt, limits.secondary.resets_at),
|
|
81
|
+
} : null,
|
|
82
|
+
credits: limits.credits ? {
|
|
83
|
+
hasCredits: limits.credits.hasCredits ?? limits.credits.has_credits ?? false,
|
|
84
|
+
unlimited: limits.credits.unlimited ?? false,
|
|
85
|
+
balance: limits.credits.balance ?? null,
|
|
86
|
+
} : null,
|
|
87
|
+
planType: limits.planType ?? limits.plan_type ?? null,
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const accountStatusFromRead = (result: AccountReadResult): AccountStatus => {
|
|
92
|
+
if (!result.account) {
|
|
93
|
+
return result.requiresOpenaiAuth ? 'offline' : 'online'
|
|
94
|
+
}
|
|
95
|
+
return 'online'
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const fetchAllModels = async (profileId: string): Promise<ModelInfo[]> => {
|
|
99
|
+
const models: ModelInfo[] = []
|
|
100
|
+
let cursor: string | null = null
|
|
101
|
+
for (let page = 0; page < 10; page += 1) {
|
|
102
|
+
let result: ModelListResult | null = null
|
|
103
|
+
try {
|
|
104
|
+
result = (await hubClient.request(profileId, 'model/list', {
|
|
105
|
+
limit: 100,
|
|
106
|
+
cursor,
|
|
107
|
+
})) as ModelListResult
|
|
108
|
+
} catch {
|
|
109
|
+
return models
|
|
110
|
+
}
|
|
111
|
+
if (!result?.data?.length) {
|
|
112
|
+
break
|
|
113
|
+
}
|
|
114
|
+
models.push(...result.data)
|
|
115
|
+
if (!result.nextCursor || result.nextCursor === cursor) {
|
|
116
|
+
break
|
|
117
|
+
}
|
|
118
|
+
cursor = result.nextCursor
|
|
119
|
+
}
|
|
120
|
+
return models
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const refreshAccountSnapshot = async (
|
|
124
|
+
profileId: string,
|
|
125
|
+
updateAccount: (id: string, updater: (account: Account) => Account) => void,
|
|
126
|
+
setModelsForAccount: (id: string, models: ModelInfo[]) => void
|
|
127
|
+
): Promise<void> => {
|
|
128
|
+
let accountResult: AccountReadResult | null = null
|
|
129
|
+
try {
|
|
130
|
+
accountResult = (await hubClient.request(profileId, 'account/read', {
|
|
131
|
+
refreshToken: false,
|
|
132
|
+
})) as AccountReadResult
|
|
133
|
+
} catch {
|
|
134
|
+
accountResult = null
|
|
135
|
+
}
|
|
136
|
+
if (accountResult) {
|
|
137
|
+
updateAccount(profileId, (prev) => ({
|
|
138
|
+
...prev,
|
|
139
|
+
status: accountStatusFromRead(accountResult),
|
|
140
|
+
email: accountResult.account?.email ?? prev.email,
|
|
141
|
+
plan: accountResult.account?.planType ?? prev.plan,
|
|
142
|
+
}))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
const limits = (await hubClient.request(profileId, 'account/rateLimits/read')) as RateLimitResult
|
|
147
|
+
if (limits) {
|
|
148
|
+
const usage = parseUsage(limits)
|
|
149
|
+
const rate = usage?.primary?.usedPercent
|
|
150
|
+
updateAccount(profileId, (prev) => ({
|
|
151
|
+
...prev,
|
|
152
|
+
rateLimit: typeof rate === 'number' ? Math.round(rate) : prev.rateLimit,
|
|
153
|
+
usage: usage ?? prev.usage,
|
|
154
|
+
}))
|
|
155
|
+
}
|
|
156
|
+
} catch {
|
|
157
|
+
// Ignore rate limit errors for unauthenticated accounts.
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
const models = await fetchAllModels(profileId)
|
|
162
|
+
if (models.length) {
|
|
163
|
+
setModelsForAccount(profileId, models)
|
|
164
|
+
}
|
|
165
|
+
} catch {
|
|
166
|
+
// Ignore model errors for unauthenticated accounts.
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ApprovalPolicy } from '../types'
|
|
2
|
+
|
|
3
|
+
const APPROVAL_POLICY_ALIASES: Record<string, ApprovalPolicy> = {
|
|
4
|
+
untrusted: 'untrusted',
|
|
5
|
+
unlessTrusted: 'untrusted',
|
|
6
|
+
'unless-trusted': 'untrusted',
|
|
7
|
+
'unless_trusted': 'untrusted',
|
|
8
|
+
'on-request': 'on-request',
|
|
9
|
+
onRequest: 'on-request',
|
|
10
|
+
on_request: 'on-request',
|
|
11
|
+
'on-failure': 'on-failure',
|
|
12
|
+
onFailure: 'on-failure',
|
|
13
|
+
on_failure: 'on-failure',
|
|
14
|
+
never: 'never',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const normalizeApprovalPolicy = (value?: string | null): ApprovalPolicy | null => {
|
|
18
|
+
if (!value) {
|
|
19
|
+
return null
|
|
20
|
+
}
|
|
21
|
+
const normalized = APPROVAL_POLICY_ALIASES[value]
|
|
22
|
+
if (normalized) {
|
|
23
|
+
return normalized
|
|
24
|
+
}
|
|
25
|
+
const lower = value.toLowerCase()
|
|
26
|
+
return APPROVAL_POLICY_ALIASES[lower] ?? null
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const approvalPolicyLabel = (value: ApprovalPolicy): string => {
|
|
30
|
+
switch (value) {
|
|
31
|
+
case 'untrusted':
|
|
32
|
+
return 'Untrusted'
|
|
33
|
+
case 'on-failure':
|
|
34
|
+
return 'On failure'
|
|
35
|
+
case 'on-request':
|
|
36
|
+
return 'On request'
|
|
37
|
+
case 'never':
|
|
38
|
+
return 'Never'
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const approvalPolicyDescription = (value: ApprovalPolicy): string => {
|
|
43
|
+
switch (value) {
|
|
44
|
+
case 'untrusted':
|
|
45
|
+
return 'Always ask before running commands or edits.'
|
|
46
|
+
case 'on-failure':
|
|
47
|
+
return 'Run in sandbox; ask if it fails.'
|
|
48
|
+
case 'on-request':
|
|
49
|
+
return 'Ask before risky commands; auto-run safe reads.'
|
|
50
|
+
case 'never':
|
|
51
|
+
return 'Run without approvals.'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export const INIT_PROMPT = `Generate a file named AGENTS.md that serves as a contributor guide for this repository.
|
|
2
|
+
Your goal is to produce a clear, concise, and well-structured document with descriptive headings and actionable explanations for each section.
|
|
3
|
+
Follow the outline below, but adapt as needed -- add sections if relevant, and omit those that do not apply to this project.
|
|
4
|
+
|
|
5
|
+
Document Requirements
|
|
6
|
+
|
|
7
|
+
- Title the document "Repository Guidelines".
|
|
8
|
+
- Use Markdown headings (#, ##, etc.) for structure.
|
|
9
|
+
- Keep the document concise. 200-400 words is optimal.
|
|
10
|
+
- Keep explanations short, direct, and specific to this repository.
|
|
11
|
+
- Provide examples where helpful (commands, directory paths, naming patterns).
|
|
12
|
+
- Maintain a professional, instructional tone.
|
|
13
|
+
|
|
14
|
+
Recommended Sections
|
|
15
|
+
|
|
16
|
+
Project Structure & Module Organization
|
|
17
|
+
|
|
18
|
+
- Outline the project structure, including where the source code, tests, and assets are located.
|
|
19
|
+
|
|
20
|
+
Build, Test, and Development Commands
|
|
21
|
+
|
|
22
|
+
- List key commands for building, testing, and running locally (e.g., npm test, make build).
|
|
23
|
+
- Briefly explain what each command does.
|
|
24
|
+
|
|
25
|
+
Coding Style & Naming Conventions
|
|
26
|
+
|
|
27
|
+
- Specify indentation rules, language-specific style preferences, and naming patterns.
|
|
28
|
+
- Include any formatting or linting tools used.
|
|
29
|
+
|
|
30
|
+
Testing Guidelines
|
|
31
|
+
|
|
32
|
+
- Identify testing frameworks and coverage requirements.
|
|
33
|
+
- State test naming conventions and how to run tests.
|
|
34
|
+
|
|
35
|
+
Commit & Pull Request Guidelines
|
|
36
|
+
|
|
37
|
+
- Summarize commit message conventions found in the project's Git history.
|
|
38
|
+
- Outline pull request requirements (descriptions, linked issues, screenshots, etc.).
|
|
39
|
+
|
|
40
|
+
(Optional) Add other sections if relevant, such as Security & Configuration Tips, Architecture Overview, or Agent-Specific Instructions.
|
|
41
|
+
`
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import type { Message, MessageKind } from '../types'
|
|
2
|
+
|
|
3
|
+
type ThreadItem = {
|
|
4
|
+
type: string
|
|
5
|
+
id: string
|
|
6
|
+
[key: string]: unknown
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type CommandAction =
|
|
10
|
+
| { type: 'read'; command: string; name: string; path: string }
|
|
11
|
+
| { type: 'listFiles'; command: string; path?: string | null }
|
|
12
|
+
| { type: 'search'; command: string; query?: string | null; path?: string | null }
|
|
13
|
+
| { type: 'unknown'; command: string }
|
|
14
|
+
|
|
15
|
+
const clampText = (value: string, max = 1400) => {
|
|
16
|
+
if (value.length <= max) {
|
|
17
|
+
return value
|
|
18
|
+
}
|
|
19
|
+
return `${value.slice(0, max)}\n…`
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const safeStringify = (value: unknown) => {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.stringify(value, null, 2)
|
|
25
|
+
} catch {
|
|
26
|
+
return String(value)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const formatFileChanges = (changes: Array<{ path?: unknown; kind?: unknown; diff?: string; movePath?: unknown }>) => {
|
|
31
|
+
const summary = changes
|
|
32
|
+
.map((change) => {
|
|
33
|
+
const path =
|
|
34
|
+
typeof change.path === 'string'
|
|
35
|
+
? change.path
|
|
36
|
+
: change.path
|
|
37
|
+
? safeStringify(change.path)
|
|
38
|
+
: 'unknown'
|
|
39
|
+
const kind = typeof change.kind === 'string' ? change.kind : 'update'
|
|
40
|
+
const movePath =
|
|
41
|
+
typeof change.movePath === 'string'
|
|
42
|
+
? ` -> ${change.movePath}`
|
|
43
|
+
: change.movePath
|
|
44
|
+
? ` -> ${safeStringify(change.movePath)}`
|
|
45
|
+
: ''
|
|
46
|
+
return `${kind}: ${path}${movePath}`
|
|
47
|
+
})
|
|
48
|
+
.join('\n')
|
|
49
|
+
|
|
50
|
+
const diffPreview = changes
|
|
51
|
+
.map((change) => change.diff ?? '')
|
|
52
|
+
.filter(Boolean)
|
|
53
|
+
.join('\n\n')
|
|
54
|
+
|
|
55
|
+
const content = [summary, diffPreview].filter(Boolean).join('\n\n')
|
|
56
|
+
return clampText(content)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const formatCommandActions = (actions: CommandAction[], commandFallback: string) => {
|
|
60
|
+
if (!actions.length) {
|
|
61
|
+
return {
|
|
62
|
+
kind: 'command' as MessageKind,
|
|
63
|
+
title: 'Command',
|
|
64
|
+
content: commandFallback,
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const primary = actions.find((action) => action.type !== 'unknown') ?? actions[0]
|
|
69
|
+
switch (primary.type) {
|
|
70
|
+
case 'read': {
|
|
71
|
+
const detail = primary.path ? `${primary.name} · ${primary.path}` : primary.name
|
|
72
|
+
return {
|
|
73
|
+
kind: 'tool' as MessageKind,
|
|
74
|
+
title: 'Read',
|
|
75
|
+
content: detail || commandFallback,
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
case 'search': {
|
|
79
|
+
const detail = [primary.query, primary.path].filter(Boolean).join(' · ')
|
|
80
|
+
return {
|
|
81
|
+
kind: 'tool' as MessageKind,
|
|
82
|
+
title: 'Search',
|
|
83
|
+
content: detail || commandFallback,
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
case 'listFiles': {
|
|
87
|
+
return {
|
|
88
|
+
kind: 'tool' as MessageKind,
|
|
89
|
+
title: 'List',
|
|
90
|
+
content: primary.path || commandFallback,
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
default:
|
|
94
|
+
return {
|
|
95
|
+
kind: 'command' as MessageKind,
|
|
96
|
+
title: 'Command',
|
|
97
|
+
content: commandFallback,
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export const formatThreadItem = (item: ThreadItem): { kind: MessageKind; content: string; title?: string } | null => {
|
|
103
|
+
switch (item.type) {
|
|
104
|
+
case 'reasoning': {
|
|
105
|
+
const summary = Array.isArray(item.summary) ? item.summary.join('\n') : ''
|
|
106
|
+
const content = summary
|
|
107
|
+
return { kind: 'reasoning', content: clampText(content), title: 'Reasoning' }
|
|
108
|
+
}
|
|
109
|
+
case 'commandExecution': {
|
|
110
|
+
const command = typeof item.command === 'string' ? item.command : 'Command'
|
|
111
|
+
const output = typeof item.aggregatedOutput === 'string' ? item.aggregatedOutput : ''
|
|
112
|
+
const status = typeof item.status === 'string' ? item.status : 'inProgress'
|
|
113
|
+
const actions = Array.isArray(item.commandActions) ? (item.commandActions as CommandAction[]) : []
|
|
114
|
+
const actionSummary = formatCommandActions(actions, command)
|
|
115
|
+
const content = output ? `${actionSummary.content}\n\n${output}` : actionSummary.content
|
|
116
|
+
return { kind: actionSummary.kind, content: clampText(content), title: `${actionSummary.title} · ${status}` }
|
|
117
|
+
}
|
|
118
|
+
case 'fileChange': {
|
|
119
|
+
const changes = Array.isArray(item.changes) ? item.changes : []
|
|
120
|
+
const content = formatFileChanges(changes as Array<{ path?: string; kind?: string; diff?: string; movePath?: string }>)
|
|
121
|
+
const status = typeof item.status === 'string' ? item.status : 'inProgress'
|
|
122
|
+
return { kind: 'file', content, title: `Files · ${status}` }
|
|
123
|
+
}
|
|
124
|
+
case 'mcpToolCall': {
|
|
125
|
+
const server = typeof item.server === 'string' ? item.server : 'mcp'
|
|
126
|
+
const tool = typeof item.tool === 'string' ? item.tool : 'tool'
|
|
127
|
+
const args = item.arguments ? safeStringify(item.arguments) : ''
|
|
128
|
+
const result = item.result ? safeStringify(item.result) : ''
|
|
129
|
+
const error = item.error ? safeStringify(item.error) : ''
|
|
130
|
+
const content = [args, result, error].filter(Boolean).join('\n\n')
|
|
131
|
+
return { kind: 'tool', content: clampText(content || `${server}.${tool}`), title: `${server}.${tool}` }
|
|
132
|
+
}
|
|
133
|
+
case 'webSearch': {
|
|
134
|
+
const query = typeof item.query === 'string' ? item.query : 'Search'
|
|
135
|
+
return { kind: 'tool', content: clampText(query), title: 'Web Search' }
|
|
136
|
+
}
|
|
137
|
+
case 'imageView': {
|
|
138
|
+
const path = typeof item.path === 'string' ? item.path : 'Image'
|
|
139
|
+
return { kind: 'tool', content: clampText(path), title: 'Image View' }
|
|
140
|
+
}
|
|
141
|
+
case 'enteredReviewMode': {
|
|
142
|
+
const review = typeof item.review === 'string' ? item.review : 'Review'
|
|
143
|
+
return { kind: 'tool', content: clampText(review), title: 'Review Started' }
|
|
144
|
+
}
|
|
145
|
+
case 'exitedReviewMode': {
|
|
146
|
+
const review = typeof item.review === 'string' ? item.review : 'Review'
|
|
147
|
+
return { kind: 'tool', content: clampText(review, 2400), title: 'Review' }
|
|
148
|
+
}
|
|
149
|
+
case 'compacted': {
|
|
150
|
+
return { kind: 'tool', content: 'Conversation compacted to save context.', title: 'Compaction' }
|
|
151
|
+
}
|
|
152
|
+
default:
|
|
153
|
+
return null
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export const buildSystemMessage = (item: ThreadItem): Message | null => {
|
|
158
|
+
const formatted = formatThreadItem(item)
|
|
159
|
+
if (!formatted) {
|
|
160
|
+
return null
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
id: item.id,
|
|
164
|
+
role: 'assistant',
|
|
165
|
+
kind: formatted.kind,
|
|
166
|
+
title: formatted.title,
|
|
167
|
+
content: formatted.content,
|
|
168
|
+
timestamp: '',
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
type ParsedArgs = {
|
|
2
|
+
positional: string[]
|
|
3
|
+
named: Record<string, string>
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const tokenizeArgs = (input: string): string[] => {
|
|
7
|
+
if (!input.trim()) {
|
|
8
|
+
return []
|
|
9
|
+
}
|
|
10
|
+
const tokens: string[] = []
|
|
11
|
+
const regex = /"([^"]*)"|'([^']*)'|([^\s]+)/g
|
|
12
|
+
let match: RegExpExecArray | null
|
|
13
|
+
while ((match = regex.exec(input)) !== null) {
|
|
14
|
+
tokens.push(match[1] ?? match[2] ?? match[3] ?? '')
|
|
15
|
+
}
|
|
16
|
+
return tokens
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const parseArgs = (input: string): ParsedArgs => {
|
|
20
|
+
const tokens = tokenizeArgs(input)
|
|
21
|
+
const positional: string[] = []
|
|
22
|
+
const named: Record<string, string> = {}
|
|
23
|
+
|
|
24
|
+
tokens.forEach((token) => {
|
|
25
|
+
const eqIndex = token.indexOf('=')
|
|
26
|
+
if (eqIndex > 0) {
|
|
27
|
+
const key = token.slice(0, eqIndex)
|
|
28
|
+
const value = token.slice(eqIndex + 1)
|
|
29
|
+
named[key] = value
|
|
30
|
+
} else {
|
|
31
|
+
positional.push(token)
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
return { positional, named }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const stripPromptFrontmatter = (input: string): string => {
|
|
39
|
+
const trimmed = input.trimStart()
|
|
40
|
+
if (!trimmed.startsWith('---')) {
|
|
41
|
+
return input
|
|
42
|
+
}
|
|
43
|
+
const end = trimmed.indexOf('\n---', 3)
|
|
44
|
+
if (end === -1) {
|
|
45
|
+
return input
|
|
46
|
+
}
|
|
47
|
+
const after = trimmed.slice(end + 4)
|
|
48
|
+
return after.startsWith('\n') ? after.slice(1) : after
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const expandPromptTemplate = (template: string, args: string): string => {
|
|
52
|
+
const { positional, named } = parseArgs(args)
|
|
53
|
+
const placeholder = '__CODEX_DOLLAR__'
|
|
54
|
+
let output = template.replace(/\$\$/g, placeholder)
|
|
55
|
+
|
|
56
|
+
output = output.replace(/\$ARGUMENTS/g, positional.join(' '))
|
|
57
|
+
output = output.replace(/\$(\d)/g, (_, digit) => positional[Number(digit) - 1] ?? '')
|
|
58
|
+
output = output.replace(/\$([A-Z][A-Z0-9_]*)/g, (_, key) => named[key] ?? '')
|
|
59
|
+
|
|
60
|
+
output = output.replace(new RegExp(placeholder, 'g'), '$')
|
|
61
|
+
return output
|
|
62
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ReasoningSummary } from '../types'
|
|
2
|
+
|
|
3
|
+
const SUMMARY_ALIASES: Record<string, ReasoningSummary> = {
|
|
4
|
+
auto: 'auto',
|
|
5
|
+
concise: 'concise',
|
|
6
|
+
detailed: 'detailed',
|
|
7
|
+
none: 'none',
|
|
8
|
+
off: 'none',
|
|
9
|
+
disable: 'none',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const normalizeReasoningSummary = (value?: string | null): ReasoningSummary | null => {
|
|
13
|
+
if (!value) {
|
|
14
|
+
return null
|
|
15
|
+
}
|
|
16
|
+
const normalized = SUMMARY_ALIASES[value]
|
|
17
|
+
if (normalized) {
|
|
18
|
+
return normalized
|
|
19
|
+
}
|
|
20
|
+
const lower = value.toLowerCase()
|
|
21
|
+
return SUMMARY_ALIASES[lower] ?? null
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const reasoningSummaryLabel = (value: ReasoningSummary): string => {
|
|
25
|
+
switch (value) {
|
|
26
|
+
case 'auto':
|
|
27
|
+
return 'Auto'
|
|
28
|
+
case 'concise':
|
|
29
|
+
return 'Concise'
|
|
30
|
+
case 'detailed':
|
|
31
|
+
return 'Detailed'
|
|
32
|
+
case 'none':
|
|
33
|
+
return 'None'
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const reasoningSummaryDescription = (value: ReasoningSummary): string => {
|
|
38
|
+
switch (value) {
|
|
39
|
+
case 'auto':
|
|
40
|
+
return 'Let the model choose the best summary length.'
|
|
41
|
+
case 'concise':
|
|
42
|
+
return 'Short, readable reasoning summaries.'
|
|
43
|
+
case 'detailed':
|
|
44
|
+
return 'Longer reasoning summaries with extra detail.'
|
|
45
|
+
case 'none':
|
|
46
|
+
return 'Disable reasoning summaries.'
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export type SlashCommandId =
|
|
2
|
+
| 'model'
|
|
3
|
+
| 'summary'
|
|
4
|
+
| 'cwd'
|
|
5
|
+
| 'approvals'
|
|
6
|
+
| 'skills'
|
|
7
|
+
| 'review'
|
|
8
|
+
| 'new'
|
|
9
|
+
| 'resume'
|
|
10
|
+
| 'init'
|
|
11
|
+
| 'compact'
|
|
12
|
+
| 'diff'
|
|
13
|
+
| 'mention'
|
|
14
|
+
| 'status'
|
|
15
|
+
| 'mcp'
|
|
16
|
+
| 'experimental'
|
|
17
|
+
| 'logout'
|
|
18
|
+
| 'quit'
|
|
19
|
+
| 'exit'
|
|
20
|
+
| 'feedback'
|
|
21
|
+
| `prompts:${string}`
|
|
22
|
+
|
|
23
|
+
export type SlashCommandDefinition = {
|
|
24
|
+
id: SlashCommandId
|
|
25
|
+
description: string
|
|
26
|
+
availableDuringTask: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const SLASH_COMMANDS: SlashCommandDefinition[] = [
|
|
30
|
+
{ id: 'model', description: 'choose what model and reasoning effort to use', availableDuringTask: false },
|
|
31
|
+
{ id: 'summary', description: 'set reasoning summary length', availableDuringTask: false },
|
|
32
|
+
{ id: 'cwd', description: 'set working directory for the thread', availableDuringTask: false },
|
|
33
|
+
{ id: 'approvals', description: 'choose what Codex can do without approval', availableDuringTask: false },
|
|
34
|
+
{ id: 'skills', description: 'browse and insert skills', availableDuringTask: true },
|
|
35
|
+
{ id: 'review', description: 'review my current changes and find issues', availableDuringTask: false },
|
|
36
|
+
{ id: 'new', description: 'start a new chat during a conversation', availableDuringTask: false },
|
|
37
|
+
{ id: 'resume', description: 'resume a saved chat', availableDuringTask: false },
|
|
38
|
+
{ id: 'init', description: 'create an AGENTS.md file with instructions for Codex', availableDuringTask: false },
|
|
39
|
+
{ id: 'compact', description: 'summarize conversation to prevent hitting the context limit', availableDuringTask: false },
|
|
40
|
+
{ id: 'diff', description: 'show git diff (including untracked files)', availableDuringTask: true },
|
|
41
|
+
{ id: 'mention', description: 'mention a file', availableDuringTask: true },
|
|
42
|
+
{ id: 'status', description: 'show current session configuration and token usage', availableDuringTask: true },
|
|
43
|
+
{ id: 'mcp', description: 'list configured MCP tools', availableDuringTask: true },
|
|
44
|
+
{ id: 'experimental', description: 'open experimental menu', availableDuringTask: true },
|
|
45
|
+
{ id: 'logout', description: 'log out of Codex', availableDuringTask: false },
|
|
46
|
+
{ id: 'quit', description: 'exit Codex', availableDuringTask: true },
|
|
47
|
+
{ id: 'exit', description: 'exit Codex', availableDuringTask: true },
|
|
48
|
+
{ id: 'feedback', description: 'send logs to maintainers', availableDuringTask: true },
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
export const filterSlashCommands = (query: string, extra: SlashCommandDefinition[] = []) => {
|
|
52
|
+
const allCommands = [...SLASH_COMMANDS, ...extra]
|
|
53
|
+
if (!query) {
|
|
54
|
+
return allCommands
|
|
55
|
+
}
|
|
56
|
+
const lowered = query.toLowerCase()
|
|
57
|
+
return allCommands.filter((command) => command.id.startsWith(lowered))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const findSlashCommand = (name: string, extra: SlashCommandDefinition[] = []) =>
|
|
61
|
+
[...SLASH_COMMANDS, ...extra].find((command) => command.id === name)
|
|
62
|
+
|
|
63
|
+
export const getSlashQuery = (text: string): string | null => {
|
|
64
|
+
const firstLine = text.split('\n')[0] ?? ''
|
|
65
|
+
if (!firstLine.startsWith('/')) {
|
|
66
|
+
return null
|
|
67
|
+
}
|
|
68
|
+
if (firstLine.startsWith('/ ') || firstLine.startsWith('/\t')) {
|
|
69
|
+
return null
|
|
70
|
+
}
|
|
71
|
+
const raw = firstLine.slice(1)
|
|
72
|
+
const token = raw.split(/\s/)[0]
|
|
73
|
+
return token
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const parseSlashInput = (text: string): { name: string; rest: string } | null => {
|
|
77
|
+
const firstLine = text.split('\n')[0] ?? ''
|
|
78
|
+
if (!firstLine.startsWith('/')) {
|
|
79
|
+
return null
|
|
80
|
+
}
|
|
81
|
+
if (firstLine.startsWith('/ ') || firstLine.startsWith('/\t')) {
|
|
82
|
+
return null
|
|
83
|
+
}
|
|
84
|
+
const raw = firstLine.slice(1)
|
|
85
|
+
if (!raw) {
|
|
86
|
+
return { name: '', rest: '' }
|
|
87
|
+
}
|
|
88
|
+
const match = raw.match(/^([^\s]+)\s*(.*)$/)
|
|
89
|
+
if (!match) {
|
|
90
|
+
return null
|
|
91
|
+
}
|
|
92
|
+
const name = match[1]
|
|
93
|
+
const rest = match[2] ?? ''
|
|
94
|
+
if (!name || name.includes('/')) {
|
|
95
|
+
return null
|
|
96
|
+
}
|
|
97
|
+
return { name, rest: rest.trim() }
|
|
98
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"useDefineForClassFields": true,
|
|
6
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"types": ["vite/client"],
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
|
|
11
|
+
/* Bundler mode */
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"verbatimModuleSyntax": true,
|
|
15
|
+
"moduleDetection": "force",
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"jsx": "react-jsx",
|
|
18
|
+
|
|
19
|
+
/* Linting */
|
|
20
|
+
"strict": true,
|
|
21
|
+
"noUnusedLocals": true,
|
|
22
|
+
"noUnusedParameters": true,
|
|
23
|
+
"erasableSyntaxOnly": true,
|
|
24
|
+
"noFallthroughCasesInSwitch": true,
|
|
25
|
+
"noUncheckedSideEffectImports": true
|
|
26
|
+
},
|
|
27
|
+
"include": ["src"]
|
|
28
|
+
}
|