mcp-codex-worker 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 (462) hide show
  1. package/README.md +135 -0
  2. package/bin/mcp-codex-worker.mjs +17 -0
  3. package/dist/src/app.d.ts +29 -0
  4. package/dist/src/app.js +353 -0
  5. package/dist/src/app.js.map +1 -0
  6. package/dist/src/config/defaults.d.ts +11 -0
  7. package/dist/src/config/defaults.js +12 -0
  8. package/dist/src/config/defaults.js.map +1 -0
  9. package/dist/src/index.d.ts +2 -0
  10. package/dist/src/index.js +64 -0
  11. package/dist/src/index.js.map +1 -0
  12. package/dist/src/mcp/tool-definitions.d.ts +180 -0
  13. package/dist/src/mcp/tool-definitions.js +241 -0
  14. package/dist/src/mcp/tool-definitions.js.map +1 -0
  15. package/dist/src/services/app-server-client.d.ts +65 -0
  16. package/dist/src/services/app-server-client.js +511 -0
  17. package/dist/src/services/app-server-client.js.map +1 -0
  18. package/dist/src/services/codex-runtime.d.ts +84 -0
  19. package/dist/src/services/codex-runtime.js +371 -0
  20. package/dist/src/services/codex-runtime.js.map +1 -0
  21. package/dist/src/services/fleet-mode.d.ts +3 -0
  22. package/dist/src/services/fleet-mode.js +21 -0
  23. package/dist/src/services/fleet-mode.js.map +1 -0
  24. package/dist/src/services/model-catalog.d.ts +22 -0
  25. package/dist/src/services/model-catalog.js +51 -0
  26. package/dist/src/services/model-catalog.js.map +1 -0
  27. package/dist/src/services/profile-manager.d.ts +29 -0
  28. package/dist/src/services/profile-manager.js +82 -0
  29. package/dist/src/services/profile-manager.js.map +1 -0
  30. package/dist/src/types/codex.d.ts +50 -0
  31. package/dist/src/types/codex.js +2 -0
  32. package/dist/src/types/codex.js.map +1 -0
  33. package/package.json +53 -0
  34. package/src/app.ts +417 -0
  35. package/src/config/defaults.ts +14 -0
  36. package/src/index.ts +84 -0
  37. package/src/mcp/tool-definitions.ts +280 -0
  38. package/src/protocol/AbsolutePathBuf.ts +14 -0
  39. package/src/protocol/AgentPath.ts +5 -0
  40. package/src/protocol/ApplyPatchApprovalParams.ts +21 -0
  41. package/src/protocol/ApplyPatchApprovalResponse.ts +6 -0
  42. package/src/protocol/AuthMode.ts +8 -0
  43. package/src/protocol/ClientInfo.ts +5 -0
  44. package/src/protocol/ClientNotification.ts +5 -0
  45. package/src/protocol/ClientRequest.ts +67 -0
  46. package/src/protocol/CollaborationMode.ts +10 -0
  47. package/src/protocol/ContentItem.ts +5 -0
  48. package/src/protocol/ConversationGitInfo.ts +5 -0
  49. package/src/protocol/ConversationSummary.ts +8 -0
  50. package/src/protocol/ExecCommandApprovalParams.ts +16 -0
  51. package/src/protocol/ExecCommandApprovalResponse.ts +6 -0
  52. package/src/protocol/ExecPolicyAmendment.ts +12 -0
  53. package/src/protocol/FileChange.ts +5 -0
  54. package/src/protocol/ForcedLoginMethod.ts +5 -0
  55. package/src/protocol/FunctionCallOutputBody.ts +6 -0
  56. package/src/protocol/FunctionCallOutputContentItem.ts +10 -0
  57. package/src/protocol/FuzzyFileSearchMatchType.ts +5 -0
  58. package/src/protocol/FuzzyFileSearchParams.ts +5 -0
  59. package/src/protocol/FuzzyFileSearchResponse.ts +6 -0
  60. package/src/protocol/FuzzyFileSearchResult.ts +9 -0
  61. package/src/protocol/FuzzyFileSearchSessionCompletedNotification.ts +5 -0
  62. package/src/protocol/FuzzyFileSearchSessionUpdatedNotification.ts +6 -0
  63. package/src/protocol/GetAuthStatusParams.ts +5 -0
  64. package/src/protocol/GetAuthStatusResponse.ts +6 -0
  65. package/src/protocol/GetConversationSummaryParams.ts +6 -0
  66. package/src/protocol/GetConversationSummaryResponse.ts +6 -0
  67. package/src/protocol/GhostCommit.ts +8 -0
  68. package/src/protocol/GitDiffToRemoteParams.ts +5 -0
  69. package/src/protocol/GitDiffToRemoteResponse.ts +6 -0
  70. package/src/protocol/GitSha.ts +5 -0
  71. package/src/protocol/ImageDetail.ts +5 -0
  72. package/src/protocol/InitializeCapabilities.ts +17 -0
  73. package/src/protocol/InitializeParams.ts +7 -0
  74. package/src/protocol/InitializeResponse.ts +20 -0
  75. package/src/protocol/InputModality.ts +8 -0
  76. package/src/protocol/LocalShellAction.ts +6 -0
  77. package/src/protocol/LocalShellExecAction.ts +5 -0
  78. package/src/protocol/LocalShellStatus.ts +5 -0
  79. package/src/protocol/MessagePhase.ts +11 -0
  80. package/src/protocol/ModeKind.ts +8 -0
  81. package/src/protocol/NetworkPolicyAmendment.ts +6 -0
  82. package/src/protocol/NetworkPolicyRuleAction.ts +5 -0
  83. package/src/protocol/ParsedCommand.ts +12 -0
  84. package/src/protocol/Personality.ts +5 -0
  85. package/src/protocol/PlanType.ts +5 -0
  86. package/src/protocol/RealtimeConversationVersion.ts +5 -0
  87. package/src/protocol/ReasoningEffort.ts +8 -0
  88. package/src/protocol/ReasoningItemContent.ts +5 -0
  89. package/src/protocol/ReasoningItemReasoningSummary.ts +5 -0
  90. package/src/protocol/ReasoningSummary.ts +10 -0
  91. package/src/protocol/RequestId.ts +5 -0
  92. package/src/protocol/Resource.ts +9 -0
  93. package/src/protocol/ResourceTemplate.ts +9 -0
  94. package/src/protocol/ResponseItem.ts +18 -0
  95. package/src/protocol/ReviewDecision.ts +10 -0
  96. package/src/protocol/ServerNotification.ts +60 -0
  97. package/src/protocol/ServerRequest.ts +18 -0
  98. package/src/protocol/ServiceTier.ts +5 -0
  99. package/src/protocol/SessionSource.ts +6 -0
  100. package/src/protocol/Settings.ts +9 -0
  101. package/src/protocol/SubAgentSource.ts +7 -0
  102. package/src/protocol/ThreadId.ts +5 -0
  103. package/src/protocol/Tool.ts +9 -0
  104. package/src/protocol/Verbosity.ts +9 -0
  105. package/src/protocol/WebSearchAction.ts +5 -0
  106. package/src/protocol/WebSearchContextSize.ts +5 -0
  107. package/src/protocol/WebSearchLocation.ts +5 -0
  108. package/src/protocol/WebSearchMode.ts +5 -0
  109. package/src/protocol/WebSearchToolConfig.ts +7 -0
  110. package/src/protocol/index.ts +75 -0
  111. package/src/protocol/serde_json/JsonValue.ts +5 -0
  112. package/src/protocol/v2/Account.ts +6 -0
  113. package/src/protocol/v2/AccountLoginCompletedNotification.ts +5 -0
  114. package/src/protocol/v2/AccountRateLimitsUpdatedNotification.ts +6 -0
  115. package/src/protocol/v2/AccountUpdatedNotification.ts +7 -0
  116. package/src/protocol/v2/AdditionalFileSystemPermissions.ts +6 -0
  117. package/src/protocol/v2/AdditionalNetworkPermissions.ts +5 -0
  118. package/src/protocol/v2/AdditionalPermissionProfile.ts +7 -0
  119. package/src/protocol/v2/AgentMessageDeltaNotification.ts +5 -0
  120. package/src/protocol/v2/AnalyticsConfig.ts +6 -0
  121. package/src/protocol/v2/AppBranding.ts +8 -0
  122. package/src/protocol/v2/AppInfo.ts +19 -0
  123. package/src/protocol/v2/AppListUpdatedNotification.ts +9 -0
  124. package/src/protocol/v2/AppMetadata.ts +7 -0
  125. package/src/protocol/v2/AppReview.ts +5 -0
  126. package/src/protocol/v2/AppScreenshot.ts +5 -0
  127. package/src/protocol/v2/AppSummary.ts +8 -0
  128. package/src/protocol/v2/AppToolApproval.ts +5 -0
  129. package/src/protocol/v2/AppToolsConfig.ts +6 -0
  130. package/src/protocol/v2/ApprovalsReviewer.ts +12 -0
  131. package/src/protocol/v2/AppsConfig.ts +8 -0
  132. package/src/protocol/v2/AppsDefaultConfig.ts +5 -0
  133. package/src/protocol/v2/AppsListParams.ts +24 -0
  134. package/src/protocol/v2/AppsListResponse.ts +14 -0
  135. package/src/protocol/v2/AskForApproval.ts +5 -0
  136. package/src/protocol/v2/ByteRange.ts +5 -0
  137. package/src/protocol/v2/CancelLoginAccountParams.ts +5 -0
  138. package/src/protocol/v2/CancelLoginAccountResponse.ts +6 -0
  139. package/src/protocol/v2/CancelLoginAccountStatus.ts +5 -0
  140. package/src/protocol/v2/ChatgptAuthTokensRefreshParams.ts +16 -0
  141. package/src/protocol/v2/ChatgptAuthTokensRefreshReason.ts +5 -0
  142. package/src/protocol/v2/ChatgptAuthTokensRefreshResponse.ts +5 -0
  143. package/src/protocol/v2/CodexErrorInfo.ts +12 -0
  144. package/src/protocol/v2/CollabAgentState.ts +6 -0
  145. package/src/protocol/v2/CollabAgentStatus.ts +5 -0
  146. package/src/protocol/v2/CollabAgentTool.ts +5 -0
  147. package/src/protocol/v2/CollabAgentToolCallStatus.ts +5 -0
  148. package/src/protocol/v2/CollaborationModeMask.ts +10 -0
  149. package/src/protocol/v2/CommandAction.ts +5 -0
  150. package/src/protocol/v2/CommandExecOutputDeltaNotification.ts +30 -0
  151. package/src/protocol/v2/CommandExecOutputStream.ts +8 -0
  152. package/src/protocol/v2/CommandExecParams.ts +97 -0
  153. package/src/protocol/v2/CommandExecResizeParams.ts +18 -0
  154. package/src/protocol/v2/CommandExecResizeResponse.ts +8 -0
  155. package/src/protocol/v2/CommandExecResponse.ts +24 -0
  156. package/src/protocol/v2/CommandExecTerminalSize.ts +16 -0
  157. package/src/protocol/v2/CommandExecTerminateParams.ts +13 -0
  158. package/src/protocol/v2/CommandExecTerminateResponse.ts +8 -0
  159. package/src/protocol/v2/CommandExecWriteParams.ts +22 -0
  160. package/src/protocol/v2/CommandExecWriteResponse.ts +8 -0
  161. package/src/protocol/v2/CommandExecutionApprovalDecision.ts +7 -0
  162. package/src/protocol/v2/CommandExecutionOutputDeltaNotification.ts +5 -0
  163. package/src/protocol/v2/CommandExecutionRequestApprovalParams.ts +57 -0
  164. package/src/protocol/v2/CommandExecutionRequestApprovalResponse.ts +6 -0
  165. package/src/protocol/v2/CommandExecutionSource.ts +5 -0
  166. package/src/protocol/v2/CommandExecutionStatus.ts +5 -0
  167. package/src/protocol/v2/Config.ts +23 -0
  168. package/src/protocol/v2/ConfigBatchWriteParams.ts +14 -0
  169. package/src/protocol/v2/ConfigEdit.ts +7 -0
  170. package/src/protocol/v2/ConfigLayer.ts +7 -0
  171. package/src/protocol/v2/ConfigLayerMetadata.ts +6 -0
  172. package/src/protocol/v2/ConfigLayerSource.ts +16 -0
  173. package/src/protocol/v2/ConfigReadParams.ts +11 -0
  174. package/src/protocol/v2/ConfigReadResponse.ts +8 -0
  175. package/src/protocol/v2/ConfigRequirements.ts +9 -0
  176. package/src/protocol/v2/ConfigRequirementsReadResponse.ts +10 -0
  177. package/src/protocol/v2/ConfigValueWriteParams.ts +11 -0
  178. package/src/protocol/v2/ConfigWarningNotification.ts +22 -0
  179. package/src/protocol/v2/ConfigWriteResponse.ts +12 -0
  180. package/src/protocol/v2/ContextCompactedNotification.ts +8 -0
  181. package/src/protocol/v2/CreditsSnapshot.ts +5 -0
  182. package/src/protocol/v2/DeprecationNoticeNotification.ts +13 -0
  183. package/src/protocol/v2/DynamicToolCallOutputContentItem.ts +5 -0
  184. package/src/protocol/v2/DynamicToolCallParams.ts +6 -0
  185. package/src/protocol/v2/DynamicToolCallResponse.ts +6 -0
  186. package/src/protocol/v2/DynamicToolCallStatus.ts +5 -0
  187. package/src/protocol/v2/DynamicToolSpec.ts +6 -0
  188. package/src/protocol/v2/ErrorNotification.ts +6 -0
  189. package/src/protocol/v2/ExecPolicyAmendment.ts +5 -0
  190. package/src/protocol/v2/ExperimentalFeature.ts +37 -0
  191. package/src/protocol/v2/ExperimentalFeatureEnablementSetParams.ts +12 -0
  192. package/src/protocol/v2/ExperimentalFeatureEnablementSetResponse.ts +9 -0
  193. package/src/protocol/v2/ExperimentalFeatureListParams.ts +13 -0
  194. package/src/protocol/v2/ExperimentalFeatureListResponse.ts +11 -0
  195. package/src/protocol/v2/ExperimentalFeatureStage.ts +5 -0
  196. package/src/protocol/v2/ExternalAgentConfigDetectParams.ts +13 -0
  197. package/src/protocol/v2/ExternalAgentConfigDetectResponse.ts +6 -0
  198. package/src/protocol/v2/ExternalAgentConfigImportParams.ts +6 -0
  199. package/src/protocol/v2/ExternalAgentConfigImportResponse.ts +5 -0
  200. package/src/protocol/v2/ExternalAgentConfigMigrationItem.ts +10 -0
  201. package/src/protocol/v2/ExternalAgentConfigMigrationItemType.ts +5 -0
  202. package/src/protocol/v2/FeedbackUploadParams.ts +5 -0
  203. package/src/protocol/v2/FeedbackUploadResponse.ts +5 -0
  204. package/src/protocol/v2/FileChangeApprovalDecision.ts +5 -0
  205. package/src/protocol/v2/FileChangeOutputDeltaNotification.ts +5 -0
  206. package/src/protocol/v2/FileChangeRequestApprovalParams.ts +14 -0
  207. package/src/protocol/v2/FileChangeRequestApprovalResponse.ts +6 -0
  208. package/src/protocol/v2/FileUpdateChange.ts +6 -0
  209. package/src/protocol/v2/FsChangedNotification.ts +17 -0
  210. package/src/protocol/v2/FsCopyParams.ts +21 -0
  211. package/src/protocol/v2/FsCopyResponse.ts +8 -0
  212. package/src/protocol/v2/FsCreateDirectoryParams.ts +17 -0
  213. package/src/protocol/v2/FsCreateDirectoryResponse.ts +8 -0
  214. package/src/protocol/v2/FsGetMetadataParams.ts +13 -0
  215. package/src/protocol/v2/FsGetMetadataResponse.ts +24 -0
  216. package/src/protocol/v2/FsReadDirectoryEntry.ts +20 -0
  217. package/src/protocol/v2/FsReadDirectoryParams.ts +13 -0
  218. package/src/protocol/v2/FsReadDirectoryResponse.ts +13 -0
  219. package/src/protocol/v2/FsReadFileParams.ts +13 -0
  220. package/src/protocol/v2/FsReadFileResponse.ts +12 -0
  221. package/src/protocol/v2/FsRemoveParams.ts +21 -0
  222. package/src/protocol/v2/FsRemoveResponse.ts +8 -0
  223. package/src/protocol/v2/FsUnwatchParams.ts +12 -0
  224. package/src/protocol/v2/FsUnwatchResponse.ts +8 -0
  225. package/src/protocol/v2/FsWatchParams.ts +13 -0
  226. package/src/protocol/v2/FsWatchResponse.ts +17 -0
  227. package/src/protocol/v2/FsWriteFileParams.ts +17 -0
  228. package/src/protocol/v2/FsWriteFileResponse.ts +8 -0
  229. package/src/protocol/v2/GetAccountParams.ts +13 -0
  230. package/src/protocol/v2/GetAccountRateLimitsResponse.ts +14 -0
  231. package/src/protocol/v2/GetAccountResponse.ts +6 -0
  232. package/src/protocol/v2/GitInfo.ts +5 -0
  233. package/src/protocol/v2/GrantedPermissionProfile.ts +7 -0
  234. package/src/protocol/v2/GuardianApprovalReview.ts +12 -0
  235. package/src/protocol/v2/GuardianApprovalReviewStatus.ts +8 -0
  236. package/src/protocol/v2/GuardianRiskLevel.ts +8 -0
  237. package/src/protocol/v2/HookCompletedNotification.ts +6 -0
  238. package/src/protocol/v2/HookEventName.ts +5 -0
  239. package/src/protocol/v2/HookExecutionMode.ts +5 -0
  240. package/src/protocol/v2/HookHandlerType.ts +5 -0
  241. package/src/protocol/v2/HookOutputEntry.ts +6 -0
  242. package/src/protocol/v2/HookOutputEntryKind.ts +5 -0
  243. package/src/protocol/v2/HookPromptFragment.ts +5 -0
  244. package/src/protocol/v2/HookRunStatus.ts +5 -0
  245. package/src/protocol/v2/HookRunSummary.ts +11 -0
  246. package/src/protocol/v2/HookScope.ts +5 -0
  247. package/src/protocol/v2/HookStartedNotification.ts +6 -0
  248. package/src/protocol/v2/ItemCompletedNotification.ts +6 -0
  249. package/src/protocol/v2/ItemGuardianApprovalReviewCompletedNotification.ts +15 -0
  250. package/src/protocol/v2/ItemGuardianApprovalReviewStartedNotification.ts +15 -0
  251. package/src/protocol/v2/ItemStartedNotification.ts +6 -0
  252. package/src/protocol/v2/ListMcpServerStatusParams.ts +13 -0
  253. package/src/protocol/v2/ListMcpServerStatusResponse.ts +11 -0
  254. package/src/protocol/v2/LoginAccountParams.ts +21 -0
  255. package/src/protocol/v2/LoginAccountResponse.ts +17 -0
  256. package/src/protocol/v2/LogoutAccountResponse.ts +5 -0
  257. package/src/protocol/v2/MarketplaceInterface.ts +5 -0
  258. package/src/protocol/v2/MarketplaceLoadErrorInfo.ts +6 -0
  259. package/src/protocol/v2/McpAuthStatus.ts +5 -0
  260. package/src/protocol/v2/McpElicitationArrayType.ts +5 -0
  261. package/src/protocol/v2/McpElicitationBooleanSchema.ts +6 -0
  262. package/src/protocol/v2/McpElicitationBooleanType.ts +5 -0
  263. package/src/protocol/v2/McpElicitationConstOption.ts +5 -0
  264. package/src/protocol/v2/McpElicitationEnumSchema.ts +8 -0
  265. package/src/protocol/v2/McpElicitationLegacyTitledEnumSchema.ts +6 -0
  266. package/src/protocol/v2/McpElicitationMultiSelectEnumSchema.ts +7 -0
  267. package/src/protocol/v2/McpElicitationNumberSchema.ts +6 -0
  268. package/src/protocol/v2/McpElicitationNumberType.ts +5 -0
  269. package/src/protocol/v2/McpElicitationObjectType.ts +5 -0
  270. package/src/protocol/v2/McpElicitationPrimitiveSchema.ts +9 -0
  271. package/src/protocol/v2/McpElicitationSchema.ts +13 -0
  272. package/src/protocol/v2/McpElicitationSingleSelectEnumSchema.ts +7 -0
  273. package/src/protocol/v2/McpElicitationStringFormat.ts +5 -0
  274. package/src/protocol/v2/McpElicitationStringSchema.ts +7 -0
  275. package/src/protocol/v2/McpElicitationStringType.ts +5 -0
  276. package/src/protocol/v2/McpElicitationTitledEnumItems.ts +6 -0
  277. package/src/protocol/v2/McpElicitationTitledMultiSelectEnumSchema.ts +7 -0
  278. package/src/protocol/v2/McpElicitationTitledSingleSelectEnumSchema.ts +7 -0
  279. package/src/protocol/v2/McpElicitationUntitledEnumItems.ts +6 -0
  280. package/src/protocol/v2/McpElicitationUntitledMultiSelectEnumSchema.ts +7 -0
  281. package/src/protocol/v2/McpElicitationUntitledSingleSelectEnumSchema.ts +6 -0
  282. package/src/protocol/v2/McpServerElicitationAction.ts +5 -0
  283. package/src/protocol/v2/McpServerElicitationRequestParams.ts +16 -0
  284. package/src/protocol/v2/McpServerElicitationRequestResponse.ts +17 -0
  285. package/src/protocol/v2/McpServerOauthLoginCompletedNotification.ts +5 -0
  286. package/src/protocol/v2/McpServerOauthLoginParams.ts +5 -0
  287. package/src/protocol/v2/McpServerOauthLoginResponse.ts +5 -0
  288. package/src/protocol/v2/McpServerRefreshResponse.ts +5 -0
  289. package/src/protocol/v2/McpServerStartupState.ts +5 -0
  290. package/src/protocol/v2/McpServerStatus.ts +9 -0
  291. package/src/protocol/v2/McpServerStatusUpdatedNotification.ts +6 -0
  292. package/src/protocol/v2/McpToolCallError.ts +5 -0
  293. package/src/protocol/v2/McpToolCallProgressNotification.ts +5 -0
  294. package/src/protocol/v2/McpToolCallResult.ts +6 -0
  295. package/src/protocol/v2/McpToolCallStatus.ts +5 -0
  296. package/src/protocol/v2/MemoryCitation.ts +6 -0
  297. package/src/protocol/v2/MemoryCitationEntry.ts +5 -0
  298. package/src/protocol/v2/MergeStrategy.ts +5 -0
  299. package/src/protocol/v2/Model.ts +10 -0
  300. package/src/protocol/v2/ModelAvailabilityNux.ts +5 -0
  301. package/src/protocol/v2/ModelListParams.ts +17 -0
  302. package/src/protocol/v2/ModelListResponse.ts +11 -0
  303. package/src/protocol/v2/ModelRerouteReason.ts +5 -0
  304. package/src/protocol/v2/ModelReroutedNotification.ts +6 -0
  305. package/src/protocol/v2/ModelUpgradeInfo.ts +5 -0
  306. package/src/protocol/v2/NetworkAccess.ts +5 -0
  307. package/src/protocol/v2/NetworkApprovalContext.ts +6 -0
  308. package/src/protocol/v2/NetworkApprovalProtocol.ts +5 -0
  309. package/src/protocol/v2/NetworkDomainPermission.ts +5 -0
  310. package/src/protocol/v2/NetworkPolicyAmendment.ts +6 -0
  311. package/src/protocol/v2/NetworkPolicyRuleAction.ts +5 -0
  312. package/src/protocol/v2/NetworkRequirements.ts +32 -0
  313. package/src/protocol/v2/NetworkUnixSocketPermission.ts +5 -0
  314. package/src/protocol/v2/NonSteerableTurnKind.ts +5 -0
  315. package/src/protocol/v2/OverriddenMetadata.ts +7 -0
  316. package/src/protocol/v2/PatchApplyStatus.ts +5 -0
  317. package/src/protocol/v2/PatchChangeKind.ts +5 -0
  318. package/src/protocol/v2/PermissionGrantScope.ts +5 -0
  319. package/src/protocol/v2/PermissionsRequestApprovalParams.ts +6 -0
  320. package/src/protocol/v2/PermissionsRequestApprovalResponse.ts +7 -0
  321. package/src/protocol/v2/PlanDeltaNotification.ts +9 -0
  322. package/src/protocol/v2/PluginAuthPolicy.ts +5 -0
  323. package/src/protocol/v2/PluginDetail.ts +9 -0
  324. package/src/protocol/v2/PluginInstallParams.ts +10 -0
  325. package/src/protocol/v2/PluginInstallPolicy.ts +5 -0
  326. package/src/protocol/v2/PluginInstallResponse.ts +7 -0
  327. package/src/protocol/v2/PluginInterface.ts +11 -0
  328. package/src/protocol/v2/PluginListParams.ts +16 -0
  329. package/src/protocol/v2/PluginListResponse.ts +7 -0
  330. package/src/protocol/v2/PluginMarketplaceEntry.ts +8 -0
  331. package/src/protocol/v2/PluginReadParams.ts +6 -0
  332. package/src/protocol/v2/PluginReadResponse.ts +6 -0
  333. package/src/protocol/v2/PluginSource.ts +6 -0
  334. package/src/protocol/v2/PluginSummary.ts +9 -0
  335. package/src/protocol/v2/PluginUninstallParams.ts +9 -0
  336. package/src/protocol/v2/PluginUninstallResponse.ts +5 -0
  337. package/src/protocol/v2/ProfileV2.ts +19 -0
  338. package/src/protocol/v2/RateLimitSnapshot.ts +8 -0
  339. package/src/protocol/v2/RateLimitWindow.ts +5 -0
  340. package/src/protocol/v2/RawResponseItemCompletedNotification.ts +6 -0
  341. package/src/protocol/v2/ReadOnlyAccess.ts +6 -0
  342. package/src/protocol/v2/ReasoningEffortOption.ts +6 -0
  343. package/src/protocol/v2/ReasoningSummaryPartAddedNotification.ts +5 -0
  344. package/src/protocol/v2/ReasoningSummaryTextDeltaNotification.ts +5 -0
  345. package/src/protocol/v2/ReasoningTextDeltaNotification.ts +5 -0
  346. package/src/protocol/v2/RequestPermissionProfile.ts +7 -0
  347. package/src/protocol/v2/ResidencyRequirement.ts +5 -0
  348. package/src/protocol/v2/ReviewDelivery.ts +5 -0
  349. package/src/protocol/v2/ReviewStartParams.ts +12 -0
  350. package/src/protocol/v2/ReviewStartResponse.ts +13 -0
  351. package/src/protocol/v2/ReviewTarget.ts +9 -0
  352. package/src/protocol/v2/SandboxMode.ts +5 -0
  353. package/src/protocol/v2/SandboxPolicy.ts +8 -0
  354. package/src/protocol/v2/SandboxWorkspaceWrite.ts +5 -0
  355. package/src/protocol/v2/ServerRequestResolvedNotification.ts +6 -0
  356. package/src/protocol/v2/SessionSource.ts +6 -0
  357. package/src/protocol/v2/SkillDependencies.ts +6 -0
  358. package/src/protocol/v2/SkillErrorInfo.ts +5 -0
  359. package/src/protocol/v2/SkillInterface.ts +5 -0
  360. package/src/protocol/v2/SkillMetadata.ts +12 -0
  361. package/src/protocol/v2/SkillScope.ts +5 -0
  362. package/src/protocol/v2/SkillSummary.ts +6 -0
  363. package/src/protocol/v2/SkillToolDependency.ts +5 -0
  364. package/src/protocol/v2/SkillsChangedNotification.ts +11 -0
  365. package/src/protocol/v2/SkillsConfigWriteParams.ts +14 -0
  366. package/src/protocol/v2/SkillsConfigWriteResponse.ts +5 -0
  367. package/src/protocol/v2/SkillsListEntry.ts +7 -0
  368. package/src/protocol/v2/SkillsListExtraRootsForCwd.ts +5 -0
  369. package/src/protocol/v2/SkillsListParams.ts +18 -0
  370. package/src/protocol/v2/SkillsListResponse.ts +6 -0
  371. package/src/protocol/v2/TerminalInteractionNotification.ts +5 -0
  372. package/src/protocol/v2/TextElement.ts +14 -0
  373. package/src/protocol/v2/TextPosition.ts +13 -0
  374. package/src/protocol/v2/TextRange.ts +6 -0
  375. package/src/protocol/v2/Thread.ts +72 -0
  376. package/src/protocol/v2/ThreadActiveFlag.ts +5 -0
  377. package/src/protocol/v2/ThreadArchiveParams.ts +5 -0
  378. package/src/protocol/v2/ThreadArchiveResponse.ts +5 -0
  379. package/src/protocol/v2/ThreadArchivedNotification.ts +5 -0
  380. package/src/protocol/v2/ThreadClosedNotification.ts +5 -0
  381. package/src/protocol/v2/ThreadCompactStartParams.ts +5 -0
  382. package/src/protocol/v2/ThreadCompactStartResponse.ts +5 -0
  383. package/src/protocol/v2/ThreadForkParams.ts +34 -0
  384. package/src/protocol/v2/ThreadForkResponse.ts +15 -0
  385. package/src/protocol/v2/ThreadItem.ts +100 -0
  386. package/src/protocol/v2/ThreadListParams.ts +43 -0
  387. package/src/protocol/v2/ThreadListResponse.ts +11 -0
  388. package/src/protocol/v2/ThreadLoadedListParams.ts +13 -0
  389. package/src/protocol/v2/ThreadLoadedListResponse.ts +14 -0
  390. package/src/protocol/v2/ThreadMetadataGitInfoUpdateParams.ts +20 -0
  391. package/src/protocol/v2/ThreadMetadataUpdateParams.ts +12 -0
  392. package/src/protocol/v2/ThreadMetadataUpdateResponse.ts +6 -0
  393. package/src/protocol/v2/ThreadNameUpdatedNotification.ts +5 -0
  394. package/src/protocol/v2/ThreadReadParams.ts +9 -0
  395. package/src/protocol/v2/ThreadReadResponse.ts +6 -0
  396. package/src/protocol/v2/ThreadRealtimeAudioChunk.ts +8 -0
  397. package/src/protocol/v2/ThreadRealtimeClosedNotification.ts +8 -0
  398. package/src/protocol/v2/ThreadRealtimeErrorNotification.ts +8 -0
  399. package/src/protocol/v2/ThreadRealtimeItemAddedNotification.ts +9 -0
  400. package/src/protocol/v2/ThreadRealtimeOutputAudioDeltaNotification.ts +9 -0
  401. package/src/protocol/v2/ThreadRealtimeStartedNotification.ts +9 -0
  402. package/src/protocol/v2/ThreadRealtimeTranscriptUpdatedNotification.ts +9 -0
  403. package/src/protocol/v2/ThreadResumeParams.ts +43 -0
  404. package/src/protocol/v2/ThreadResumeResponse.ts +15 -0
  405. package/src/protocol/v2/ThreadRollbackParams.ts +12 -0
  406. package/src/protocol/v2/ThreadRollbackResponse.ts +14 -0
  407. package/src/protocol/v2/ThreadSetNameParams.ts +5 -0
  408. package/src/protocol/v2/ThreadSetNameResponse.ts +5 -0
  409. package/src/protocol/v2/ThreadShellCommandParams.ts +12 -0
  410. package/src/protocol/v2/ThreadShellCommandResponse.ts +5 -0
  411. package/src/protocol/v2/ThreadSortKey.ts +5 -0
  412. package/src/protocol/v2/ThreadSourceKind.ts +5 -0
  413. package/src/protocol/v2/ThreadStartParams.ts +23 -0
  414. package/src/protocol/v2/ThreadStartResponse.ts +15 -0
  415. package/src/protocol/v2/ThreadStartedNotification.ts +6 -0
  416. package/src/protocol/v2/ThreadStatus.ts +6 -0
  417. package/src/protocol/v2/ThreadStatusChangedNotification.ts +6 -0
  418. package/src/protocol/v2/ThreadTokenUsage.ts +6 -0
  419. package/src/protocol/v2/ThreadTokenUsageUpdatedNotification.ts +6 -0
  420. package/src/protocol/v2/ThreadUnarchiveParams.ts +5 -0
  421. package/src/protocol/v2/ThreadUnarchiveResponse.ts +6 -0
  422. package/src/protocol/v2/ThreadUnarchivedNotification.ts +5 -0
  423. package/src/protocol/v2/ThreadUnsubscribeParams.ts +5 -0
  424. package/src/protocol/v2/ThreadUnsubscribeResponse.ts +6 -0
  425. package/src/protocol/v2/ThreadUnsubscribeStatus.ts +5 -0
  426. package/src/protocol/v2/TokenUsageBreakdown.ts +5 -0
  427. package/src/protocol/v2/ToolRequestUserInputAnswer.ts +8 -0
  428. package/src/protocol/v2/ToolRequestUserInputOption.ts +8 -0
  429. package/src/protocol/v2/ToolRequestUserInputParams.ts +9 -0
  430. package/src/protocol/v2/ToolRequestUserInputQuestion.ts +9 -0
  431. package/src/protocol/v2/ToolRequestUserInputResponse.ts +9 -0
  432. package/src/protocol/v2/ToolsV2.ts +6 -0
  433. package/src/protocol/v2/Turn.ts +18 -0
  434. package/src/protocol/v2/TurnCompletedNotification.ts +6 -0
  435. package/src/protocol/v2/TurnDiffUpdatedNotification.ts +9 -0
  436. package/src/protocol/v2/TurnError.ts +6 -0
  437. package/src/protocol/v2/TurnInterruptParams.ts +5 -0
  438. package/src/protocol/v2/TurnInterruptResponse.ts +5 -0
  439. package/src/protocol/v2/TurnPlanStep.ts +6 -0
  440. package/src/protocol/v2/TurnPlanStepStatus.ts +5 -0
  441. package/src/protocol/v2/TurnPlanUpdatedNotification.ts +6 -0
  442. package/src/protocol/v2/TurnStartParams.ts +54 -0
  443. package/src/protocol/v2/TurnStartResponse.ts +6 -0
  444. package/src/protocol/v2/TurnStartedNotification.ts +6 -0
  445. package/src/protocol/v2/TurnStatus.ts +5 -0
  446. package/src/protocol/v2/TurnSteerParams.ts +11 -0
  447. package/src/protocol/v2/TurnSteerResponse.ts +5 -0
  448. package/src/protocol/v2/UserInput.ts +10 -0
  449. package/src/protocol/v2/WebSearchAction.ts +5 -0
  450. package/src/protocol/v2/WindowsSandboxSetupCompletedNotification.ts +6 -0
  451. package/src/protocol/v2/WindowsSandboxSetupMode.ts +5 -0
  452. package/src/protocol/v2/WindowsSandboxSetupStartParams.ts +7 -0
  453. package/src/protocol/v2/WindowsSandboxSetupStartResponse.ts +5 -0
  454. package/src/protocol/v2/WindowsWorldWritableWarningNotification.ts +5 -0
  455. package/src/protocol/v2/WriteStatus.ts +5 -0
  456. package/src/protocol/v2/index.ts +346 -0
  457. package/src/services/app-server-client.ts +636 -0
  458. package/src/services/codex-runtime.ts +500 -0
  459. package/src/services/fleet-mode.ts +29 -0
  460. package/src/services/model-catalog.ts +86 -0
  461. package/src/services/profile-manager.ts +113 -0
  462. package/src/types/codex.ts +57 -0
@@ -0,0 +1,500 @@
1
+ import process from 'node:process';
2
+ import { copyFile, mkdtemp, mkdir, readFile, writeFile } from 'node:fs/promises';
3
+ import { basename, join } from 'node:path';
4
+ import { tmpdir } from 'node:os';
5
+
6
+ import {
7
+ CODEX_APP_SERVER_ARGS_ENV,
8
+ CODEX_APP_SERVER_COMMAND_ENV,
9
+ REQUEST_TIMEOUT_MS,
10
+ } from '../config/defaults.js';
11
+ import type { PendingServerRequest } from '../types/codex.js';
12
+ import { AppServerClient, type BridgedOperationResult } from './app-server-client.js';
13
+ import { appendFleetDeveloperInstructions } from './fleet-mode.js';
14
+ import {
15
+ buildModelCatalog,
16
+ describeAllowedModels,
17
+ resolveModel,
18
+ type ModelCatalog,
19
+ type ModelInfo,
20
+ } from './model-catalog.js';
21
+ import {
22
+ ProfileManager,
23
+ type CodexProfile,
24
+ } from './profile-manager.js';
25
+
26
+ interface RuntimeRequestOptions {
27
+ timeoutMs?: number | undefined;
28
+ }
29
+
30
+ interface RuntimeBridgeOptions extends RuntimeRequestOptions {
31
+ threadId?: string | undefined;
32
+ bridgeTimeoutMs?: number | undefined;
33
+ }
34
+
35
+ interface RuntimeCommandOptions {
36
+ command?: string | undefined;
37
+ args?: string[] | undefined;
38
+ env?: NodeJS.ProcessEnv | undefined;
39
+ }
40
+
41
+ function parseArgs(raw: string | undefined): string[] {
42
+ if (!raw || !raw.trim()) {
43
+ return ['app-server', '--listen', 'stdio://'];
44
+ }
45
+
46
+ const trimmed = raw.trim();
47
+ if (trimmed.startsWith('[')) {
48
+ try {
49
+ const parsed = JSON.parse(trimmed) as unknown;
50
+ if (Array.isArray(parsed) && parsed.every((value) => typeof value === 'string')) {
51
+ return parsed;
52
+ }
53
+ } catch {
54
+ // fall through to token split
55
+ }
56
+ }
57
+
58
+ return trimmed.split(/\s+/g).filter(Boolean);
59
+ }
60
+
61
+ function isRateLimitSignal(error: unknown): boolean {
62
+ const message = error instanceof Error ? error.message : String(error);
63
+ const normalized = message.toLowerCase();
64
+ return (
65
+ normalized.includes('rate limit') ||
66
+ normalized.includes('usage limit') ||
67
+ normalized.includes('usagelimitexceeded') ||
68
+ normalized.includes('429')
69
+ );
70
+ }
71
+
72
+ function isAuthSignal(error: unknown): boolean {
73
+ const message = error instanceof Error ? error.message : String(error);
74
+ const normalized = message.toLowerCase();
75
+ return (
76
+ normalized.includes('unauthorized') ||
77
+ normalized.includes('requires auth') ||
78
+ normalized.includes('authentication') ||
79
+ normalized.includes('login')
80
+ );
81
+ }
82
+
83
+ function isConfigCompatSignal(error: unknown): boolean {
84
+ const message = error instanceof Error ? error.message : String(error);
85
+ const normalized = message.toLowerCase();
86
+ return (
87
+ normalized.includes('error deriving config') ||
88
+ normalized.includes('agentroletoml') ||
89
+ (normalized.includes('invalid type: integer') && normalized.includes('agents'))
90
+ );
91
+ }
92
+
93
+ function sanitizeConfigForCompatibility(rawConfig: string): string {
94
+ const lines = rawConfig.split(/\r?\n/g);
95
+ const sanitized: string[] = [];
96
+ let skippingAgentsSection = false;
97
+
98
+ for (const line of lines) {
99
+ const trimmed = line.trim();
100
+ const isSection = trimmed.startsWith('[') && trimmed.endsWith(']');
101
+ if (isSection) {
102
+ if (trimmed === '[agents]' || trimmed.startsWith('[agents.')) {
103
+ skippingAgentsSection = true;
104
+ continue;
105
+ }
106
+ skippingAgentsSection = false;
107
+ }
108
+
109
+ if (skippingAgentsSection) {
110
+ continue;
111
+ }
112
+
113
+ sanitized.push(line);
114
+ }
115
+
116
+ return sanitized.join('\n');
117
+ }
118
+
119
+ export interface ModelResolutionResult {
120
+ resolvedModel: string;
121
+ remappedFrom?: string | undefined;
122
+ allowedModels: string[];
123
+ }
124
+
125
+ export class CodexRuntime {
126
+ private readonly profileManager: ProfileManager;
127
+ private readonly command: string;
128
+ private readonly args: string[];
129
+ private readonly env: NodeJS.ProcessEnv;
130
+ private readonly clients = new Map<string, AppServerClient>();
131
+ private readonly effectiveCodexHomes = new Map<string, string>();
132
+ private modelCatalog?: ModelCatalog | undefined;
133
+ private readonly knownThreadIds = new Set<string>();
134
+ private readonly loadedThreadIds = new Set<string>();
135
+
136
+ constructor(commandOptions: RuntimeCommandOptions = {}) {
137
+ this.profileManager = ProfileManager.fromEnvironment();
138
+ this.command = commandOptions.command ?? process.env[CODEX_APP_SERVER_COMMAND_ENV] ?? 'codex';
139
+ this.args = commandOptions.args ?? parseArgs(process.env[CODEX_APP_SERVER_ARGS_ENV]);
140
+ this.env = commandOptions.env ?? process.env;
141
+ }
142
+
143
+ async shutdown(): Promise<void> {
144
+ await Promise.all(
145
+ [...this.clients.values()].map((client) => client.stop()),
146
+ );
147
+ this.clients.clear();
148
+ this.loadedThreadIds.clear();
149
+ }
150
+
151
+ getPendingServerRequests(includeResolved = false): PendingServerRequest[] {
152
+ return this.getCurrentClient().listServerRequests(includeResolved);
153
+ }
154
+
155
+ getPendingServerRequest(id: string | number): PendingServerRequest | undefined {
156
+ return this.getCurrentClient().getServerRequest(id);
157
+ }
158
+
159
+ async respondToServerRequest(id: string | number, payload: unknown): Promise<void> {
160
+ await this.getCurrentClient().respondToServerRequest(id, payload);
161
+ }
162
+
163
+ async waitForOperation(operationId: string, timeoutMs: number, pollIntervalMs: number) {
164
+ return this.getCurrentClient().waitForOperation(operationId, {
165
+ timeoutMs,
166
+ pollIntervalMs,
167
+ });
168
+ }
169
+
170
+ getOperation(operationId: string) {
171
+ return this.getCurrentClient().getOperation(operationId);
172
+ }
173
+
174
+ async request(method: string, params: unknown, options: RuntimeRequestOptions = {}): Promise<unknown> {
175
+ const response = await this.withFailover(async (client, profile) => {
176
+ try {
177
+ return await client.request(
178
+ method,
179
+ params,
180
+ { timeoutMs: options.timeoutMs ?? REQUEST_TIMEOUT_MS },
181
+ );
182
+ } catch (error) {
183
+ if (!isConfigCompatSignal(error)) {
184
+ throw error;
185
+ }
186
+
187
+ const compatClient = await this.activateCompatibilityClient(profile);
188
+ return await compatClient.request(
189
+ method,
190
+ params,
191
+ { timeoutMs: options.timeoutMs ?? REQUEST_TIMEOUT_MS },
192
+ );
193
+ }
194
+ });
195
+ this.trackLoadedThread(method, response, params);
196
+ return response;
197
+ }
198
+
199
+ async requestWithBridge(
200
+ method: string,
201
+ params: unknown,
202
+ options: RuntimeBridgeOptions = {},
203
+ ): Promise<BridgedOperationResult> {
204
+ const response = await this.withFailover(async (client, profile) => {
205
+ try {
206
+ return await client.requestWithBridge(
207
+ method,
208
+ params,
209
+ {
210
+ timeoutMs: options.timeoutMs ?? REQUEST_TIMEOUT_MS,
211
+ bridgeTimeoutMs: options.bridgeTimeoutMs,
212
+ threadId: options.threadId,
213
+ },
214
+ );
215
+ } catch (error) {
216
+ if (!isConfigCompatSignal(error)) {
217
+ throw error;
218
+ }
219
+
220
+ const compatClient = await this.activateCompatibilityClient(profile);
221
+ return await compatClient.requestWithBridge(
222
+ method,
223
+ params,
224
+ {
225
+ timeoutMs: options.timeoutMs ?? REQUEST_TIMEOUT_MS,
226
+ bridgeTimeoutMs: options.bridgeTimeoutMs,
227
+ threadId: options.threadId,
228
+ },
229
+ );
230
+ }
231
+ });
232
+ this.trackLoadedThread(method, response.result ?? response, params);
233
+ return response;
234
+ }
235
+
236
+ async listModels(includeHidden = false): Promise<ModelInfo[]> {
237
+ const response = await this.request('model/list', { includeHidden }) as {
238
+ data?: Array<Record<string, unknown>>;
239
+ };
240
+ const models = (response.data ?? []).map((row) => ({
241
+ id: String(row.id),
242
+ model: String(row.model),
243
+ displayName: String(row.displayName),
244
+ hidden: Boolean(row.hidden),
245
+ upgrade: typeof row.upgrade === 'string' ? row.upgrade : null,
246
+ isDefault: Boolean(row.isDefault),
247
+ }));
248
+ this.modelCatalog = buildModelCatalog(models);
249
+ return includeHidden ? models : models.filter((model) => !model.hidden);
250
+ }
251
+
252
+ async resolveRequestedModel(requestedModel?: string | undefined): Promise<ModelResolutionResult> {
253
+ if (!this.modelCatalog) {
254
+ await this.listModels(true);
255
+ }
256
+ const catalog = this.modelCatalog;
257
+ if (!catalog) {
258
+ throw new Error('Failed to build model catalog from model/list.');
259
+ }
260
+
261
+ try {
262
+ const resolution = resolveModel(catalog, requestedModel);
263
+ return {
264
+ resolvedModel: resolution.resolved,
265
+ remappedFrom: resolution.remappedFrom,
266
+ allowedModels: catalog.visibleModels.map((model) => model.id).sort(),
267
+ };
268
+ } catch (error) {
269
+ if (error instanceof Error && error.message.startsWith('Unsupported model')) {
270
+ throw new Error(
271
+ `Unsupported model "${requestedModel}". Allowed models: ${describeAllowedModels(catalog)}`,
272
+ );
273
+ }
274
+ throw error;
275
+ }
276
+ }
277
+
278
+ async listVisibleModelIds(): Promise<string[]> {
279
+ if (!this.modelCatalog) {
280
+ await this.listModels(false);
281
+ }
282
+ return (this.modelCatalog?.visibleModels ?? []).map((model) => model.id).sort();
283
+ }
284
+
285
+ buildThreadStartParams(input: {
286
+ model?: string | undefined;
287
+ cwd?: string | undefined;
288
+ developerInstructions?: string | undefined;
289
+ }): Promise<{ params: Record<string, unknown>; remappedFrom?: string | undefined; }> {
290
+ return this.resolveRequestedModel(input.model).then((resolved) => {
291
+ const params: Record<string, unknown> = {
292
+ model: resolved.resolvedModel,
293
+ modelProvider: 'openai',
294
+ cwd: input.cwd ?? process.cwd(),
295
+ approvalPolicy: 'on-request',
296
+ sandbox: 'workspace-write',
297
+ developerInstructions: appendFleetDeveloperInstructions(input.developerInstructions),
298
+ experimentalRawEvents: false,
299
+ persistExtendedHistory: false,
300
+ };
301
+ return {
302
+ params,
303
+ remappedFrom: resolved.remappedFrom,
304
+ };
305
+ });
306
+ }
307
+
308
+ buildThreadResumeParams(input: {
309
+ threadId: string;
310
+ model?: string | undefined;
311
+ cwd?: string | undefined;
312
+ developerInstructions?: string | undefined;
313
+ }): Promise<{ params: Record<string, unknown>; remappedFrom?: string | undefined; }> {
314
+ return this.resolveRequestedModel(input.model).then((resolved) => {
315
+ const params: Record<string, unknown> = {
316
+ threadId: input.threadId,
317
+ model: resolved.resolvedModel,
318
+ modelProvider: 'openai',
319
+ cwd: input.cwd ?? process.cwd(),
320
+ approvalPolicy: 'on-request',
321
+ sandbox: 'workspace-write',
322
+ developerInstructions: appendFleetDeveloperInstructions(input.developerInstructions),
323
+ persistExtendedHistory: false,
324
+ };
325
+ return {
326
+ params,
327
+ remappedFrom: resolved.remappedFrom,
328
+ };
329
+ });
330
+ }
331
+
332
+ buildTurnStartParams(input: {
333
+ threadId: string;
334
+ userInput: string;
335
+ model?: string | undefined;
336
+ }): Promise<{ params: Record<string, unknown>; remappedFrom?: string | undefined; }> {
337
+ return this.resolveRequestedModel(input.model).then((resolved) => ({
338
+ params: {
339
+ threadId: input.threadId,
340
+ model: resolved.resolvedModel,
341
+ input: [{
342
+ type: 'text',
343
+ text: input.userInput,
344
+ text_elements: [],
345
+ }],
346
+ },
347
+ remappedFrom: resolved.remappedFrom,
348
+ }));
349
+ }
350
+
351
+ buildTurnSteerParams(input: {
352
+ threadId: string;
353
+ expectedTurnId: string;
354
+ userInput: string;
355
+ }): Record<string, unknown> {
356
+ return {
357
+ threadId: input.threadId,
358
+ expectedTurnId: input.expectedTurnId,
359
+ input: [{
360
+ type: 'text',
361
+ text: input.userInput,
362
+ text_elements: [],
363
+ }],
364
+ };
365
+ }
366
+
367
+ async getThreadEvents(threadId: string): Promise<unknown[]> {
368
+ return this.getCurrentClient().getThreadEvents(threadId);
369
+ }
370
+
371
+ rememberThreadId(threadId: string): void {
372
+ this.knownThreadIds.add(threadId);
373
+ }
374
+
375
+ listKnownThreadIds(): string[] {
376
+ return [...this.knownThreadIds].sort();
377
+ }
378
+
379
+ async ensureThreadLoaded(threadId: string, model?: string | undefined): Promise<void> {
380
+ if (!this.knownThreadIds.has(threadId) || this.loadedThreadIds.has(threadId)) {
381
+ return;
382
+ }
383
+
384
+ const built = await this.buildThreadResumeParams({ threadId, model });
385
+ await this.request('thread/resume', built.params);
386
+ }
387
+
388
+ private async withFailover<T>(operation: (client: AppServerClient, profile: CodexProfile) => Promise<T>): Promise<T> {
389
+ let attempt = 0;
390
+ let lastError: unknown;
391
+ while (attempt < this.profileManager.getProfiles().length) {
392
+ const profile = this.profileManager.getCurrentProfile();
393
+ const client = await this.getClient(profile);
394
+ try {
395
+ return await operation(client, profile);
396
+ } catch (error) {
397
+ lastError = error;
398
+ if (!isRateLimitSignal(error) && !isAuthSignal(error)) {
399
+ throw error;
400
+ }
401
+
402
+ await client.stop().catch(() => {});
403
+ this.clients.delete(profile.codexHome);
404
+ this.loadedThreadIds.clear();
405
+ const reason = isRateLimitSignal(error) ? 'rate_limit' : 'auth';
406
+ const rotated = this.profileManager.markFailure(reason);
407
+ if (!rotated.rotated) {
408
+ throw error;
409
+ }
410
+ attempt += 1;
411
+ }
412
+ }
413
+
414
+ throw lastError instanceof Error
415
+ ? lastError
416
+ : new Error(String(lastError));
417
+ }
418
+
419
+ private getCurrentClient(): AppServerClient {
420
+ const profile = this.profileManager.getCurrentProfile();
421
+ const existing = this.clients.get(profile.codexHome);
422
+ if (!existing) {
423
+ throw new Error(`No active Codex app-server client for profile ${profile.codexHome}`);
424
+ }
425
+ return existing;
426
+ }
427
+
428
+ private async getClient(profile: CodexProfile): Promise<AppServerClient> {
429
+ const existing = this.clients.get(profile.codexHome);
430
+ if (existing) {
431
+ return existing;
432
+ }
433
+
434
+ const codexHome = this.effectiveCodexHomes.get(profile.codexHome) ?? profile.codexHome;
435
+ const client = new AppServerClient({
436
+ command: this.command,
437
+ args: this.args,
438
+ env: this.env,
439
+ codexHome,
440
+ appVersion: '0.1.0',
441
+ });
442
+ await client.start();
443
+ this.clients.set(profile.codexHome, client);
444
+ return client;
445
+ }
446
+
447
+ private async activateCompatibilityClient(profile: CodexProfile): Promise<AppServerClient> {
448
+ const existing = this.clients.get(profile.codexHome);
449
+ if (existing) {
450
+ await existing.stop().catch(() => {});
451
+ this.clients.delete(profile.codexHome);
452
+ }
453
+
454
+ if (!this.effectiveCodexHomes.has(profile.codexHome)) {
455
+ const compatHome = await this.createCompatibilityHome(profile.codexHome);
456
+ this.effectiveCodexHomes.set(profile.codexHome, compatHome);
457
+ }
458
+
459
+ this.loadedThreadIds.clear();
460
+ return await this.getClient(profile);
461
+ }
462
+
463
+ private async createCompatibilityHome(sourceCodexHome: string): Promise<string> {
464
+ const compatHome = await mkdtemp(join(tmpdir(), 'mcp-codex-compat-'));
465
+ await mkdir(compatHome, { recursive: true });
466
+
467
+ const configPath = join(sourceCodexHome, 'config.toml');
468
+ const rawConfig = await readFile(configPath, 'utf8');
469
+ await writeFile(join(compatHome, 'config.toml'), sanitizeConfigForCompatibility(rawConfig), 'utf8');
470
+
471
+ for (const fileName of ['auth.json', 'version.json']) {
472
+ try {
473
+ await copyFile(join(sourceCodexHome, fileName), join(compatHome, basename(fileName)));
474
+ } catch {
475
+ // optional compatibility files
476
+ }
477
+ }
478
+
479
+ return compatHome;
480
+ }
481
+
482
+ private trackLoadedThread(method: string, response: unknown, params: unknown): void {
483
+ if (method === 'thread/start' || method === 'thread/resume') {
484
+ const object = response as { thread?: { id?: string } };
485
+ const threadId = object.thread?.id;
486
+ if (typeof threadId === 'string') {
487
+ this.rememberThreadId(threadId);
488
+ this.loadedThreadIds.add(threadId);
489
+ }
490
+ return;
491
+ }
492
+
493
+ if (method === 'turn/start') {
494
+ const object = params as { threadId?: string };
495
+ if (typeof object.threadId === 'string') {
496
+ this.loadedThreadIds.add(object.threadId);
497
+ }
498
+ }
499
+ }
500
+ }
@@ -0,0 +1,29 @@
1
+ import { CODEX_ENABLE_FLEET_ENV } from '../config/defaults.js';
2
+
3
+ const TRUTHY_VALUES = new Set(['1', 'true', 'yes', 'on']);
4
+
5
+ export const FLEET_DEVELOPER_INSTRUCTIONS_SUFFIX = [
6
+ '',
7
+ '[codex-worker-fleet]',
8
+ 'This thread is running under mcp-codex-worker fleet mode.',
9
+ ].join('\n');
10
+
11
+ export function isFleetModeEnabled(value = process.env[CODEX_ENABLE_FLEET_ENV]): boolean {
12
+ return value !== undefined && TRUTHY_VALUES.has(value.trim().toLowerCase());
13
+ }
14
+
15
+ export function appendFleetDeveloperInstructions(
16
+ developerInstructions: string | null | undefined,
17
+ ): string | undefined {
18
+ if (!isFleetModeEnabled()) {
19
+ return developerInstructions ?? undefined;
20
+ }
21
+
22
+ const base = developerInstructions?.trim();
23
+ if (!base) {
24
+ return FLEET_DEVELOPER_INSTRUCTIONS_SUFFIX.trim();
25
+ }
26
+
27
+ return `${base}\n${FLEET_DEVELOPER_INSTRUCTIONS_SUFFIX}`;
28
+ }
29
+
@@ -0,0 +1,86 @@
1
+ export interface ModelInfo {
2
+ id: string;
3
+ model: string;
4
+ displayName: string;
5
+ hidden: boolean;
6
+ upgrade: string | null;
7
+ isDefault: boolean;
8
+ }
9
+
10
+ export interface ModelCatalog {
11
+ visibleModels: ModelInfo[];
12
+ byId: Map<string, ModelInfo>;
13
+ upgradeAliases: Map<string, string>;
14
+ defaultModelId?: string | undefined;
15
+ }
16
+
17
+ export interface ModelResolution {
18
+ requested: string;
19
+ resolved: string;
20
+ remappedFrom?: string | undefined;
21
+ }
22
+
23
+ export function buildModelCatalog(models: ModelInfo[]): ModelCatalog {
24
+ const byId = new Map(models.map((model) => [model.id, model]));
25
+ const visibleModels = models.filter((model) => !model.hidden);
26
+ const upgradeAliases = new Map<string, string>();
27
+
28
+ for (const model of models) {
29
+ if (!model.upgrade) {
30
+ continue;
31
+ }
32
+ if (byId.has(model.upgrade)) {
33
+ upgradeAliases.set(model.id, model.upgrade);
34
+ }
35
+ }
36
+
37
+ const defaultModelId = visibleModels.find((model) => model.isDefault)?.id ?? visibleModels[0]?.id;
38
+
39
+ return {
40
+ visibleModels,
41
+ byId,
42
+ upgradeAliases,
43
+ defaultModelId,
44
+ };
45
+ }
46
+
47
+ export function describeAllowedModels(catalog: ModelCatalog): string {
48
+ return catalog.visibleModels.map((model) => model.id).sort().join(', ');
49
+ }
50
+
51
+ export function resolveModel(
52
+ catalog: ModelCatalog,
53
+ requestedModel?: string | undefined,
54
+ ): ModelResolution {
55
+ const requested = requestedModel ?? catalog.defaultModelId;
56
+ if (!requested) {
57
+ throw new Error('No models available from model/list.');
58
+ }
59
+
60
+ const direct = catalog.byId.get(requested);
61
+ if (direct && !direct.hidden) {
62
+ const upgraded = catalog.upgradeAliases.get(requested);
63
+ if (upgraded) {
64
+ return {
65
+ requested,
66
+ resolved: upgraded,
67
+ remappedFrom: requested,
68
+ };
69
+ }
70
+ return { requested, resolved: requested };
71
+ }
72
+
73
+ const upgraded = catalog.upgradeAliases.get(requested);
74
+ if (upgraded) {
75
+ return {
76
+ requested,
77
+ resolved: upgraded,
78
+ remappedFrom: requested,
79
+ };
80
+ }
81
+
82
+ throw new Error(
83
+ `Unsupported model "${requested}". Allowed models: ${describeAllowedModels(catalog)}`,
84
+ );
85
+ }
86
+