@excitedjs/tm 1.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 (702) hide show
  1. package/bin/tm +76 -0
  2. package/package.json +39 -0
  3. package/resolver-register.mjs +7 -0
  4. package/resolver.mjs +86 -0
  5. package/src/cli/context.ts +63 -0
  6. package/src/cli/dispatch.ts +444 -0
  7. package/src/cli/errors.ts +45 -0
  8. package/src/cli/parse.ts +265 -0
  9. package/src/cli.ts +12 -0
  10. package/src/codex-protocol/AbsolutePathBuf.ts +14 -0
  11. package/src/codex-protocol/AgentPath.ts +5 -0
  12. package/src/codex-protocol/ApplyPatchApprovalParams.ts +21 -0
  13. package/src/codex-protocol/ApplyPatchApprovalResponse.ts +6 -0
  14. package/src/codex-protocol/AuthMode.ts +8 -0
  15. package/src/codex-protocol/AutoCompactTokenLimitScope.ts +9 -0
  16. package/src/codex-protocol/ClientInfo.ts +5 -0
  17. package/src/codex-protocol/ClientNotification.ts +5 -0
  18. package/src/codex-protocol/ClientRequest.ts +110 -0
  19. package/src/codex-protocol/CollaborationMode.ts +10 -0
  20. package/src/codex-protocol/ContentItem.ts +6 -0
  21. package/src/codex-protocol/ConversationGitInfo.ts +5 -0
  22. package/src/codex-protocol/ConversationSummary.ts +8 -0
  23. package/src/codex-protocol/ExecCommandApprovalParams.ts +16 -0
  24. package/src/codex-protocol/ExecCommandApprovalResponse.ts +6 -0
  25. package/src/codex-protocol/ExecPolicyAmendment.ts +12 -0
  26. package/src/codex-protocol/FileChange.ts +5 -0
  27. package/src/codex-protocol/ForcedLoginMethod.ts +5 -0
  28. package/src/codex-protocol/FunctionCallOutputBody.ts +6 -0
  29. package/src/codex-protocol/FunctionCallOutputContentItem.ts +10 -0
  30. package/src/codex-protocol/FuzzyFileSearchMatchType.ts +5 -0
  31. package/src/codex-protocol/FuzzyFileSearchParams.ts +5 -0
  32. package/src/codex-protocol/FuzzyFileSearchResponse.ts +6 -0
  33. package/src/codex-protocol/FuzzyFileSearchResult.ts +9 -0
  34. package/src/codex-protocol/FuzzyFileSearchSessionCompletedNotification.ts +5 -0
  35. package/src/codex-protocol/FuzzyFileSearchSessionStartParams.ts +5 -0
  36. package/src/codex-protocol/FuzzyFileSearchSessionStartResponse.ts +5 -0
  37. package/src/codex-protocol/FuzzyFileSearchSessionStopParams.ts +5 -0
  38. package/src/codex-protocol/FuzzyFileSearchSessionStopResponse.ts +5 -0
  39. package/src/codex-protocol/FuzzyFileSearchSessionUpdateParams.ts +5 -0
  40. package/src/codex-protocol/FuzzyFileSearchSessionUpdateResponse.ts +5 -0
  41. package/src/codex-protocol/FuzzyFileSearchSessionUpdatedNotification.ts +6 -0
  42. package/src/codex-protocol/GetAuthStatusParams.ts +5 -0
  43. package/src/codex-protocol/GetAuthStatusResponse.ts +6 -0
  44. package/src/codex-protocol/GetConversationSummaryParams.ts +6 -0
  45. package/src/codex-protocol/GetConversationSummaryResponse.ts +6 -0
  46. package/src/codex-protocol/GitDiffToRemoteParams.ts +5 -0
  47. package/src/codex-protocol/GitDiffToRemoteResponse.ts +6 -0
  48. package/src/codex-protocol/GitSha.ts +5 -0
  49. package/src/codex-protocol/ImageDetail.ts +5 -0
  50. package/src/codex-protocol/InitializeCapabilities.ts +21 -0
  51. package/src/codex-protocol/InitializeParams.ts +7 -0
  52. package/src/codex-protocol/InitializeResponse.ts +20 -0
  53. package/src/codex-protocol/InputModality.ts +8 -0
  54. package/src/codex-protocol/InternalSessionSource.ts +5 -0
  55. package/src/codex-protocol/LocalShellAction.ts +6 -0
  56. package/src/codex-protocol/LocalShellExecAction.ts +5 -0
  57. package/src/codex-protocol/LocalShellStatus.ts +5 -0
  58. package/src/codex-protocol/MessagePhase.ts +11 -0
  59. package/src/codex-protocol/ModeKind.ts +8 -0
  60. package/src/codex-protocol/NetworkPolicyAmendment.ts +6 -0
  61. package/src/codex-protocol/NetworkPolicyRuleAction.ts +5 -0
  62. package/src/codex-protocol/ParsedCommand.ts +12 -0
  63. package/src/codex-protocol/Personality.ts +5 -0
  64. package/src/codex-protocol/PlanType.ts +5 -0
  65. package/src/codex-protocol/RealtimeConversationVersion.ts +5 -0
  66. package/src/codex-protocol/RealtimeOutputModality.ts +5 -0
  67. package/src/codex-protocol/RealtimeVoice.ts +5 -0
  68. package/src/codex-protocol/RealtimeVoicesList.ts +6 -0
  69. package/src/codex-protocol/ReasoningEffort.ts +8 -0
  70. package/src/codex-protocol/ReasoningItemContent.ts +5 -0
  71. package/src/codex-protocol/ReasoningItemReasoningSummary.ts +5 -0
  72. package/src/codex-protocol/ReasoningSummary.ts +10 -0
  73. package/src/codex-protocol/RequestId.ts +5 -0
  74. package/src/codex-protocol/Resource.ts +9 -0
  75. package/src/codex-protocol/ResourceContent.ts +17 -0
  76. package/src/codex-protocol/ResourceTemplate.ts +9 -0
  77. package/src/codex-protocol/ResponseItem.ts +17 -0
  78. package/src/codex-protocol/ReviewDecision.ts +10 -0
  79. package/src/codex-protocol/ServerNotification.ts +73 -0
  80. package/src/codex-protocol/ServerRequest.ts +19 -0
  81. package/src/codex-protocol/SessionSource.ts +7 -0
  82. package/src/codex-protocol/Settings.ts +9 -0
  83. package/src/codex-protocol/SubAgentSource.ts +7 -0
  84. package/src/codex-protocol/ThreadId.ts +5 -0
  85. package/src/codex-protocol/ThreadMemoryMode.ts +5 -0
  86. package/src/codex-protocol/Tool.ts +9 -0
  87. package/src/codex-protocol/Verbosity.ts +9 -0
  88. package/src/codex-protocol/WebSearchAction.ts +5 -0
  89. package/src/codex-protocol/WebSearchContextSize.ts +5 -0
  90. package/src/codex-protocol/WebSearchLocation.ts +5 -0
  91. package/src/codex-protocol/WebSearchMode.ts +5 -0
  92. package/src/codex-protocol/WebSearchToolConfig.ts +7 -0
  93. package/src/codex-protocol/index.ts +86 -0
  94. package/src/codex-protocol/serde_json/JsonValue.ts +5 -0
  95. package/src/codex-protocol/v2/Account.ts +6 -0
  96. package/src/codex-protocol/v2/AccountLoginCompletedNotification.ts +5 -0
  97. package/src/codex-protocol/v2/AccountRateLimitsUpdatedNotification.ts +6 -0
  98. package/src/codex-protocol/v2/AccountUpdatedNotification.ts +7 -0
  99. package/src/codex-protocol/v2/ActivePermissionProfile.ts +15 -0
  100. package/src/codex-protocol/v2/AddCreditsNudgeCreditType.ts +5 -0
  101. package/src/codex-protocol/v2/AddCreditsNudgeEmailStatus.ts +5 -0
  102. package/src/codex-protocol/v2/AdditionalFileSystemPermissions.ts +15 -0
  103. package/src/codex-protocol/v2/AdditionalNetworkPermissions.ts +5 -0
  104. package/src/codex-protocol/v2/AdditionalPermissionProfile.ts +11 -0
  105. package/src/codex-protocol/v2/AgentMessageDeltaNotification.ts +5 -0
  106. package/src/codex-protocol/v2/AnalyticsConfig.ts +6 -0
  107. package/src/codex-protocol/v2/AppBranding.ts +8 -0
  108. package/src/codex-protocol/v2/AppInfo.ts +19 -0
  109. package/src/codex-protocol/v2/AppListUpdatedNotification.ts +9 -0
  110. package/src/codex-protocol/v2/AppMetadata.ts +7 -0
  111. package/src/codex-protocol/v2/AppReview.ts +5 -0
  112. package/src/codex-protocol/v2/AppScreenshot.ts +5 -0
  113. package/src/codex-protocol/v2/AppSummary.ts +8 -0
  114. package/src/codex-protocol/v2/AppToolApproval.ts +5 -0
  115. package/src/codex-protocol/v2/AppToolsConfig.ts +6 -0
  116. package/src/codex-protocol/v2/ApprovalsReviewer.ts +12 -0
  117. package/src/codex-protocol/v2/AppsConfig.ts +8 -0
  118. package/src/codex-protocol/v2/AppsDefaultConfig.ts +5 -0
  119. package/src/codex-protocol/v2/AppsListParams.ts +24 -0
  120. package/src/codex-protocol/v2/AppsListResponse.ts +14 -0
  121. package/src/codex-protocol/v2/AskForApproval.ts +5 -0
  122. package/src/codex-protocol/v2/AttestationGenerateParams.ts +5 -0
  123. package/src/codex-protocol/v2/AttestationGenerateResponse.ts +9 -0
  124. package/src/codex-protocol/v2/AutoReviewDecisionSource.ts +8 -0
  125. package/src/codex-protocol/v2/ByteRange.ts +5 -0
  126. package/src/codex-protocol/v2/CancelLoginAccountParams.ts +5 -0
  127. package/src/codex-protocol/v2/CancelLoginAccountResponse.ts +6 -0
  128. package/src/codex-protocol/v2/CancelLoginAccountStatus.ts +5 -0
  129. package/src/codex-protocol/v2/ChatgptAuthTokensRefreshParams.ts +16 -0
  130. package/src/codex-protocol/v2/ChatgptAuthTokensRefreshReason.ts +5 -0
  131. package/src/codex-protocol/v2/ChatgptAuthTokensRefreshResponse.ts +5 -0
  132. package/src/codex-protocol/v2/CodexErrorInfo.ts +12 -0
  133. package/src/codex-protocol/v2/CollabAgentState.ts +6 -0
  134. package/src/codex-protocol/v2/CollabAgentStatus.ts +5 -0
  135. package/src/codex-protocol/v2/CollabAgentTool.ts +5 -0
  136. package/src/codex-protocol/v2/CollabAgentToolCallStatus.ts +5 -0
  137. package/src/codex-protocol/v2/CollaborationModeListParams.ts +8 -0
  138. package/src/codex-protocol/v2/CollaborationModeListResponse.ts +9 -0
  139. package/src/codex-protocol/v2/CollaborationModeMask.ts +10 -0
  140. package/src/codex-protocol/v2/CommandAction.ts +6 -0
  141. package/src/codex-protocol/v2/CommandExecOutputDeltaNotification.ts +30 -0
  142. package/src/codex-protocol/v2/CommandExecOutputStream.ts +8 -0
  143. package/src/codex-protocol/v2/CommandExecParams.ts +105 -0
  144. package/src/codex-protocol/v2/CommandExecResizeParams.ts +18 -0
  145. package/src/codex-protocol/v2/CommandExecResizeResponse.ts +8 -0
  146. package/src/codex-protocol/v2/CommandExecResponse.ts +24 -0
  147. package/src/codex-protocol/v2/CommandExecTerminalSize.ts +16 -0
  148. package/src/codex-protocol/v2/CommandExecTerminateParams.ts +13 -0
  149. package/src/codex-protocol/v2/CommandExecTerminateResponse.ts +8 -0
  150. package/src/codex-protocol/v2/CommandExecWriteParams.ts +22 -0
  151. package/src/codex-protocol/v2/CommandExecWriteResponse.ts +8 -0
  152. package/src/codex-protocol/v2/CommandExecutionApprovalDecision.ts +7 -0
  153. package/src/codex-protocol/v2/CommandExecutionOutputDeltaNotification.ts +5 -0
  154. package/src/codex-protocol/v2/CommandExecutionRequestApprovalParams.ts +62 -0
  155. package/src/codex-protocol/v2/CommandExecutionRequestApprovalResponse.ts +6 -0
  156. package/src/codex-protocol/v2/CommandExecutionSource.ts +5 -0
  157. package/src/codex-protocol/v2/CommandExecutionStatus.ts +5 -0
  158. package/src/codex-protocol/v2/CommandMigration.ts +5 -0
  159. package/src/codex-protocol/v2/ComputerUseRequirements.ts +5 -0
  160. package/src/codex-protocol/v2/Config.ts +26 -0
  161. package/src/codex-protocol/v2/ConfigBatchWriteParams.ts +14 -0
  162. package/src/codex-protocol/v2/ConfigEdit.ts +7 -0
  163. package/src/codex-protocol/v2/ConfigLayer.ts +7 -0
  164. package/src/codex-protocol/v2/ConfigLayerMetadata.ts +6 -0
  165. package/src/codex-protocol/v2/ConfigLayerSource.ts +21 -0
  166. package/src/codex-protocol/v2/ConfigReadParams.ts +11 -0
  167. package/src/codex-protocol/v2/ConfigReadResponse.ts +8 -0
  168. package/src/codex-protocol/v2/ConfigRequirements.ts +13 -0
  169. package/src/codex-protocol/v2/ConfigRequirementsReadResponse.ts +10 -0
  170. package/src/codex-protocol/v2/ConfigValueWriteParams.ts +11 -0
  171. package/src/codex-protocol/v2/ConfigWarningNotification.ts +22 -0
  172. package/src/codex-protocol/v2/ConfigWriteResponse.ts +12 -0
  173. package/src/codex-protocol/v2/ConfiguredHookHandler.ts +5 -0
  174. package/src/codex-protocol/v2/ConfiguredHookMatcherGroup.ts +6 -0
  175. package/src/codex-protocol/v2/ContextCompactedNotification.ts +8 -0
  176. package/src/codex-protocol/v2/CreditsSnapshot.ts +5 -0
  177. package/src/codex-protocol/v2/DeprecationNoticeNotification.ts +13 -0
  178. package/src/codex-protocol/v2/DynamicToolCallOutputContentItem.ts +5 -0
  179. package/src/codex-protocol/v2/DynamicToolCallParams.ts +6 -0
  180. package/src/codex-protocol/v2/DynamicToolCallResponse.ts +6 -0
  181. package/src/codex-protocol/v2/DynamicToolCallStatus.ts +5 -0
  182. package/src/codex-protocol/v2/DynamicToolSpec.ts +6 -0
  183. package/src/codex-protocol/v2/EnvironmentAddParams.ts +5 -0
  184. package/src/codex-protocol/v2/EnvironmentAddResponse.ts +5 -0
  185. package/src/codex-protocol/v2/ErrorNotification.ts +6 -0
  186. package/src/codex-protocol/v2/ExecPolicyAmendment.ts +5 -0
  187. package/src/codex-protocol/v2/ExperimentalFeature.ts +37 -0
  188. package/src/codex-protocol/v2/ExperimentalFeatureEnablementSetParams.ts +12 -0
  189. package/src/codex-protocol/v2/ExperimentalFeatureEnablementSetResponse.ts +9 -0
  190. package/src/codex-protocol/v2/ExperimentalFeatureListParams.ts +19 -0
  191. package/src/codex-protocol/v2/ExperimentalFeatureListResponse.ts +11 -0
  192. package/src/codex-protocol/v2/ExperimentalFeatureStage.ts +5 -0
  193. package/src/codex-protocol/v2/ExternalAgentConfigDetectParams.ts +13 -0
  194. package/src/codex-protocol/v2/ExternalAgentConfigDetectResponse.ts +6 -0
  195. package/src/codex-protocol/v2/ExternalAgentConfigImportCompletedNotification.ts +5 -0
  196. package/src/codex-protocol/v2/ExternalAgentConfigImportParams.ts +6 -0
  197. package/src/codex-protocol/v2/ExternalAgentConfigImportResponse.ts +5 -0
  198. package/src/codex-protocol/v2/ExternalAgentConfigMigrationItem.ts +11 -0
  199. package/src/codex-protocol/v2/ExternalAgentConfigMigrationItemType.ts +5 -0
  200. package/src/codex-protocol/v2/FeedbackUploadParams.ts +5 -0
  201. package/src/codex-protocol/v2/FeedbackUploadResponse.ts +5 -0
  202. package/src/codex-protocol/v2/FileChangeApprovalDecision.ts +5 -0
  203. package/src/codex-protocol/v2/FileChangeOutputDeltaNotification.ts +10 -0
  204. package/src/codex-protocol/v2/FileChangePatchUpdatedNotification.ts +6 -0
  205. package/src/codex-protocol/v2/FileChangeRequestApprovalParams.ts +18 -0
  206. package/src/codex-protocol/v2/FileChangeRequestApprovalResponse.ts +6 -0
  207. package/src/codex-protocol/v2/FileSystemAccessMode.ts +5 -0
  208. package/src/codex-protocol/v2/FileSystemPath.ts +7 -0
  209. package/src/codex-protocol/v2/FileSystemSandboxEntry.ts +7 -0
  210. package/src/codex-protocol/v2/FileSystemSpecialPath.ts +5 -0
  211. package/src/codex-protocol/v2/FileUpdateChange.ts +6 -0
  212. package/src/codex-protocol/v2/ForcedChatgptWorkspaceIds.ts +8 -0
  213. package/src/codex-protocol/v2/FsChangedNotification.ts +17 -0
  214. package/src/codex-protocol/v2/FsCopyParams.ts +21 -0
  215. package/src/codex-protocol/v2/FsCopyResponse.ts +8 -0
  216. package/src/codex-protocol/v2/FsCreateDirectoryParams.ts +17 -0
  217. package/src/codex-protocol/v2/FsCreateDirectoryResponse.ts +8 -0
  218. package/src/codex-protocol/v2/FsGetMetadataParams.ts +13 -0
  219. package/src/codex-protocol/v2/FsGetMetadataResponse.ts +28 -0
  220. package/src/codex-protocol/v2/FsReadDirectoryEntry.ts +20 -0
  221. package/src/codex-protocol/v2/FsReadDirectoryParams.ts +13 -0
  222. package/src/codex-protocol/v2/FsReadDirectoryResponse.ts +13 -0
  223. package/src/codex-protocol/v2/FsReadFileParams.ts +13 -0
  224. package/src/codex-protocol/v2/FsReadFileResponse.ts +12 -0
  225. package/src/codex-protocol/v2/FsRemoveParams.ts +21 -0
  226. package/src/codex-protocol/v2/FsRemoveResponse.ts +8 -0
  227. package/src/codex-protocol/v2/FsUnwatchParams.ts +12 -0
  228. package/src/codex-protocol/v2/FsUnwatchResponse.ts +8 -0
  229. package/src/codex-protocol/v2/FsWatchParams.ts +17 -0
  230. package/src/codex-protocol/v2/FsWatchResponse.ts +13 -0
  231. package/src/codex-protocol/v2/FsWriteFileParams.ts +17 -0
  232. package/src/codex-protocol/v2/FsWriteFileResponse.ts +8 -0
  233. package/src/codex-protocol/v2/GetAccountParams.ts +13 -0
  234. package/src/codex-protocol/v2/GetAccountRateLimitsResponse.ts +14 -0
  235. package/src/codex-protocol/v2/GetAccountResponse.ts +6 -0
  236. package/src/codex-protocol/v2/GitInfo.ts +5 -0
  237. package/src/codex-protocol/v2/GrantedPermissionProfile.ts +7 -0
  238. package/src/codex-protocol/v2/GuardianApprovalReview.ts +13 -0
  239. package/src/codex-protocol/v2/GuardianApprovalReviewAction.ts +9 -0
  240. package/src/codex-protocol/v2/GuardianApprovalReviewStatus.ts +8 -0
  241. package/src/codex-protocol/v2/GuardianCommandSource.ts +5 -0
  242. package/src/codex-protocol/v2/GuardianRiskLevel.ts +8 -0
  243. package/src/codex-protocol/v2/GuardianUserAuthorization.ts +8 -0
  244. package/src/codex-protocol/v2/GuardianWarningNotification.ts +13 -0
  245. package/src/codex-protocol/v2/HookCompletedNotification.ts +6 -0
  246. package/src/codex-protocol/v2/HookErrorInfo.ts +5 -0
  247. package/src/codex-protocol/v2/HookEventName.ts +5 -0
  248. package/src/codex-protocol/v2/HookExecutionMode.ts +5 -0
  249. package/src/codex-protocol/v2/HookHandlerType.ts +5 -0
  250. package/src/codex-protocol/v2/HookMetadata.ts +10 -0
  251. package/src/codex-protocol/v2/HookMigration.ts +5 -0
  252. package/src/codex-protocol/v2/HookOutputEntry.ts +6 -0
  253. package/src/codex-protocol/v2/HookOutputEntryKind.ts +5 -0
  254. package/src/codex-protocol/v2/HookPromptFragment.ts +5 -0
  255. package/src/codex-protocol/v2/HookRunStatus.ts +5 -0
  256. package/src/codex-protocol/v2/HookRunSummary.ts +13 -0
  257. package/src/codex-protocol/v2/HookScope.ts +5 -0
  258. package/src/codex-protocol/v2/HookSource.ts +5 -0
  259. package/src/codex-protocol/v2/HookStartedNotification.ts +6 -0
  260. package/src/codex-protocol/v2/HookTrustStatus.ts +5 -0
  261. package/src/codex-protocol/v2/HooksListEntry.ts +7 -0
  262. package/src/codex-protocol/v2/HooksListParams.ts +9 -0
  263. package/src/codex-protocol/v2/HooksListResponse.ts +6 -0
  264. package/src/codex-protocol/v2/ItemCompletedNotification.ts +10 -0
  265. package/src/codex-protocol/v2/ItemGuardianApprovalReviewCompletedNotification.ts +38 -0
  266. package/src/codex-protocol/v2/ItemGuardianApprovalReviewStartedNotification.ts +33 -0
  267. package/src/codex-protocol/v2/ItemStartedNotification.ts +10 -0
  268. package/src/codex-protocol/v2/ListMcpServerStatusParams.ts +19 -0
  269. package/src/codex-protocol/v2/ListMcpServerStatusResponse.ts +11 -0
  270. package/src/codex-protocol/v2/LoginAccountParams.ts +21 -0
  271. package/src/codex-protocol/v2/LoginAccountResponse.ts +17 -0
  272. package/src/codex-protocol/v2/LogoutAccountResponse.ts +5 -0
  273. package/src/codex-protocol/v2/ManagedHooksRequirements.ts +6 -0
  274. package/src/codex-protocol/v2/MarketplaceAddParams.ts +5 -0
  275. package/src/codex-protocol/v2/MarketplaceAddResponse.ts +6 -0
  276. package/src/codex-protocol/v2/MarketplaceInterface.ts +5 -0
  277. package/src/codex-protocol/v2/MarketplaceLoadErrorInfo.ts +6 -0
  278. package/src/codex-protocol/v2/MarketplaceRemoveParams.ts +5 -0
  279. package/src/codex-protocol/v2/MarketplaceRemoveResponse.ts +6 -0
  280. package/src/codex-protocol/v2/MarketplaceUpgradeErrorInfo.ts +5 -0
  281. package/src/codex-protocol/v2/MarketplaceUpgradeParams.ts +5 -0
  282. package/src/codex-protocol/v2/MarketplaceUpgradeResponse.ts +7 -0
  283. package/src/codex-protocol/v2/McpAuthStatus.ts +5 -0
  284. package/src/codex-protocol/v2/McpElicitationArrayType.ts +5 -0
  285. package/src/codex-protocol/v2/McpElicitationBooleanSchema.ts +6 -0
  286. package/src/codex-protocol/v2/McpElicitationBooleanType.ts +5 -0
  287. package/src/codex-protocol/v2/McpElicitationConstOption.ts +5 -0
  288. package/src/codex-protocol/v2/McpElicitationEnumSchema.ts +8 -0
  289. package/src/codex-protocol/v2/McpElicitationLegacyTitledEnumSchema.ts +6 -0
  290. package/src/codex-protocol/v2/McpElicitationMultiSelectEnumSchema.ts +7 -0
  291. package/src/codex-protocol/v2/McpElicitationNumberSchema.ts +6 -0
  292. package/src/codex-protocol/v2/McpElicitationNumberType.ts +5 -0
  293. package/src/codex-protocol/v2/McpElicitationObjectType.ts +5 -0
  294. package/src/codex-protocol/v2/McpElicitationPrimitiveSchema.ts +9 -0
  295. package/src/codex-protocol/v2/McpElicitationSchema.ts +13 -0
  296. package/src/codex-protocol/v2/McpElicitationSingleSelectEnumSchema.ts +7 -0
  297. package/src/codex-protocol/v2/McpElicitationStringFormat.ts +5 -0
  298. package/src/codex-protocol/v2/McpElicitationStringSchema.ts +7 -0
  299. package/src/codex-protocol/v2/McpElicitationStringType.ts +5 -0
  300. package/src/codex-protocol/v2/McpElicitationTitledEnumItems.ts +6 -0
  301. package/src/codex-protocol/v2/McpElicitationTitledMultiSelectEnumSchema.ts +7 -0
  302. package/src/codex-protocol/v2/McpElicitationTitledSingleSelectEnumSchema.ts +7 -0
  303. package/src/codex-protocol/v2/McpElicitationUntitledEnumItems.ts +6 -0
  304. package/src/codex-protocol/v2/McpElicitationUntitledMultiSelectEnumSchema.ts +7 -0
  305. package/src/codex-protocol/v2/McpElicitationUntitledSingleSelectEnumSchema.ts +6 -0
  306. package/src/codex-protocol/v2/McpResourceReadParams.ts +5 -0
  307. package/src/codex-protocol/v2/McpResourceReadResponse.ts +6 -0
  308. package/src/codex-protocol/v2/McpServerElicitationAction.ts +5 -0
  309. package/src/codex-protocol/v2/McpServerElicitationRequestParams.ts +16 -0
  310. package/src/codex-protocol/v2/McpServerElicitationRequestResponse.ts +17 -0
  311. package/src/codex-protocol/v2/McpServerMigration.ts +5 -0
  312. package/src/codex-protocol/v2/McpServerOauthLoginCompletedNotification.ts +5 -0
  313. package/src/codex-protocol/v2/McpServerOauthLoginParams.ts +5 -0
  314. package/src/codex-protocol/v2/McpServerOauthLoginResponse.ts +5 -0
  315. package/src/codex-protocol/v2/McpServerRefreshResponse.ts +5 -0
  316. package/src/codex-protocol/v2/McpServerStartupState.ts +5 -0
  317. package/src/codex-protocol/v2/McpServerStatus.ts +9 -0
  318. package/src/codex-protocol/v2/McpServerStatusDetail.ts +5 -0
  319. package/src/codex-protocol/v2/McpServerStatusUpdatedNotification.ts +6 -0
  320. package/src/codex-protocol/v2/McpServerToolCallParams.ts +6 -0
  321. package/src/codex-protocol/v2/McpServerToolCallResponse.ts +6 -0
  322. package/src/codex-protocol/v2/McpToolCallError.ts +5 -0
  323. package/src/codex-protocol/v2/McpToolCallProgressNotification.ts +5 -0
  324. package/src/codex-protocol/v2/McpToolCallResult.ts +6 -0
  325. package/src/codex-protocol/v2/McpToolCallStatus.ts +5 -0
  326. package/src/codex-protocol/v2/MemoryCitation.ts +6 -0
  327. package/src/codex-protocol/v2/MemoryCitationEntry.ts +5 -0
  328. package/src/codex-protocol/v2/MemoryResetResponse.ts +5 -0
  329. package/src/codex-protocol/v2/MergeStrategy.ts +5 -0
  330. package/src/codex-protocol/v2/MigrationDetails.ts +11 -0
  331. package/src/codex-protocol/v2/MockExperimentalMethodParams.ts +9 -0
  332. package/src/codex-protocol/v2/MockExperimentalMethodResponse.ts +9 -0
  333. package/src/codex-protocol/v2/Model.ts +19 -0
  334. package/src/codex-protocol/v2/ModelAvailabilityNux.ts +5 -0
  335. package/src/codex-protocol/v2/ModelListParams.ts +17 -0
  336. package/src/codex-protocol/v2/ModelListResponse.ts +11 -0
  337. package/src/codex-protocol/v2/ModelProviderCapabilitiesReadParams.ts +5 -0
  338. package/src/codex-protocol/v2/ModelProviderCapabilitiesReadResponse.ts +5 -0
  339. package/src/codex-protocol/v2/ModelRerouteReason.ts +5 -0
  340. package/src/codex-protocol/v2/ModelReroutedNotification.ts +6 -0
  341. package/src/codex-protocol/v2/ModelServiceTier.ts +5 -0
  342. package/src/codex-protocol/v2/ModelUpgradeInfo.ts +5 -0
  343. package/src/codex-protocol/v2/ModelVerification.ts +5 -0
  344. package/src/codex-protocol/v2/ModelVerificationNotification.ts +6 -0
  345. package/src/codex-protocol/v2/NetworkAccess.ts +5 -0
  346. package/src/codex-protocol/v2/NetworkApprovalContext.ts +6 -0
  347. package/src/codex-protocol/v2/NetworkApprovalProtocol.ts +5 -0
  348. package/src/codex-protocol/v2/NetworkDomainPermission.ts +5 -0
  349. package/src/codex-protocol/v2/NetworkPolicyAmendment.ts +6 -0
  350. package/src/codex-protocol/v2/NetworkPolicyRuleAction.ts +5 -0
  351. package/src/codex-protocol/v2/NetworkRequirements.ts +32 -0
  352. package/src/codex-protocol/v2/NetworkUnixSocketPermission.ts +5 -0
  353. package/src/codex-protocol/v2/NonSteerableTurnKind.ts +5 -0
  354. package/src/codex-protocol/v2/OverriddenMetadata.ts +7 -0
  355. package/src/codex-protocol/v2/PatchApplyStatus.ts +5 -0
  356. package/src/codex-protocol/v2/PatchChangeKind.ts +5 -0
  357. package/src/codex-protocol/v2/PermissionGrantScope.ts +5 -0
  358. package/src/codex-protocol/v2/PermissionProfileListParams.ts +17 -0
  359. package/src/codex-protocol/v2/PermissionProfileListResponse.ts +11 -0
  360. package/src/codex-protocol/v2/PermissionProfileSummary.ts +13 -0
  361. package/src/codex-protocol/v2/PermissionsRequestApprovalParams.ts +11 -0
  362. package/src/codex-protocol/v2/PermissionsRequestApprovalResponse.ts +11 -0
  363. package/src/codex-protocol/v2/PlanDeltaNotification.ts +9 -0
  364. package/src/codex-protocol/v2/PluginAuthPolicy.ts +5 -0
  365. package/src/codex-protocol/v2/PluginAvailability.ts +5 -0
  366. package/src/codex-protocol/v2/PluginDetail.ts +10 -0
  367. package/src/codex-protocol/v2/PluginHookSummary.ts +6 -0
  368. package/src/codex-protocol/v2/PluginInstallParams.ts +6 -0
  369. package/src/codex-protocol/v2/PluginInstallPolicy.ts +5 -0
  370. package/src/codex-protocol/v2/PluginInstallResponse.ts +7 -0
  371. package/src/codex-protocol/v2/PluginInstalledParams.ts +15 -0
  372. package/src/codex-protocol/v2/PluginInstalledResponse.ts +7 -0
  373. package/src/codex-protocol/v2/PluginInterface.ts +35 -0
  374. package/src/codex-protocol/v2/PluginListMarketplaceKind.ts +5 -0
  375. package/src/codex-protocol/v2/PluginListParams.ts +17 -0
  376. package/src/codex-protocol/v2/PluginListResponse.ts +7 -0
  377. package/src/codex-protocol/v2/PluginMarketplaceEntry.ts +13 -0
  378. package/src/codex-protocol/v2/PluginReadParams.ts +6 -0
  379. package/src/codex-protocol/v2/PluginReadResponse.ts +6 -0
  380. package/src/codex-protocol/v2/PluginShareCheckoutParams.ts +5 -0
  381. package/src/codex-protocol/v2/PluginShareCheckoutResponse.ts +6 -0
  382. package/src/codex-protocol/v2/PluginShareContext.ts +11 -0
  383. package/src/codex-protocol/v2/PluginShareDeleteParams.ts +5 -0
  384. package/src/codex-protocol/v2/PluginShareDeleteResponse.ts +5 -0
  385. package/src/codex-protocol/v2/PluginShareDiscoverability.ts +5 -0
  386. package/src/codex-protocol/v2/PluginShareListItem.ts +7 -0
  387. package/src/codex-protocol/v2/PluginShareListParams.ts +5 -0
  388. package/src/codex-protocol/v2/PluginShareListResponse.ts +6 -0
  389. package/src/codex-protocol/v2/PluginSharePrincipal.ts +7 -0
  390. package/src/codex-protocol/v2/PluginSharePrincipalRole.ts +5 -0
  391. package/src/codex-protocol/v2/PluginSharePrincipalType.ts +5 -0
  392. package/src/codex-protocol/v2/PluginShareSaveParams.ts +8 -0
  393. package/src/codex-protocol/v2/PluginShareSaveResponse.ts +5 -0
  394. package/src/codex-protocol/v2/PluginShareTarget.ts +7 -0
  395. package/src/codex-protocol/v2/PluginShareTargetRole.ts +5 -0
  396. package/src/codex-protocol/v2/PluginShareUpdateDiscoverability.ts +5 -0
  397. package/src/codex-protocol/v2/PluginShareUpdateTargetsParams.ts +7 -0
  398. package/src/codex-protocol/v2/PluginShareUpdateTargetsResponse.ts +7 -0
  399. package/src/codex-protocol/v2/PluginSkillReadParams.ts +5 -0
  400. package/src/codex-protocol/v2/PluginSkillReadResponse.ts +5 -0
  401. package/src/codex-protocol/v2/PluginSource.ts +6 -0
  402. package/src/codex-protocol/v2/PluginSummary.ts +27 -0
  403. package/src/codex-protocol/v2/PluginUninstallParams.ts +5 -0
  404. package/src/codex-protocol/v2/PluginUninstallResponse.ts +5 -0
  405. package/src/codex-protocol/v2/PluginsMigration.ts +5 -0
  406. package/src/codex-protocol/v2/ProcessExitedNotification.ts +42 -0
  407. package/src/codex-protocol/v2/ProcessKillParams.ts +12 -0
  408. package/src/codex-protocol/v2/ProcessKillResponse.ts +8 -0
  409. package/src/codex-protocol/v2/ProcessOutputDeltaNotification.ts +26 -0
  410. package/src/codex-protocol/v2/ProcessOutputStream.ts +8 -0
  411. package/src/codex-protocol/v2/ProcessResizePtyParams.ts +17 -0
  412. package/src/codex-protocol/v2/ProcessResizePtyResponse.ts +8 -0
  413. package/src/codex-protocol/v2/ProcessSpawnParams.ts +73 -0
  414. package/src/codex-protocol/v2/ProcessSpawnResponse.ts +8 -0
  415. package/src/codex-protocol/v2/ProcessTerminalSize.ts +16 -0
  416. package/src/codex-protocol/v2/ProcessWriteStdinParams.ts +21 -0
  417. package/src/codex-protocol/v2/ProcessWriteStdinResponse.ts +8 -0
  418. package/src/codex-protocol/v2/ProfileV2.ts +19 -0
  419. package/src/codex-protocol/v2/RateLimitReachedType.ts +5 -0
  420. package/src/codex-protocol/v2/RateLimitSnapshot.ts +9 -0
  421. package/src/codex-protocol/v2/RateLimitWindow.ts +5 -0
  422. package/src/codex-protocol/v2/RawResponseItemCompletedNotification.ts +6 -0
  423. package/src/codex-protocol/v2/ReasoningEffortOption.ts +6 -0
  424. package/src/codex-protocol/v2/ReasoningSummaryPartAddedNotification.ts +5 -0
  425. package/src/codex-protocol/v2/ReasoningSummaryTextDeltaNotification.ts +5 -0
  426. package/src/codex-protocol/v2/ReasoningTextDeltaNotification.ts +5 -0
  427. package/src/codex-protocol/v2/RemoteControlConnectionStatus.ts +5 -0
  428. package/src/codex-protocol/v2/RemoteControlDisableResponse.ts +6 -0
  429. package/src/codex-protocol/v2/RemoteControlEnableResponse.ts +6 -0
  430. package/src/codex-protocol/v2/RemoteControlStatusChangedNotification.ts +9 -0
  431. package/src/codex-protocol/v2/RemoteControlStatusReadResponse.ts +6 -0
  432. package/src/codex-protocol/v2/RequestPermissionProfile.ts +7 -0
  433. package/src/codex-protocol/v2/ResidencyRequirement.ts +5 -0
  434. package/src/codex-protocol/v2/ReviewDelivery.ts +5 -0
  435. package/src/codex-protocol/v2/ReviewStartParams.ts +12 -0
  436. package/src/codex-protocol/v2/ReviewStartResponse.ts +13 -0
  437. package/src/codex-protocol/v2/ReviewTarget.ts +9 -0
  438. package/src/codex-protocol/v2/SandboxMode.ts +5 -0
  439. package/src/codex-protocol/v2/SandboxPolicy.ts +7 -0
  440. package/src/codex-protocol/v2/SandboxWorkspaceWrite.ts +5 -0
  441. package/src/codex-protocol/v2/SendAddCreditsNudgeEmailParams.ts +6 -0
  442. package/src/codex-protocol/v2/SendAddCreditsNudgeEmailResponse.ts +6 -0
  443. package/src/codex-protocol/v2/ServerRequestResolvedNotification.ts +6 -0
  444. package/src/codex-protocol/v2/SessionMigration.ts +5 -0
  445. package/src/codex-protocol/v2/SessionSource.ts +6 -0
  446. package/src/codex-protocol/v2/SkillDependencies.ts +6 -0
  447. package/src/codex-protocol/v2/SkillErrorInfo.ts +5 -0
  448. package/src/codex-protocol/v2/SkillInterface.ts +6 -0
  449. package/src/codex-protocol/v2/SkillMetadata.ts +13 -0
  450. package/src/codex-protocol/v2/SkillScope.ts +5 -0
  451. package/src/codex-protocol/v2/SkillSummary.ts +7 -0
  452. package/src/codex-protocol/v2/SkillToolDependency.ts +5 -0
  453. package/src/codex-protocol/v2/SkillsChangedNotification.ts +11 -0
  454. package/src/codex-protocol/v2/SkillsConfigWriteParams.ts +14 -0
  455. package/src/codex-protocol/v2/SkillsConfigWriteResponse.ts +5 -0
  456. package/src/codex-protocol/v2/SkillsListEntry.ts +7 -0
  457. package/src/codex-protocol/v2/SkillsListParams.ts +13 -0
  458. package/src/codex-protocol/v2/SkillsListResponse.ts +6 -0
  459. package/src/codex-protocol/v2/SortDirection.ts +5 -0
  460. package/src/codex-protocol/v2/SubagentMigration.ts +5 -0
  461. package/src/codex-protocol/v2/TerminalInteractionNotification.ts +5 -0
  462. package/src/codex-protocol/v2/TextElement.ts +14 -0
  463. package/src/codex-protocol/v2/TextPosition.ts +13 -0
  464. package/src/codex-protocol/v2/TextRange.ts +6 -0
  465. package/src/codex-protocol/v2/Thread.ts +86 -0
  466. package/src/codex-protocol/v2/ThreadActiveFlag.ts +5 -0
  467. package/src/codex-protocol/v2/ThreadApproveGuardianDeniedActionParams.ts +10 -0
  468. package/src/codex-protocol/v2/ThreadApproveGuardianDeniedActionResponse.ts +5 -0
  469. package/src/codex-protocol/v2/ThreadArchiveParams.ts +5 -0
  470. package/src/codex-protocol/v2/ThreadArchiveResponse.ts +5 -0
  471. package/src/codex-protocol/v2/ThreadArchivedNotification.ts +5 -0
  472. package/src/codex-protocol/v2/ThreadBackgroundTerminalsCleanParams.ts +5 -0
  473. package/src/codex-protocol/v2/ThreadBackgroundTerminalsCleanResponse.ts +5 -0
  474. package/src/codex-protocol/v2/ThreadClosedNotification.ts +5 -0
  475. package/src/codex-protocol/v2/ThreadCompactStartParams.ts +5 -0
  476. package/src/codex-protocol/v2/ThreadCompactStartResponse.ts +5 -0
  477. package/src/codex-protocol/v2/ThreadDecrementElicitationParams.ts +12 -0
  478. package/src/codex-protocol/v2/ThreadDecrementElicitationResponse.ts +16 -0
  479. package/src/codex-protocol/v2/ThreadForkParams.ts +60 -0
  480. package/src/codex-protocol/v2/ThreadForkResponse.ts +35 -0
  481. package/src/codex-protocol/v2/ThreadGoal.ts +6 -0
  482. package/src/codex-protocol/v2/ThreadGoalClearParams.ts +5 -0
  483. package/src/codex-protocol/v2/ThreadGoalClearResponse.ts +5 -0
  484. package/src/codex-protocol/v2/ThreadGoalClearedNotification.ts +5 -0
  485. package/src/codex-protocol/v2/ThreadGoalGetParams.ts +5 -0
  486. package/src/codex-protocol/v2/ThreadGoalGetResponse.ts +6 -0
  487. package/src/codex-protocol/v2/ThreadGoalSetParams.ts +6 -0
  488. package/src/codex-protocol/v2/ThreadGoalSetResponse.ts +6 -0
  489. package/src/codex-protocol/v2/ThreadGoalStatus.ts +5 -0
  490. package/src/codex-protocol/v2/ThreadGoalUpdatedNotification.ts +6 -0
  491. package/src/codex-protocol/v2/ThreadIncrementElicitationParams.ts +12 -0
  492. package/src/codex-protocol/v2/ThreadIncrementElicitationResponse.ts +16 -0
  493. package/src/codex-protocol/v2/ThreadInjectItemsParams.ts +10 -0
  494. package/src/codex-protocol/v2/ThreadInjectItemsResponse.ts +5 -0
  495. package/src/codex-protocol/v2/ThreadItem.ts +101 -0
  496. package/src/codex-protocol/v2/ThreadListParams.ts +54 -0
  497. package/src/codex-protocol/v2/ThreadListResponse.ts +18 -0
  498. package/src/codex-protocol/v2/ThreadLoadedListParams.ts +13 -0
  499. package/src/codex-protocol/v2/ThreadLoadedListResponse.ts +14 -0
  500. package/src/codex-protocol/v2/ThreadMemoryModeSetParams.ts +6 -0
  501. package/src/codex-protocol/v2/ThreadMemoryModeSetResponse.ts +5 -0
  502. package/src/codex-protocol/v2/ThreadMetadataGitInfoUpdateParams.ts +20 -0
  503. package/src/codex-protocol/v2/ThreadMetadataUpdateParams.ts +12 -0
  504. package/src/codex-protocol/v2/ThreadMetadataUpdateResponse.ts +6 -0
  505. package/src/codex-protocol/v2/ThreadNameUpdatedNotification.ts +5 -0
  506. package/src/codex-protocol/v2/ThreadReadParams.ts +9 -0
  507. package/src/codex-protocol/v2/ThreadReadResponse.ts +6 -0
  508. package/src/codex-protocol/v2/ThreadRealtimeAppendAudioParams.ts +9 -0
  509. package/src/codex-protocol/v2/ThreadRealtimeAppendAudioResponse.ts +8 -0
  510. package/src/codex-protocol/v2/ThreadRealtimeAppendTextParams.ts +8 -0
  511. package/src/codex-protocol/v2/ThreadRealtimeAppendTextResponse.ts +8 -0
  512. package/src/codex-protocol/v2/ThreadRealtimeAudioChunk.ts +8 -0
  513. package/src/codex-protocol/v2/ThreadRealtimeClosedNotification.ts +8 -0
  514. package/src/codex-protocol/v2/ThreadRealtimeErrorNotification.ts +8 -0
  515. package/src/codex-protocol/v2/ThreadRealtimeItemAddedNotification.ts +9 -0
  516. package/src/codex-protocol/v2/ThreadRealtimeListVoicesParams.ts +8 -0
  517. package/src/codex-protocol/v2/ThreadRealtimeListVoicesResponse.ts +9 -0
  518. package/src/codex-protocol/v2/ThreadRealtimeOutputAudioDeltaNotification.ts +9 -0
  519. package/src/codex-protocol/v2/ThreadRealtimeSdpNotification.ts +8 -0
  520. package/src/codex-protocol/v2/ThreadRealtimeStartParams.ts +16 -0
  521. package/src/codex-protocol/v2/ThreadRealtimeStartResponse.ts +8 -0
  522. package/src/codex-protocol/v2/ThreadRealtimeStartTransport.ts +13 -0
  523. package/src/codex-protocol/v2/ThreadRealtimeStartedNotification.ts +9 -0
  524. package/src/codex-protocol/v2/ThreadRealtimeStopParams.ts +8 -0
  525. package/src/codex-protocol/v2/ThreadRealtimeStopResponse.ts +8 -0
  526. package/src/codex-protocol/v2/ThreadRealtimeTranscriptDeltaNotification.ts +13 -0
  527. package/src/codex-protocol/v2/ThreadRealtimeTranscriptDoneNotification.ts +13 -0
  528. package/src/codex-protocol/v2/ThreadResumeParams.ts +71 -0
  529. package/src/codex-protocol/v2/ThreadResumeResponse.ts +35 -0
  530. package/src/codex-protocol/v2/ThreadRollbackParams.ts +12 -0
  531. package/src/codex-protocol/v2/ThreadRollbackResponse.ts +14 -0
  532. package/src/codex-protocol/v2/ThreadSetNameParams.ts +5 -0
  533. package/src/codex-protocol/v2/ThreadSetNameResponse.ts +5 -0
  534. package/src/codex-protocol/v2/ThreadSettings.ts +14 -0
  535. package/src/codex-protocol/v2/ThreadSettingsUpdateParams.ts +61 -0
  536. package/src/codex-protocol/v2/ThreadSettingsUpdateResponse.ts +5 -0
  537. package/src/codex-protocol/v2/ThreadSettingsUpdatedNotification.ts +6 -0
  538. package/src/codex-protocol/v2/ThreadShellCommandParams.ts +12 -0
  539. package/src/codex-protocol/v2/ThreadShellCommandResponse.ts +5 -0
  540. package/src/codex-protocol/v2/ThreadSortKey.ts +5 -0
  541. package/src/codex-protocol/v2/ThreadSource.ts +5 -0
  542. package/src/codex-protocol/v2/ThreadSourceKind.ts +5 -0
  543. package/src/codex-protocol/v2/ThreadStartParams.ts +57 -0
  544. package/src/codex-protocol/v2/ThreadStartResponse.ts +35 -0
  545. package/src/codex-protocol/v2/ThreadStartSource.ts +5 -0
  546. package/src/codex-protocol/v2/ThreadStartedNotification.ts +6 -0
  547. package/src/codex-protocol/v2/ThreadStatus.ts +6 -0
  548. package/src/codex-protocol/v2/ThreadStatusChangedNotification.ts +6 -0
  549. package/src/codex-protocol/v2/ThreadTokenUsage.ts +6 -0
  550. package/src/codex-protocol/v2/ThreadTokenUsageUpdatedNotification.ts +6 -0
  551. package/src/codex-protocol/v2/ThreadTurnsItemsListParams.ts +18 -0
  552. package/src/codex-protocol/v2/ThreadTurnsItemsListResponse.ts +16 -0
  553. package/src/codex-protocol/v2/ThreadTurnsListParams.ts +23 -0
  554. package/src/codex-protocol/v2/ThreadTurnsListResponse.ts +18 -0
  555. package/src/codex-protocol/v2/ThreadUnarchiveParams.ts +5 -0
  556. package/src/codex-protocol/v2/ThreadUnarchiveResponse.ts +6 -0
  557. package/src/codex-protocol/v2/ThreadUnarchivedNotification.ts +5 -0
  558. package/src/codex-protocol/v2/ThreadUnsubscribeParams.ts +5 -0
  559. package/src/codex-protocol/v2/ThreadUnsubscribeResponse.ts +6 -0
  560. package/src/codex-protocol/v2/ThreadUnsubscribeStatus.ts +5 -0
  561. package/src/codex-protocol/v2/TokenUsageBreakdown.ts +5 -0
  562. package/src/codex-protocol/v2/ToolRequestUserInputAnswer.ts +8 -0
  563. package/src/codex-protocol/v2/ToolRequestUserInputOption.ts +8 -0
  564. package/src/codex-protocol/v2/ToolRequestUserInputParams.ts +9 -0
  565. package/src/codex-protocol/v2/ToolRequestUserInputQuestion.ts +9 -0
  566. package/src/codex-protocol/v2/ToolRequestUserInputResponse.ts +9 -0
  567. package/src/codex-protocol/v2/ToolsV2.ts +6 -0
  568. package/src/codex-protocol/v2/Turn.ts +33 -0
  569. package/src/codex-protocol/v2/TurnCompletedNotification.ts +6 -0
  570. package/src/codex-protocol/v2/TurnDiffUpdatedNotification.ts +9 -0
  571. package/src/codex-protocol/v2/TurnEnvironmentParams.ts +6 -0
  572. package/src/codex-protocol/v2/TurnError.ts +6 -0
  573. package/src/codex-protocol/v2/TurnInterruptParams.ts +5 -0
  574. package/src/codex-protocol/v2/TurnInterruptResponse.ts +5 -0
  575. package/src/codex-protocol/v2/TurnItemsView.ts +5 -0
  576. package/src/codex-protocol/v2/TurnPlanStep.ts +6 -0
  577. package/src/codex-protocol/v2/TurnPlanStepStatus.ts +5 -0
  578. package/src/codex-protocol/v2/TurnPlanUpdatedNotification.ts +6 -0
  579. package/src/codex-protocol/v2/TurnStartParams.ts +88 -0
  580. package/src/codex-protocol/v2/TurnStartResponse.ts +6 -0
  581. package/src/codex-protocol/v2/TurnStartedNotification.ts +6 -0
  582. package/src/codex-protocol/v2/TurnStatus.ts +5 -0
  583. package/src/codex-protocol/v2/TurnSteerParams.ts +15 -0
  584. package/src/codex-protocol/v2/TurnSteerResponse.ts +5 -0
  585. package/src/codex-protocol/v2/UserInput.ts +11 -0
  586. package/src/codex-protocol/v2/WarningNotification.ts +13 -0
  587. package/src/codex-protocol/v2/WebSearchAction.ts +5 -0
  588. package/src/codex-protocol/v2/WindowsSandboxReadiness.ts +5 -0
  589. package/src/codex-protocol/v2/WindowsSandboxReadinessResponse.ts +6 -0
  590. package/src/codex-protocol/v2/WindowsSandboxSetupCompletedNotification.ts +6 -0
  591. package/src/codex-protocol/v2/WindowsSandboxSetupMode.ts +5 -0
  592. package/src/codex-protocol/v2/WindowsSandboxSetupStartParams.ts +7 -0
  593. package/src/codex-protocol/v2/WindowsSandboxSetupStartResponse.ts +5 -0
  594. package/src/codex-protocol/v2/WindowsWorldWritableWarningNotification.ts +5 -0
  595. package/src/codex-protocol/v2/WriteStatus.ts +5 -0
  596. package/src/codex-protocol/v2/index.ts +503 -0
  597. package/src/column.ts +44 -0
  598. package/src/engines/claude/claude-engine.ts +769 -0
  599. package/src/engines/claude/clock.ts +48 -0
  600. package/src/engines/claude/compact.ts +107 -0
  601. package/src/engines/claude/ctx.ts +239 -0
  602. package/src/engines/claude/doctor.ts +202 -0
  603. package/src/engines/claude/env.ts +16 -0
  604. package/src/engines/claude/history.ts +504 -0
  605. package/src/engines/claude/identifiers.ts +25 -0
  606. package/src/engines/claude/identity-migration.ts +16 -0
  607. package/src/engines/claude/idle.ts +91 -0
  608. package/src/engines/claude/keys.ts +163 -0
  609. package/src/engines/claude/last.ts +52 -0
  610. package/src/engines/claude/mem.ts +124 -0
  611. package/src/engines/claude/persistence.ts +41 -0
  612. package/src/engines/claude/post-turn.ts +45 -0
  613. package/src/engines/claude/reload.ts +53 -0
  614. package/src/engines/claude/repo-fs.ts +63 -0
  615. package/src/engines/claude/resume.ts +145 -0
  616. package/src/engines/claude/send.ts +86 -0
  617. package/src/engines/claude/spawn.ts +435 -0
  618. package/src/engines/claude/state.ts +124 -0
  619. package/src/engines/claude/tmux.ts +99 -0
  620. package/src/engines/claude/wait-signals.ts +128 -0
  621. package/src/engines/claude/wait.ts +59 -0
  622. package/src/engines/codex/ask.ts +69 -0
  623. package/src/engines/codex/engine.ts +1261 -0
  624. package/src/engines/codex/events.ts +106 -0
  625. package/src/engines/codex/history.ts +385 -0
  626. package/src/engines/codex/identity-migration.ts +14 -0
  627. package/src/engines/codex/ipc-bridge-process.ts +14 -0
  628. package/src/engines/codex/ipc-bridge.ts +844 -0
  629. package/src/engines/codex/persistence.ts +236 -0
  630. package/src/engines/codex/rollout.ts +384 -0
  631. package/src/engines/codex/rpc.ts +311 -0
  632. package/src/engines/codex/supervisor.ts +648 -0
  633. package/src/engines/codex/ui-ipc.ts +374 -0
  634. package/src/engines/codex/verb-common.ts +34 -0
  635. package/src/engines/codex/verb-lifecycle.ts +94 -0
  636. package/src/engines/codex/verb-state.ts +19 -0
  637. package/src/engines/codex/verb-turns.ts +49 -0
  638. package/src/engines/codex/verbs.ts +15 -0
  639. package/src/engines/engine.ts +91 -0
  640. package/src/engines/git-worktree.ts +137 -0
  641. package/src/engines/production.ts +19 -0
  642. package/src/engines/registry.ts +70 -0
  643. package/src/engines/teammate-record.ts +113 -0
  644. package/src/engines/types.ts +334 -0
  645. package/src/env.ts +29 -0
  646. package/src/grep.ts +39 -0
  647. package/src/help.ts +433 -0
  648. package/src/identity/name.ts +58 -0
  649. package/src/identity/router.ts +80 -0
  650. package/src/identity/uuid-prefix.ts +40 -0
  651. package/src/main.ts +39 -0
  652. package/src/persistence/atomic-file.ts +74 -0
  653. package/src/persistence/identity-store.ts +294 -0
  654. package/src/persistence/identity-writer.ts +28 -0
  655. package/src/persistence/paths.ts +138 -0
  656. package/src/plugin-root.ts +26 -0
  657. package/src/proc.ts +66 -0
  658. package/src/shared/verb-args.ts +331 -0
  659. package/src/tm.ts +54 -0
  660. package/src/tmux.ts +57 -0
  661. package/src/verbs/archive.ts +211 -0
  662. package/src/verbs/ask.ts +29 -0
  663. package/src/verbs/compact.ts +25 -0
  664. package/src/verbs/context.ts +68 -0
  665. package/src/verbs/ctx.ts +21 -0
  666. package/src/verbs/format.ts +213 -0
  667. package/src/verbs/history.ts +190 -0
  668. package/src/verbs/kill.ts +61 -0
  669. package/src/verbs/last.ts +34 -0
  670. package/src/verbs/ls.ts +27 -0
  671. package/src/verbs/mem.ts +40 -0
  672. package/src/verbs/poll.ts +61 -0
  673. package/src/verbs/reload.ts +17 -0
  674. package/src/verbs/resolve.ts +14 -0
  675. package/src/verbs/resume.ts +170 -0
  676. package/src/verbs/send.ts +36 -0
  677. package/src/verbs/spawn.ts +81 -0
  678. package/src/verbs/states.ts +74 -0
  679. package/src/verbs/status.ts +26 -0
  680. package/src/verbs/wait.ts +40 -0
  681. package/src/verbs.ts +56 -0
  682. package/src/ws-types.d.ts +9 -0
  683. package/third_party/ws/LICENSE +20 -0
  684. package/third_party/ws/README.md +548 -0
  685. package/third_party/ws/UPSTREAM.md +55 -0
  686. package/third_party/ws/browser.js +8 -0
  687. package/third_party/ws/index.js +22 -0
  688. package/third_party/ws/lib/buffer-util.js +131 -0
  689. package/third_party/ws/lib/constants.js +19 -0
  690. package/third_party/ws/lib/event-target.js +292 -0
  691. package/third_party/ws/lib/extension.js +203 -0
  692. package/third_party/ws/lib/limiter.js +55 -0
  693. package/third_party/ws/lib/permessage-deflate.js +528 -0
  694. package/third_party/ws/lib/receiver.js +760 -0
  695. package/third_party/ws/lib/sender.js +607 -0
  696. package/third_party/ws/lib/stream.js +161 -0
  697. package/third_party/ws/lib/subprotocol.js +62 -0
  698. package/third_party/ws/lib/validation.js +152 -0
  699. package/third_party/ws/lib/websocket-server.js +562 -0
  700. package/third_party/ws/lib/websocket.js +1407 -0
  701. package/third_party/ws/package.json +13 -0
  702. package/third_party/ws/wrapper.mjs +21 -0
@@ -0,0 +1,1261 @@
1
+ /**
2
+ * Codex Engine implementation.
3
+ *
4
+ * This is the Phase 2b migration target for the former root-level
5
+ * `codex-verbs.ts` logic. Codex keeps its JSON-RPC notification stream,
6
+ * daemon supervision, and `/tmp/teammate-codex/<name>/` registry private to
7
+ * this directory; the public surface is the shared `Engine` interface.
8
+ */
9
+
10
+ import { Buffer } from 'node:buffer'
11
+ import { existsSync } from 'node:fs'
12
+
13
+ import type { Engine } from '../engine'
14
+ import type {
15
+ CompactRequest,
16
+ CompactResult,
17
+ DoctorFinding,
18
+ ContextRequest,
19
+ ContextResult,
20
+ DoctorSection,
21
+ EngineCapabilities,
22
+ EngineContext,
23
+ EngineKind,
24
+ EngineSnapshot,
25
+ HistoryRequest,
26
+ HistoryResult,
27
+ InspectRequest,
28
+ InteractionItem,
29
+ KillRequest,
30
+ KillResult,
31
+ LastRequest,
32
+ MemoryRequest,
33
+ ReloadRequest,
34
+ ReloadResult,
35
+ ResumeRequest,
36
+ ResumeResult,
37
+ SendRequest,
38
+ SpawnRequest,
39
+ SpawnResult,
40
+ StatusRequest,
41
+ TeammateListing,
42
+ TeammateStatus,
43
+ TextResult,
44
+ TurnResult,
45
+ WaitRequest,
46
+ } from '../types'
47
+ import type { ClientInfo, InitializeResponse } from '../../codex-protocol/index.js'
48
+ import type { Turn } from '../../codex-protocol/v2/Turn.js'
49
+ import type { TurnItemsView } from '../../codex-protocol/v2/TurnItemsView.js'
50
+ import type { ThreadItem } from '../../codex-protocol/v2/ThreadItem.js'
51
+ import type { ThreadListResponse } from '../../codex-protocol/v2/ThreadListResponse.js'
52
+ import type { ThreadReadResponse } from '../../codex-protocol/v2/ThreadReadResponse.js'
53
+ import type { ThreadResumeResponse } from '../../codex-protocol/v2/ThreadResumeResponse.js'
54
+ import type { ThreadStartResponse } from '../../codex-protocol/v2/ThreadStartResponse.js'
55
+ import type { ThreadTokenUsage } from '../../codex-protocol/v2/ThreadTokenUsage.js'
56
+ import { EXIT_SYNC_WAIT_EXPIRED, type TmResult } from '../../tm'
57
+ import type { CollectedTurn, TurnCompletedNotification } from './events.js'
58
+ import { codexHistory } from './history.js'
59
+ import { CodexWsClient } from './rpc.js'
60
+ import { runTurn, subscribeTurnCollection } from './events.js'
61
+ import {
62
+ CodexDaemonAlreadyAliveError,
63
+ CodexDaemonSpawnInProgressError,
64
+ daemonAlive,
65
+ daemonBorrowed,
66
+ daemonSpawnInProgress,
67
+ ensureCodexIpcBridge,
68
+ isProcessAlive,
69
+ listDaemons,
70
+ readDaemonState,
71
+ reapDaemon,
72
+ releaseDaemonBorrow,
73
+ spawnDaemon,
74
+ touchLastSeen,
75
+ tryBorrowDaemon,
76
+ writeThreadId,
77
+ } from './supervisor.js'
78
+ import {
79
+ CodexTeammateRecord,
80
+ codexLastTurnFile,
81
+ readBaseRecord,
82
+ readCodexMeta,
83
+ readCodexLastTurn,
84
+ removeBaseRecord,
85
+ reserveBaseRecord,
86
+ writeCodexLastTurn,
87
+ } from './persistence.js'
88
+ import {
89
+ type CodexRolloutSnapshot,
90
+ CODEX_ROLLOUT_BUSY_WINDOW_MS,
91
+ readCodexRolloutSnapshot,
92
+ rolloutRecentlyActive,
93
+ } from './rollout.js'
94
+ import { validateTeammateName } from '../../identity/name.js'
95
+ import { looksLikeUuidPrefix } from '../../identity/uuid-prefix.js'
96
+ import { provisionCodexWorktree, reapCodexWorktree } from '../git-worktree.js'
97
+
98
+ export const CODEX_CLIENT_INFO: ClientInfo = {
99
+ name: 'claudemux',
100
+ title: null,
101
+ version: '1.0.0',
102
+ }
103
+
104
+ const COMPACT_REASON =
105
+ 'codex compacts its own context automatically when the 252k window fills'
106
+ const CODEX_STATUS_RPC_TIMEOUT_MS = 250
107
+ const CODEX_THREAD_ID_RE =
108
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
109
+ const NO_TEXT_REPLY =
110
+ '(no text reply this turn — tool-only, /compact, /clear, or fresh spawn)'
111
+
112
+ export interface CodexEngineOptions {
113
+ readonly binPath?: string
114
+ readonly readyTimeoutMs?: number
115
+ }
116
+
117
+ function notSupported(reason: string): TextResult {
118
+ return { kind: 'not-supported', reason }
119
+ }
120
+
121
+ function itemToInteractions(item: ThreadItem): readonly InteractionItem[] {
122
+ if (item.type === 'agentMessage') {
123
+ return [{ kind: 'assistant-text', text: item.text }]
124
+ }
125
+ if (item.type === 'commandExecution') {
126
+ return [
127
+ { kind: 'tool-call', tool: 'commandExecution', argsJson: item.command },
128
+ {
129
+ kind: 'tool-result',
130
+ tool: 'commandExecution',
131
+ ok: item.exitCode === 0,
132
+ textOrJson: item.aggregatedOutput ?? '',
133
+ },
134
+ ]
135
+ }
136
+ if (item.type === 'mcpToolCall') {
137
+ return [
138
+ { kind: 'tool-call', tool: item.tool, argsJson: JSON.stringify(item.arguments) },
139
+ {
140
+ kind: 'tool-result',
141
+ tool: item.tool,
142
+ ok: item.error === null,
143
+ textOrJson: JSON.stringify(item.result ?? item.error ?? null),
144
+ },
145
+ ]
146
+ }
147
+ return [{ kind: 'system-note', text: JSON.stringify(item) }]
148
+ }
149
+
150
+ function finalAssistantText(items: readonly ThreadItem[]): string | null {
151
+ for (let i = items.length - 1; i >= 0; i -= 1) {
152
+ const item = items[i]
153
+ if (item?.type !== 'agentMessage') continue
154
+ if (item.text.length === 0) continue
155
+ return item.text
156
+ }
157
+ return null
158
+ }
159
+
160
+ function ensureTrailingNewline(text: string): string {
161
+ return text.endsWith('\n') ? text : `${text}\n`
162
+ }
163
+
164
+ function fmtTokenWindow(tokens: number): string {
165
+ if (tokens >= 1_000_000 && tokens % 1_000_000 === 0) return `${tokens / 1_000_000}M`
166
+ if (tokens >= 1000 && tokens % 1000 === 0) return `${tokens / 1000}k`
167
+ return String(tokens)
168
+ }
169
+
170
+ function contextFromThreadTokenUsage(tokenUsage: ThreadTokenUsage | null): ContextResult | null {
171
+ if (tokenUsage === null) return null
172
+ const window = tokenUsage.modelContextWindow
173
+ if (window === null || window <= 0) return null
174
+ const used = tokenUsage.last.totalTokens
175
+ return {
176
+ kind: 'usage',
177
+ tokensUsed: used,
178
+ tokensTotal: window,
179
+ pct: Math.floor((used * 100) / window),
180
+ }
181
+ }
182
+
183
+ function contextFromRollout(threadId: string, ctx: EngineContext): ContextResult | null {
184
+ const usage = readCodexRolloutSnapshot(threadId, ctx.env)?.tokenUsage ?? null
185
+ if (usage === null) return null
186
+ return {
187
+ kind: 'usage',
188
+ tokensUsed: usage.tokensUsed,
189
+ tokensTotal: usage.tokensTotal,
190
+ pct: usage.pct,
191
+ }
192
+ }
193
+
194
+ function contextForCollectedTurn(outcome: CollectedTurn, ctx: EngineContext): ContextResult | null {
195
+ return contextFromThreadTokenUsage(outcome.tokenUsage) ?? contextFromRollout(outcome.completed.threadId, ctx)
196
+ }
197
+
198
+ function formatCtxForStderr(context: ContextResult | null): string {
199
+ if (context?.kind !== 'usage') return 'ctx: (no usage data)\n'
200
+ return `ctx: ${context.tokensUsed} tokens · ${context.pct}% of ${fmtTokenWindow(context.tokensTotal)}\n`
201
+ }
202
+
203
+ function codexTurnStderr(args: {
204
+ readonly name: string
205
+ readonly action: 'sent' | 'waited'
206
+ readonly threadId: string
207
+ readonly context: ContextResult | null
208
+ readonly rawPath: string
209
+ }): string {
210
+ const prefix = args.action === 'sent' ? `sent to ${args.name}` : `waited on ${args.name}`
211
+ return (
212
+ `${prefix} (codex)\n` +
213
+ `sid=${args.threadId}\n` +
214
+ formatCtxForStderr(args.context) +
215
+ `raw: ${args.rawPath}\n`
216
+ )
217
+ }
218
+
219
+ function writeLastTurn(name: string, completed: TurnCompletedNotification): string {
220
+ const rawPath = codexLastTurnFile(name)
221
+ writeCodexLastTurn(name, ensureTrailingNewline(JSON.stringify(completed, null, 2)))
222
+ return rawPath
223
+ }
224
+
225
+ /**
226
+ * Pick the latest `Turn` from a `thread/read` snapshot that reached a
227
+ * terminal state AFTER the daemon's `lastSeen` marker — the candidate
228
+ * `tm wait` should surface as a backfill instead of subscribing to a
229
+ * future event the dispatcher would never see.
230
+ *
231
+ * Why this exists: `tm send` on Codex opens a WS, posts a turn, and
232
+ * closes on `--timeout` expiry (exit 124). The follow-up `tm wait` opens
233
+ * a fresh WS and `subscribeTurnCollection` only ever receives events
234
+ * that fire AFTER the subscription is in place — so a turn that finished
235
+ * in the window [send-timeout, wait-subscribe] is invisible to the
236
+ * notification stream alone. `tm wait` now calls `thread/read` with
237
+ * `includeTurns: true` alongside the subscription and races them; if
238
+ * `lastSeen` < some terminal turn, that turn becomes the resolved value
239
+ * and `tm wait` returns it.
240
+ *
241
+ * Filters:
242
+ * - `inProgress` is skipped — the live subscription will deliver it.
243
+ * Every OTHER status is terminal (the Codex protocol's `TurnStatus`
244
+ * union is `completed | failed | interrupted | inProgress`) and must
245
+ * be eligible for backfill: the dispatcher needs the late `failed` /
246
+ * `interrupted` outcome just as much as a late `completed`, or the
247
+ * next `tm wait` keeps spinning to 124 on a turn that already
248
+ * settled into an error state. `turnNotificationToResult` is the
249
+ * single mapping site that translates any terminal status to a
250
+ * `TurnResult`, so backfill and live paths cannot drift.
251
+ * - `completedAt === null` is defensive — a turn whose timestamp
252
+ * didn't survive serialization cannot be ordered against `lastSeen`.
253
+ * - `completedAt <= lastSeen` means the dispatcher already saw it.
254
+ *
255
+ * Picks the max `completedAt` among survivors — `thread.turns` ordering
256
+ * is not documented as ascending, so a scan is the contract-safe form.
257
+ */
258
+ export function pickBackfillTurn(
259
+ turns: readonly Turn[],
260
+ lastSeen: number,
261
+ threadId: string,
262
+ ): TurnCompletedNotification | null {
263
+ let best: Turn | null = null
264
+ let bestCompletedAt = 0
265
+ for (const turn of turns) {
266
+ if (turn.status === 'inProgress') continue
267
+ if (turn.completedAt === null) continue
268
+ if (turn.completedAt <= lastSeen) continue
269
+ if (best === null || turn.completedAt > bestCompletedAt) {
270
+ best = turn
271
+ bestCompletedAt = turn.completedAt
272
+ }
273
+ }
274
+ if (best === null) return null
275
+ // Match `subscribeTurnCollection`'s synthesis convention so downstream
276
+ // `turnNotificationToResult` reads the same shape regardless of source.
277
+ const itemsView: TurnItemsView = best.items.length > 0 ? 'full' : 'notLoaded'
278
+ return {
279
+ threadId,
280
+ turn: { ...best, itemsView },
281
+ }
282
+ }
283
+
284
+ export function turnNotificationToResult(
285
+ completed: TurnCompletedNotification,
286
+ options: {
287
+ readonly name?: string
288
+ readonly action?: 'sent' | 'waited'
289
+ readonly context?: ContextResult | null
290
+ readonly rawPath?: string
291
+ } = {},
292
+ ): TurnResult {
293
+ const items = completed.turn.items.flatMap((item) => itemToInteractions(item))
294
+ if (completed.turn.status === 'failed') {
295
+ return {
296
+ kind: 'failed',
297
+ message: completed.turn.error?.message ?? 'codex turn failed',
298
+ recoverable: false,
299
+ }
300
+ }
301
+ if (completed.turn.status === 'interrupted') {
302
+ return {
303
+ kind: 'failed',
304
+ message: 'codex turn was interrupted',
305
+ recoverable: true,
306
+ }
307
+ }
308
+ const text = ensureTrailingNewline(finalAssistantText(completed.turn.items) ?? NO_TEXT_REPLY)
309
+ const context = options.context ?? null
310
+ const base = { kind: 'completed' as const, text, items, context }
311
+ if (options.name === undefined || options.action === undefined || options.rawPath === undefined) {
312
+ return base
313
+ }
314
+ return {
315
+ ...base,
316
+ tmResult: {
317
+ code: 0,
318
+ stdout: text,
319
+ stderr: codexTurnStderr({
320
+ name: options.name,
321
+ action: options.action,
322
+ threadId: completed.threadId,
323
+ context,
324
+ rawPath: options.rawPath,
325
+ }),
326
+ },
327
+ }
328
+ }
329
+
330
+ async function withTimeout<T>(
331
+ promise: Promise<T>,
332
+ timeoutMs: number | null,
333
+ ): Promise<T | { timedOut: true }> {
334
+ if (timeoutMs === null) return promise
335
+ let timer: ReturnType<typeof setTimeout> | null = null
336
+ try {
337
+ return await Promise.race([
338
+ promise,
339
+ new Promise<{ timedOut: true }>((resolve) => {
340
+ timer = setTimeout(() => resolve({ timedOut: true }), timeoutMs)
341
+ }),
342
+ ])
343
+ } finally {
344
+ if (timer !== null) clearTimeout(timer)
345
+ }
346
+ }
347
+
348
+ function isTimedOut<T>(value: T | { timedOut: true }): value is { timedOut: true } {
349
+ return (
350
+ typeof value === 'object' &&
351
+ value !== null &&
352
+ (value as { timedOut?: unknown }).timedOut === true
353
+ )
354
+ }
355
+
356
+ function closeClientWhenSettled(clientPromise: Promise<CodexWsClient>): void {
357
+ clientPromise.then(
358
+ (lateClient) => lateClient.close(),
359
+ () => {},
360
+ )
361
+ }
362
+
363
+ function codexNameFailure(name: string): string | null {
364
+ const validation = validateTeammateName(name)
365
+ return validation.kind === 'ok'
366
+ ? null
367
+ : `invalid codex teammate name '${name}': ${validation.reason}`
368
+ }
369
+
370
+ function codexThreadIdFailure(threadId: string, name: string | null = null): string | null {
371
+ if (CODEX_THREAD_ID_RE.test(threadId)) return null
372
+ if (name !== null && looksLikeUuidPrefix(threadId)) {
373
+ return (
374
+ `received '${threadId}', looks like a thread-id prefix; resume ` +
375
+ `requires the full thread id. Run 'tm history ${name} ${threadId}' to ` +
376
+ `expand it, or 'tm history ${name}' to list past threads with full ids.`
377
+ )
378
+ }
379
+ return `codex thread id is not a valid uuid: ${threadId}`
380
+ }
381
+
382
+ async function latestCodexThreadIdForCwd(
383
+ client: CodexWsClient,
384
+ cwd: string,
385
+ ): Promise<string | null> {
386
+ const response = await client.request<'thread/list', ThreadListResponse>('thread/list', {
387
+ limit: 1,
388
+ sortKey: 'updated_at',
389
+ sortDirection: 'desc',
390
+ archived: false,
391
+ cwd,
392
+ useStateDbOnly: false,
393
+ })
394
+ return response.data[0]?.id ?? null
395
+ }
396
+
397
+ function codexSpawnHeader(name: string): string {
398
+ const state = readDaemonState(name)
399
+ return state === null
400
+ ? `spawned: ${name}\n`
401
+ : `spawned: ${name} (pid=${state.pid}, socket=${state.socketPath})\n`
402
+ }
403
+
404
+ function codexResumeHeader(name: string): string {
405
+ const state = readDaemonState(name)
406
+ return state === null
407
+ ? `resumed: ${name}\n`
408
+ : `resumed: ${name} (pid=${state.pid}, socket=${state.socketPath})\n`
409
+ }
410
+
411
+ function formatFirstTurn(turn: TurnResult): TmResult {
412
+ if (turn.tmResult !== undefined) return turn.tmResult
413
+ switch (turn.kind) {
414
+ case 'completed':
415
+ return { code: 0, stdout: turn.text.endsWith('\n') ? turn.text : `${turn.text}\n`, stderr: '' }
416
+ case 'failed':
417
+ return { code: 1, stdout: '', stderr: `tm: turn failed: ${turn.message}\n` }
418
+ case 'timed-out':
419
+ return {
420
+ code: EXIT_SYNC_WAIT_EXPIRED,
421
+ stdout: '',
422
+ stderr:
423
+ `tm: sync wait expired after ${turn.elapsedMs}ms (the codex daemon ` +
424
+ `did not return a Turn within the window; it is still running). ` +
425
+ `exit ${EXIT_SYNC_WAIT_EXPIRED}.\n`,
426
+ }
427
+ case 'not-supported':
428
+ return { code: 0, stdout: '', stderr: ` not supported: ${turn.reason}\n` }
429
+ case 'no-op':
430
+ return { code: 0, stdout: '', stderr: ` no-op: ${turn.reason}\n` }
431
+ }
432
+ }
433
+
434
+ function fmtAge(age: number): string {
435
+ if (age < 60) return `${age}s`
436
+ if (age < 3600) return `${Math.floor(age / 60)}m`
437
+ if (age < 86400) return `${Math.floor(age / 3600)}h`
438
+ return `${Math.floor(age / 86400)}d`
439
+ }
440
+
441
+ interface CodexRuntimeProbe {
442
+ readonly socketReachable: 'yes' | 'no' | 'unknown'
443
+ readonly threadStatus: string | null
444
+ readonly threadState: 'idle' | 'busy' | 'unknown' | null
445
+ }
446
+
447
+ function statusState(statusType: string | null): CodexRuntimeProbe['threadState'] {
448
+ switch (statusType) {
449
+ case 'active':
450
+ return 'busy'
451
+ case 'idle':
452
+ case 'notLoaded':
453
+ return 'idle'
454
+ case 'systemError':
455
+ return 'unknown'
456
+ default:
457
+ return null
458
+ }
459
+ }
460
+
461
+ function codexDaemonState(
462
+ name: string,
463
+ state: ReturnType<typeof readDaemonState> = readDaemonState(name),
464
+ runtime: CodexRuntimeProbe | null = null,
465
+ rollout: CodexRolloutSnapshot | null = null,
466
+ nowMs = Date.now(),
467
+ ): 'idle' | 'busy' | 'unknown' {
468
+ if (state === null || !isProcessAlive(state.pid)) return 'unknown'
469
+ if (runtime?.threadState === 'busy') return 'busy'
470
+ if (daemonBorrowed(name)) return 'busy'
471
+ if (rolloutRecentlyActive(rollout, nowMs)) return 'busy'
472
+ if (runtime?.threadState === 'idle') return 'idle'
473
+ if (runtime?.threadState === 'unknown' || runtime?.socketReachable === 'no') return 'unknown'
474
+ return 'idle'
475
+ }
476
+
477
+ function codexPreview(text: string): string {
478
+ const preview = [...(text.split('\n')[0] ?? '')]
479
+ .filter((ch) => (ch.codePointAt(0) ?? 0) > 0x1f)
480
+ .slice(0, 50)
481
+ .join('')
482
+ return preview.length > 0 ? preview : '(no first line)'
483
+ }
484
+
485
+ function codexLastTextCells(
486
+ rollout: CodexRolloutSnapshot | null,
487
+ nowSec: number,
488
+ ): { readonly last: string; readonly preview: string } | null {
489
+ if (rollout?.lastAssistantText === null || rollout?.lastAssistantText === undefined) return null
490
+ const assistantAtMs = rollout.lastAssistantAtMs ?? rollout.mtimeMs
491
+ const age = Math.max(0, nowSec - Math.floor(assistantAtMs / 1000))
492
+ return {
493
+ last: `${Buffer.byteLength(rollout.lastAssistantText, 'utf8')}B/${fmtAge(age)}`,
494
+ preview: codexPreview(rollout.lastAssistantText),
495
+ }
496
+ }
497
+
498
+ function codexListExtras(
499
+ nowSec: number,
500
+ state: ReturnType<typeof readDaemonState>,
501
+ daemonState: 'idle' | 'busy' | 'unknown',
502
+ rollout: CodexRolloutSnapshot | null,
503
+ runtime: CodexRuntimeProbe | null,
504
+ ): Readonly<Record<string, string>> {
505
+ const pid = state?.pid === undefined ? '' : String(state.pid)
506
+ const thread = state?.threadId ?? ''
507
+ const rolloutSeen = rollout === null ? null : Math.floor(rollout.mtimeMs / 1000)
508
+ const lastText = codexLastTextCells(rollout, nowSec)
509
+ const recordedSeen = state?.lastSeen ?? null
510
+ const activitySeen =
511
+ recordedSeen === null ? rolloutSeen : rolloutSeen === null ? recordedSeen : Math.max(recordedSeen, rolloutSeen)
512
+ const lastSeen = activitySeen === null ? '' : String(activitySeen)
513
+ return {
514
+ sidShort: thread.length === 0 ? 'codex' : thread.slice(0, 8),
515
+ busy: daemonState === 'busy' ? 'yes' : daemonState === 'idle' ? 'no' : '?',
516
+ last: lastText?.last ?? '-',
517
+ preview: lastText?.preview ?? '-',
518
+ pid,
519
+ socket: state?.socketPath ?? '',
520
+ socketReachable: runtime?.socketReachable ?? 'unknown',
521
+ thread,
522
+ lastSeen,
523
+ rollout: rollout?.path ?? '',
524
+ threadStatus: runtime?.threadStatus ?? '',
525
+ }
526
+ }
527
+
528
+ function statusPane(args: {
529
+ readonly name: string
530
+ readonly state: ReturnType<typeof readDaemonState>
531
+ readonly base: ReturnType<typeof readBaseRecord>
532
+ readonly meta: ReturnType<typeof readCodexMeta>
533
+ readonly daemonState: 'idle' | 'busy' | 'unknown'
534
+ readonly rollout: CodexRolloutSnapshot | null
535
+ readonly runtime: CodexRuntimeProbe | null
536
+ readonly nowSec: number
537
+ }): string {
538
+ const activitySeen =
539
+ args.rollout === null
540
+ ? args.state?.lastSeen ?? null
541
+ : Math.max(args.state?.lastSeen ?? 0, Math.floor(args.rollout.mtimeMs / 1000))
542
+ const activityAge = activitySeen === null ? '-' : fmtAge(Math.max(0, args.nowSec - activitySeen))
543
+ return [
544
+ `codex: ${args.name}`,
545
+ `state: ${args.daemonState}`,
546
+ `cwd: ${args.base?.cwd ?? args.meta?.cwd ?? ''}`,
547
+ `pid: ${args.state?.pid === undefined ? '-' : String(args.state.pid)}`,
548
+ `socket: ${args.state?.socketPath ?? '-'}`,
549
+ `socket reachable: ${args.runtime?.socketReachable ?? 'unknown'}`,
550
+ `thread: ${args.state?.threadId ?? '-'}`,
551
+ `thread status: ${args.runtime?.threadStatus ?? '-'}`,
552
+ `started: ${args.state?.startedAt === undefined ? '-' : String(args.state.startedAt)}`,
553
+ `last activity: ${activitySeen === null ? '-' : `${activitySeen} (${activityAge} ago)`}`,
554
+ `rollout: ${args.rollout?.path ?? '-'}`,
555
+ ].join('\n') + '\n'
556
+ }
557
+
558
+ export class CodexEngine implements Engine {
559
+ readonly kind: EngineKind = 'codex'
560
+ readonly capabilities: EngineCapabilities = {
561
+ atomicSend: true,
562
+ atomicSpawnPrompt: true,
563
+ compaction: 'auto',
564
+ contextUsage: 'transcript-jsonl',
565
+ history: 'transcript-files',
566
+ memory: 'unsupported',
567
+ reload: 'unsupported',
568
+ resume: 'thread-id',
569
+ detachedTurn: 'unsupported',
570
+ events: 'push',
571
+ }
572
+
573
+ constructor(private readonly options: CodexEngineOptions = {}) {}
574
+
575
+ async spawn(req: SpawnRequest, ctx: EngineContext): Promise<SpawnResult> {
576
+ const invalidName = codexNameFailure(req.name)
577
+ if (invalidName !== null) return { kind: 'failed', message: invalidName }
578
+ if (req.resumeCheckpoint !== null) {
579
+ return { kind: 'failed', message: '--resume is not supported for codex teammates' }
580
+ }
581
+
582
+ const existing = readBaseRecord(req.name)
583
+ if (existing !== null) {
584
+ if (existing.engine !== 'codex') return { kind: 'already-exists', existingEngine: existing.engine }
585
+ if (daemonAlive(req.name)) return { kind: 'already-exists', existingEngine: 'codex' }
586
+ if (daemonSpawnInProgress(req.name)) return { kind: 'already-exists', existingEngine: 'codex' }
587
+ removeBaseRecord(req.name)
588
+ }
589
+ if (daemonAlive(req.name)) return { kind: 'already-exists', existingEngine: 'codex' }
590
+
591
+ const createdAt = Math.floor(ctx.now() / 1000)
592
+ const record = new CodexTeammateRecord({
593
+ name: req.name,
594
+ repo: req.repo,
595
+ cwd: req.cwd,
596
+ worktreeSlug: req.worktreeSlug,
597
+ createdAt,
598
+ displayName: req.displayName,
599
+ })
600
+ const reserved = reserveBaseRecord(record)
601
+ if (reserved.kind === 'taken') {
602
+ return { kind: 'already-exists', existingEngine: reserved.existing.engine }
603
+ }
604
+ if (reserved.kind === 'failed') return { kind: 'failed', message: reserved.message }
605
+
606
+ if (req.worktreeSlug !== null) {
607
+ const worktreeError = await provisionCodexWorktree(req.repo, req.worktreeSlug)
608
+ if (worktreeError !== null) {
609
+ removeBaseRecord(req.name)
610
+ return { kind: 'failed', message: worktreeError }
611
+ }
612
+ }
613
+
614
+ try {
615
+ await spawnDaemon({
616
+ name: req.name,
617
+ binPath: this.options.binPath,
618
+ cwd: req.cwd,
619
+ env: ctx.env,
620
+ readyTimeoutMs: this.options.readyTimeoutMs,
621
+ meta: {
622
+ schema: 1,
623
+ name: req.name,
624
+ cwd: req.cwd,
625
+ displayName: req.displayName,
626
+ spawnedAt: createdAt,
627
+ },
628
+ })
629
+
630
+ await this.healthCheck(req.name)
631
+ ensureCodexIpcBridge(req.name, { cwd: req.cwd, env: ctx.env })
632
+
633
+ if (req.prompt === null) {
634
+ return {
635
+ kind: 'spawned',
636
+ name: req.name,
637
+ firstTurn: null,
638
+ tmResult: { code: 0, stdout: '', stderr: codexSpawnHeader(req.name) },
639
+ }
640
+ }
641
+ const firstTurn = await this.send(
642
+ { name: req.name, prompt: req.prompt, timeoutMs: req.timeoutMs, paneQuiet: false },
643
+ ctx,
644
+ )
645
+ const turn = formatFirstTurn(firstTurn)
646
+ return {
647
+ kind: 'spawned',
648
+ name: req.name,
649
+ firstTurn,
650
+ tmResult: {
651
+ code: turn.code,
652
+ stdout: turn.stdout,
653
+ stderr: codexSpawnHeader(req.name) + turn.stderr,
654
+ },
655
+ }
656
+ } catch (e) {
657
+ removeBaseRecord(req.name)
658
+ if (e instanceof CodexDaemonAlreadyAliveError) {
659
+ return { kind: 'already-exists', existingEngine: 'codex' }
660
+ }
661
+ if (!(e instanceof CodexDaemonSpawnInProgressError)) {
662
+ await reapDaemon(req.name)
663
+ }
664
+ return {
665
+ kind: 'failed',
666
+ message: e instanceof Error ? e.message : String(e),
667
+ }
668
+ }
669
+ }
670
+
671
+ async send(req: SendRequest, ctx: EngineContext): Promise<TurnResult> {
672
+ const invalidName = codexNameFailure(req.name)
673
+ if (invalidName !== null) {
674
+ return { kind: 'failed', message: invalidName, recoverable: false }
675
+ }
676
+ if (req.paneQuiet) {
677
+ return {
678
+ kind: 'failed',
679
+ message: 'tm send: --pane-quiet is not supported for codex teammates',
680
+ recoverable: false,
681
+ }
682
+ }
683
+ if (!daemonAlive(req.name)) {
684
+ return {
685
+ kind: 'failed',
686
+ message: `codex teammate '${req.name}' is not alive — try 'tm spawn ${req.name} --engine codex' first`,
687
+ recoverable: false,
688
+ }
689
+ }
690
+ ensureCodexIpcBridge(req.name, {
691
+ cwd: readBaseRecord(req.name)?.cwd ?? readCodexMeta(req.name)?.cwd ?? undefined,
692
+ env: ctx.env,
693
+ })
694
+ if (req.prompt.length === 0) {
695
+ return { kind: 'failed', message: 'usage: tm send <teammate> "<prompt>"', recoverable: false }
696
+ }
697
+ if (!tryBorrowDaemon(req.name)) {
698
+ return { kind: 'failed', message: `codex teammate '${req.name}' is busy`, recoverable: true }
699
+ }
700
+
701
+ let client: CodexWsClient | null = null
702
+ try {
703
+ client = await openInitializedCodexClient(req.name)
704
+ let threadId = readDaemonState(req.name)?.threadId ?? null
705
+ if (threadId === null) {
706
+ const resp = await client.request<'thread/start', ThreadStartResponse>('thread/start', {
707
+ experimentalRawEvents: false,
708
+ persistExtendedHistory: false,
709
+ })
710
+ threadId = resp.thread.id
711
+ writeThreadId(req.name, threadId)
712
+ } else {
713
+ await client.request<'thread/resume', ThreadResumeResponse>('thread/resume', {
714
+ threadId,
715
+ persistExtendedHistory: false,
716
+ })
717
+ }
718
+
719
+ const outcome = await withTimeout(
720
+ runTurn(client, threadId, req.prompt, { wait: true, cwd: null }),
721
+ req.timeoutMs,
722
+ )
723
+ if (isTimedOut(outcome)) return { kind: 'timed-out', elapsedMs: req.timeoutMs ?? 0 }
724
+ if (outcome === null) return { kind: 'no-op', reason: 'turn was started without waiting' }
725
+ const rawPath = writeLastTurn(req.name, outcome.completed)
726
+ touchLastSeen(req.name)
727
+ return turnNotificationToResult(outcome.completed, {
728
+ name: req.name,
729
+ action: 'sent',
730
+ context: contextForCollectedTurn(outcome, ctx),
731
+ rawPath,
732
+ })
733
+ } catch (e) {
734
+ return {
735
+ kind: 'failed',
736
+ message: `codex send on '${req.name}' failed: ${e instanceof Error ? e.message : String(e)}`,
737
+ recoverable: true,
738
+ }
739
+ } finally {
740
+ if (client !== null) client.close()
741
+ releaseDaemonBorrow(req.name)
742
+ }
743
+ }
744
+
745
+ async wait(req: WaitRequest, ctx: EngineContext): Promise<TurnResult> {
746
+ const invalidName = codexNameFailure(req.name)
747
+ if (invalidName !== null) {
748
+ return { kind: 'failed', message: invalidName, recoverable: false }
749
+ }
750
+ if (req.fresh) {
751
+ return {
752
+ kind: 'failed',
753
+ message: 'tm wait: --fresh is not supported for codex teammates',
754
+ recoverable: false,
755
+ }
756
+ }
757
+ if (req.paneQuiet) {
758
+ return {
759
+ kind: 'failed',
760
+ message: 'tm wait: --pane-quiet is not supported for codex teammates',
761
+ recoverable: false,
762
+ }
763
+ }
764
+ if (!daemonAlive(req.name)) {
765
+ return { kind: 'failed', message: `codex teammate '${req.name}' is not alive`, recoverable: false }
766
+ }
767
+ const threadId = readDaemonState(req.name)?.threadId ?? null
768
+ if (threadId === null) {
769
+ return {
770
+ kind: 'failed',
771
+ message: `codex teammate '${req.name}' has no started thread yet — run 'tm send ${req.name} --prompt "…"' first`,
772
+ recoverable: false,
773
+ }
774
+ }
775
+
776
+ let client: CodexWsClient | null = null
777
+ try {
778
+ client = await openInitializedCodexClient(req.name)
779
+ await client.request<'thread/resume', ThreadResumeResponse>('thread/resume', {
780
+ threadId,
781
+ persistExtendedHistory: false,
782
+ })
783
+ // Order matters: subscribe BEFORE issuing thread/read, so a turn that
784
+ // completes between the read response and the subscription setup is
785
+ // not dropped (subscribeTurnCollection registers a notification
786
+ // handler immediately; lateInbounds buffer until awaitTurn fires).
787
+ const collector = subscribeTurnCollection(client, threadId)
788
+ const lastSeen = readDaemonState(req.name)?.lastSeen ?? 0
789
+ const readPromise = client.request<'thread/read', ThreadReadResponse>('thread/read', {
790
+ threadId,
791
+ includeTurns: true,
792
+ })
793
+ // Race the live subscription against the backfill read. If a turn
794
+ // completed in [send-timeout, wait-subscribe], the read finds it
795
+ // and resolves first; otherwise the read returns no candidate and
796
+ // we hand off to the collector (which may already have a live
797
+ // event cached from notifications that arrived during the read).
798
+ // The 124 contract — "still running, re-collect with tm wait" —
799
+ // now actually holds for Codex: the second wait recovers the
800
+ // in-window completion. If the wall-clock --timeout fires before
801
+ // the read RPC returns, control still reaches `isTimedOut(outcome)`
802
+ // and the caller gets the documented 124; the next `tm wait`
803
+ // catches the completion via the same backfill path.
804
+ //
805
+ // A thread/read RPC error is non-fatal here: the live subscription
806
+ // is the original (pre-backfill) source of truth, and a snapshot
807
+ // failure should not turn a healthy wait into a failed verb. Swallow
808
+ // the rejection and fall through to the collector.
809
+ const backfillRace: Promise<CollectedTurn> = readPromise.then(
810
+ (read) => {
811
+ const backfill = pickBackfillTurn(read.thread.turns, lastSeen, threadId)
812
+ if (backfill !== null) return { completed: backfill, tokenUsage: null }
813
+ return collector.awaitTurn()
814
+ },
815
+ () => collector.awaitTurn(),
816
+ )
817
+ const outcome = await withTimeout(
818
+ Promise.race([collector.awaitTurn(), backfillRace]),
819
+ req.timeoutMs,
820
+ )
821
+ if (isTimedOut(outcome)) {
822
+ // Swallow the readPromise rejection (if any) so the WS close in
823
+ // `finally` does not race with an unhandled rejection.
824
+ readPromise.catch(() => {})
825
+ return { kind: 'timed-out', elapsedMs: req.timeoutMs ?? 0 }
826
+ }
827
+ const rawPath = writeLastTurn(req.name, outcome.completed)
828
+ touchLastSeen(req.name)
829
+ return turnNotificationToResult(outcome.completed, {
830
+ name: req.name,
831
+ action: 'waited',
832
+ context: contextForCollectedTurn(outcome, ctx),
833
+ rawPath,
834
+ })
835
+ } catch (e) {
836
+ return {
837
+ kind: 'failed',
838
+ message: `codex wait on '${req.name}' failed: ${e instanceof Error ? e.message : String(e)}`,
839
+ recoverable: true,
840
+ }
841
+ } finally {
842
+ if (client !== null) client.close()
843
+ }
844
+ }
845
+
846
+ async kill(req: KillRequest, _ctx: EngineContext): Promise<KillResult> {
847
+ const state = readDaemonState(req.name)
848
+ const base = readBaseRecord(req.name)
849
+ const meta = readCodexMeta(req.name)
850
+ if (state === null && base === null && meta === null) return { kind: 'not-found' }
851
+ try {
852
+ await reapDaemon(req.name)
853
+ let worktreeNote = ''
854
+ if (base !== null && base.worktreeSlug !== null) {
855
+ const reap = await reapCodexWorktree(base.repo, base.worktreeSlug)
856
+ if (reap.kind === 'preserved-dirty') {
857
+ worktreeNote =
858
+ `worktree preserved at ${reap.path} ` +
859
+ `(uncommitted changes — run 'git -C ${base.repo} worktree remove --force ${reap.path}' once safe)\n`
860
+ } else if (reap.kind === 'preserved-unmerged') {
861
+ worktreeNote =
862
+ `worktree preserved at ${reap.path} ` +
863
+ `(branch '${reap.branch}' has commits not merged into HEAD — ` +
864
+ `merge or rebase the branch first, then ` +
865
+ `'git -C ${base.repo} worktree remove --force ${reap.path} && ` +
866
+ `git -C ${base.repo} branch -D ${reap.branch}' to clean up)\n`
867
+ } else if (reap.kind === 'failed') {
868
+ worktreeNote = `worktree cleanup failed: ${reap.message}\n`
869
+ }
870
+ }
871
+ // Per the Engine.kill contract, identity teardown belongs to
872
+ // `killVerb` — it archives + removes the base record after we
873
+ // return, so the post-kill recovery path for `tm resume` /
874
+ // `tm history` sees a snapshot of the launch context.
875
+ if (worktreeNote.length > 0) {
876
+ // We still return `killed` — the teammate is gone, the
877
+ // worktree leftover is communicated separately so a stale
878
+ // dirty checkout never blocks `tm kill` from completing.
879
+ // The verb layer surfaces the note through stderr.
880
+ return { kind: 'killed', note: worktreeNote }
881
+ }
882
+ return { kind: 'killed' }
883
+ } catch (e) {
884
+ return { kind: 'failed', message: e instanceof Error ? e.message : String(e) }
885
+ }
886
+ }
887
+
888
+ async list(ctx: EngineContext): Promise<readonly TeammateListing[]> {
889
+ const nowSec = Math.floor(ctx.now() / 1000)
890
+ const nowMs = ctx.now()
891
+ return Promise.all(listDaemons().map(async (name) => {
892
+ const state = readDaemonState(name)
893
+ const base = readBaseRecord(name)
894
+ const meta = readCodexMeta(name)
895
+ const rollout = state?.threadId === null || state?.threadId === undefined
896
+ ? null
897
+ : readCodexRolloutSnapshot(state.threadId, ctx.env)
898
+ const runtime = await this.probeRuntime(name, state)
899
+ const daemonState = codexDaemonState(name, state, runtime, rollout, nowMs)
900
+ return {
901
+ name,
902
+ engine: 'codex',
903
+ state: daemonState,
904
+ repo: base?.repo ?? base?.cwd ?? meta?.cwd ?? '',
905
+ cwd: base?.cwd ?? meta?.cwd ?? '',
906
+ worktreeSlug: base?.worktreeSlug ?? null,
907
+ displayName: base?.displayName ?? meta?.displayName ?? null,
908
+ extras: codexListExtras(nowSec, state, daemonState, rollout, runtime),
909
+ }
910
+ }))
911
+ }
912
+
913
+ async status(req: StatusRequest, ctx: EngineContext): Promise<TeammateStatus> {
914
+ const state = readDaemonState(req.name)
915
+ const base = readBaseRecord(req.name)
916
+ const meta = readCodexMeta(req.name)
917
+ if (state === null && base === null && meta === null) return { kind: 'not-found' }
918
+ const rollout = state?.threadId === null || state?.threadId === undefined
919
+ ? null
920
+ : readCodexRolloutSnapshot(state.threadId, ctx.env)
921
+ const runtime = await this.probeRuntime(req.name, state)
922
+ const daemonState = codexDaemonState(req.name, state, runtime, rollout, ctx.now())
923
+ return {
924
+ kind: 'present',
925
+ name: req.name,
926
+ engine: 'codex',
927
+ state: daemonState,
928
+ cwd: base?.cwd ?? meta?.cwd ?? '',
929
+ pane: statusPane({
930
+ name: req.name,
931
+ state,
932
+ base,
933
+ meta,
934
+ daemonState,
935
+ rollout,
936
+ runtime,
937
+ nowSec: Math.floor(ctx.now() / 1000),
938
+ }),
939
+ diagnostics: {
940
+ pid: state?.pid === undefined ? '' : String(state.pid),
941
+ socket: state?.socketPath ?? '',
942
+ socketReachable: runtime?.socketReachable ?? 'unknown',
943
+ thread: state?.threadId ?? '',
944
+ threadStatus: runtime?.threadStatus ?? '',
945
+ startedAt: state?.startedAt === undefined ? '' : String(state.startedAt),
946
+ lastSeen: state?.lastSeen === null || state?.lastSeen === undefined ? '' : String(state.lastSeen),
947
+ rollout: rollout?.path ?? '',
948
+ rolloutMtime: rollout === null ? '' : String(Math.floor(rollout.mtimeMs / 1000)),
949
+ busyWindowMs: String(CODEX_ROLLOUT_BUSY_WINDOW_MS),
950
+ },
951
+ }
952
+ }
953
+
954
+ async compact(_req: CompactRequest, _ctx: EngineContext): Promise<CompactResult> {
955
+ return { kind: 'not-supported', reason: COMPACT_REASON }
956
+ }
957
+
958
+ async resume(req: ResumeRequest, ctx: EngineContext): Promise<ResumeResult> {
959
+ const invalidName = codexNameFailure(req.name)
960
+ if (invalidName !== null) return { kind: 'failed', message: invalidName }
961
+ let threadId = req.checkpoint
962
+ const invalidThreadId = threadId === null ? null : codexThreadIdFailure(threadId, req.name)
963
+ if (invalidThreadId !== null) return { kind: 'failed', message: invalidThreadId }
964
+
965
+ const existing = readBaseRecord(req.name)
966
+ if (existing !== null) {
967
+ if (existing.engine !== 'codex') {
968
+ return { kind: 'failed', message: `'${req.name}' already exists as a ${existing.engine} teammate` }
969
+ }
970
+ if (daemonAlive(req.name) || daemonSpawnInProgress(req.name)) {
971
+ return { kind: 'failed', message: `codex teammate '${req.name}' is already running` }
972
+ }
973
+ removeBaseRecord(req.name)
974
+ }
975
+ if (daemonAlive(req.name)) {
976
+ return { kind: 'failed', message: `codex teammate '${req.name}' is already running` }
977
+ }
978
+ if (daemonSpawnInProgress(req.name)) {
979
+ return { kind: 'failed', message: `codex teammate '${req.name}' is already being spawned` }
980
+ }
981
+
982
+ const createdAt = Math.floor(ctx.now() / 1000)
983
+ const cwd = req.cwd ?? process.cwd()
984
+ const repo = req.repo ?? cwd
985
+ const record = new CodexTeammateRecord({
986
+ name: req.name,
987
+ repo,
988
+ cwd,
989
+ worktreeSlug: req.worktreeSlug,
990
+ createdAt,
991
+ displayName: req.displayName,
992
+ })
993
+ const reserved = reserveBaseRecord(record)
994
+ if (reserved.kind === 'taken') {
995
+ return { kind: 'failed', message: `'${req.name}' already exists as a ${reserved.existing.engine} teammate` }
996
+ }
997
+ if (reserved.kind === 'failed') return { kind: 'failed', message: reserved.message }
998
+
999
+ // Resume-after-clean-kill recovery: if the resumed teammate ran
1000
+ // in a worktree and that worktree path was cleared by the prior
1001
+ // `tm kill` (default for clean state), re-create it from `repo` +
1002
+ // `worktreeSlug` now so the daemon's `spawnDaemon` cwd actually
1003
+ // exists. The `tm resume` verb layer parses the rollout's
1004
+ // `session_meta.cwd` and forwards repo / worktreeSlug for exactly
1005
+ // this path. If `--no-worktree`, or the worktree dir still
1006
+ // exists, the provision is a no-op.
1007
+ if (req.worktreeSlug !== null && !existsSync(cwd)) {
1008
+ const error = await provisionCodexWorktree(repo, req.worktreeSlug)
1009
+ if (error !== null) {
1010
+ removeBaseRecord(req.name)
1011
+ return {
1012
+ kind: 'failed',
1013
+ message:
1014
+ `failed to re-provision worktree for resume at ${cwd}: ${error}`,
1015
+ }
1016
+ }
1017
+ }
1018
+
1019
+ let client: CodexWsClient | null = null
1020
+ try {
1021
+ await spawnDaemon({
1022
+ name: req.name,
1023
+ binPath: this.options.binPath,
1024
+ cwd,
1025
+ env: ctx.env,
1026
+ readyTimeoutMs: this.options.readyTimeoutMs,
1027
+ meta: {
1028
+ schema: 1,
1029
+ name: req.name,
1030
+ cwd,
1031
+ displayName: req.displayName,
1032
+ spawnedAt: createdAt,
1033
+ },
1034
+ })
1035
+
1036
+ await this.healthCheck(req.name)
1037
+ ensureCodexIpcBridge(req.name, { cwd, env: ctx.env })
1038
+ client = await openInitializedCodexClient(req.name)
1039
+ if (threadId === null) {
1040
+ threadId = await latestCodexThreadIdForCwd(client, cwd)
1041
+ if (threadId === null) {
1042
+ client.close()
1043
+ client = null
1044
+ removeBaseRecord(req.name)
1045
+ await reapDaemon(req.name)
1046
+ return { kind: 'not-found', reason: `no codex threads found for cwd ${cwd}` }
1047
+ }
1048
+ const latestInvalidThreadId = codexThreadIdFailure(threadId)
1049
+ if (latestInvalidThreadId !== null) {
1050
+ throw new Error(`thread/list returned invalid thread id: ${threadId}`)
1051
+ }
1052
+ }
1053
+ writeThreadId(req.name, threadId)
1054
+ await client.request<'thread/resume', ThreadResumeResponse>('thread/resume', {
1055
+ threadId,
1056
+ persistExtendedHistory: false,
1057
+ })
1058
+ touchLastSeen(req.name)
1059
+ client.close()
1060
+ client = null
1061
+
1062
+ if (req.prompt === null) {
1063
+ return {
1064
+ kind: 'resumed',
1065
+ checkpoint: threadId,
1066
+ tmResult: {
1067
+ code: 0,
1068
+ stdout: `resumed: ${threadId}\n`,
1069
+ stderr: codexResumeHeader(req.name),
1070
+ },
1071
+ }
1072
+ }
1073
+ const turn = formatFirstTurn(await this.send(
1074
+ { name: req.name, prompt: req.prompt, timeoutMs: null, paneQuiet: false },
1075
+ ctx,
1076
+ ))
1077
+ return {
1078
+ kind: 'resumed',
1079
+ checkpoint: threadId,
1080
+ tmResult: {
1081
+ code: turn.code,
1082
+ stdout: turn.stdout,
1083
+ stderr: codexResumeHeader(req.name) + turn.stderr,
1084
+ },
1085
+ }
1086
+ } catch (e) {
1087
+ removeBaseRecord(req.name)
1088
+ if (e instanceof CodexDaemonAlreadyAliveError) {
1089
+ return { kind: 'failed', message: e.message }
1090
+ }
1091
+ if (!(e instanceof CodexDaemonSpawnInProgressError)) {
1092
+ await reapDaemon(req.name)
1093
+ }
1094
+ return {
1095
+ kind: 'failed',
1096
+ message: e instanceof Error ? e.message : String(e),
1097
+ }
1098
+ } finally {
1099
+ if (client !== null) client.close()
1100
+ }
1101
+ }
1102
+
1103
+ async last(req: LastRequest, ctx: EngineContext): Promise<TextResult> {
1104
+ if (req.verbose) {
1105
+ const raw = readCodexLastTurn(req.name)
1106
+ if (raw === null) return { kind: 'not-found', reason: `codex teammate '${req.name}' has no raw last turn` }
1107
+ return { kind: 'text', text: ensureTrailingNewline(raw) }
1108
+ }
1109
+ const threadId = readDaemonState(req.name)?.threadId ?? null
1110
+ if (threadId === null) return { kind: 'not-found', reason: `codex teammate '${req.name}' has no thread id` }
1111
+ const rollout = readCodexRolloutSnapshot(threadId, ctx.env)
1112
+ if (rollout === null) return { kind: 'not-found', reason: `codex rollout for thread '${threadId}' not found` }
1113
+ if (rollout.lastAssistantText === null) {
1114
+ return { kind: 'not-found', reason: `no assistant text in codex rollout ${rollout.path}` }
1115
+ }
1116
+ return {
1117
+ kind: 'text',
1118
+ text: rollout.lastAssistantText.endsWith('\n')
1119
+ ? rollout.lastAssistantText
1120
+ : `${rollout.lastAssistantText}\n`,
1121
+ }
1122
+ }
1123
+
1124
+ async ctx(req: ContextRequest, ctx: EngineContext): Promise<ContextResult> {
1125
+ const threadId = readDaemonState(req.name)?.threadId ?? null
1126
+ if (threadId === null) {
1127
+ return { kind: 'not-supported', reason: `codex teammate '${req.name}' has no thread id` }
1128
+ }
1129
+ const rollout = readCodexRolloutSnapshot(threadId, ctx.env)
1130
+ if (rollout === null) {
1131
+ return { kind: 'not-supported', reason: `codex rollout for thread '${threadId}' not found` }
1132
+ }
1133
+ if (rollout.tokenUsage === null) {
1134
+ return { kind: 'not-supported', reason: `no token usage in codex rollout ${rollout.path}` }
1135
+ }
1136
+ return {
1137
+ kind: 'usage',
1138
+ tokensUsed: rollout.tokenUsage.tokensUsed,
1139
+ tokensTotal: rollout.tokenUsage.tokensTotal,
1140
+ pct: rollout.tokenUsage.pct,
1141
+ }
1142
+ }
1143
+
1144
+ async history(_req: HistoryRequest, _ctx: EngineContext): Promise<HistoryResult> {
1145
+ return codexHistory(_req, _ctx)
1146
+ }
1147
+
1148
+ async mem(_req: MemoryRequest, _ctx: EngineContext): Promise<TextResult> {
1149
+ return notSupported('codex does not use Claude project memory files')
1150
+ }
1151
+
1152
+ async reload(_req: ReloadRequest, _ctx: EngineContext): Promise<ReloadResult> {
1153
+ return { kind: 'not-supported', reason: 'codex has no reload prompt command' }
1154
+ }
1155
+
1156
+ async inspect(req: InspectRequest, _ctx: EngineContext): Promise<EngineSnapshot> {
1157
+ const status = await this.status({ name: req.name, lines: null }, _ctx)
1158
+ if (status.kind !== 'present') return { engine: 'codex', name: req.name, fields: { status: status.kind } }
1159
+ return { engine: 'codex', name: req.name, fields: status.diagnostics }
1160
+ }
1161
+
1162
+ async doctor(_ctx: EngineContext): Promise<DoctorSection> {
1163
+ const findings: DoctorFinding[] = []
1164
+ for (const name of listDaemons()) {
1165
+ const state = readDaemonState(name)
1166
+ if (state === null) {
1167
+ await reapDaemon(name)
1168
+ removeBaseRecord(name)
1169
+ findings.push({ severity: 'warn', summary: `reaped malformed codex daemon entry ${name}`, fix: null })
1170
+ } else if (!isProcessAlive(state.pid)) {
1171
+ await reapDaemon(name)
1172
+ removeBaseRecord(name)
1173
+ findings.push({ severity: 'warn', summary: `reaped stale codex daemon ${name} (pid=${state.pid})`, fix: null })
1174
+ } else {
1175
+ findings.push({ severity: 'ok', summary: `${name} alive (pid=${state.pid})`, fix: null })
1176
+ }
1177
+ }
1178
+ return { engine: 'codex', findings }
1179
+ }
1180
+
1181
+ private async healthCheck(name: string): Promise<void> {
1182
+ const clientPromise = openInitializedCodexClient(name)
1183
+ const initialized = await withTimeout(clientPromise, this.options.readyTimeoutMs ?? 10000)
1184
+ if (isTimedOut(initialized)) {
1185
+ closeClientWhenSettled(clientPromise)
1186
+ throw new Error(`codex daemon '${name}' did not answer initialize within health-check timeout`)
1187
+ }
1188
+ const client = initialized
1189
+ client.close()
1190
+ }
1191
+
1192
+ private async probeRuntime(
1193
+ name: string,
1194
+ state: ReturnType<typeof readDaemonState>,
1195
+ ): Promise<CodexRuntimeProbe | null> {
1196
+ if (state === null || !isProcessAlive(state.pid)) return null
1197
+ let client: CodexWsClient | null = null
1198
+ try {
1199
+ const clientPromise = openInitializedCodexClient(name)
1200
+ const initialized = await withTimeout(clientPromise, CODEX_STATUS_RPC_TIMEOUT_MS)
1201
+ if (isTimedOut(initialized)) {
1202
+ closeClientWhenSettled(clientPromise)
1203
+ return { socketReachable: 'no', threadStatus: null, threadState: null }
1204
+ }
1205
+ client = initialized
1206
+ if (state.threadId === null) {
1207
+ return { socketReachable: 'yes', threadStatus: null, threadState: null }
1208
+ }
1209
+ try {
1210
+ const readPromise = client.request<'thread/read', ThreadReadResponse>('thread/read', {
1211
+ threadId: state.threadId,
1212
+ includeTurns: false,
1213
+ })
1214
+ const read = await withTimeout(readPromise, CODEX_STATUS_RPC_TIMEOUT_MS)
1215
+ if (isTimedOut(read)) {
1216
+ readPromise.catch(() => {})
1217
+ client.close()
1218
+ client = null
1219
+ return { socketReachable: 'yes', threadStatus: null, threadState: null }
1220
+ }
1221
+ const statusType = read.thread.status.type
1222
+ return {
1223
+ socketReachable: 'yes',
1224
+ threadStatus: statusType,
1225
+ threadState: statusState(statusType),
1226
+ }
1227
+ } catch {
1228
+ return { socketReachable: 'yes', threadStatus: null, threadState: null }
1229
+ }
1230
+ } catch {
1231
+ return { socketReachable: 'no', threadStatus: null, threadState: null }
1232
+ } finally {
1233
+ if (client !== null) client.close()
1234
+ }
1235
+ }
1236
+ }
1237
+
1238
+ /**
1239
+ * Open a fresh initialized connection to one per-teammate codex daemon.
1240
+ * Exported for the thin CLI compatibility wrappers and tests; the stream
1241
+ * itself remains codex-engine private and is not part of the Engine contract.
1242
+ */
1243
+ export async function openInitializedCodexClient(name: string): Promise<CodexWsClient> {
1244
+ const state = readDaemonState(name)
1245
+ if (state === null) throw new Error(`codex daemon '${name}' has no registry state`)
1246
+ const client = new CodexWsClient({ socketPath: state.socketPath })
1247
+ try {
1248
+ await client.ready()
1249
+ await client.request<'initialize', InitializeResponse>('initialize', {
1250
+ clientInfo: CODEX_CLIENT_INFO,
1251
+ capabilities: {
1252
+ experimentalApi: true,
1253
+ requestAttestation: false,
1254
+ },
1255
+ })
1256
+ return client
1257
+ } catch (e) {
1258
+ client.close()
1259
+ throw e
1260
+ }
1261
+ }