codex-overleaf-link 2.4.0 → 2.5.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 (327) hide show
  1. package/README.md +272 -311
  2. package/README.zh-CN.md +287 -326
  3. package/extension/bootstrap/background.js +47 -10
  4. package/extension/bootstrap/manifest.template.json +9 -4
  5. package/extension/bootstrap/popup.html +10 -16
  6. package/extension/bootstrap/update.js +25 -2
  7. package/extension/runtime-manifest.json +3 -1
  8. package/extension/src/background.js +28 -3
  9. package/extension/src/backgroundSharedSessions.js +380 -0
  10. package/extension/src/backgroundUpdateCoordinator.js +442 -379
  11. package/extension/src/content/activeTurnControl.js +8 -0
  12. package/extension/src/content/assetTransferBroker.js +186 -12
  13. package/extension/src/content/changeHistoryView.js +175 -0
  14. package/extension/src/content/composerAttachments.js +24 -22
  15. package/extension/src/content/composerPanel.js +23 -8
  16. package/extension/src/content/contentRuntime.js +572 -571
  17. package/extension/src/content/diagnosticsController.js +1 -2
  18. package/extension/src/content/diagnosticsExport.js +222 -0
  19. package/extension/src/content/diagnosticsPanel.js +48 -19
  20. package/extension/src/content/diffReviewPanel.js +8 -5
  21. package/extension/src/content/generated/content.bundle.js +8974 -1781
  22. package/extension/src/content/generated/content.bundle.meta.json +22 -3
  23. package/extension/src/content/legacyGlobalRegistry.js +19 -1
  24. package/extension/src/content/localSkillsPanel.js +42 -7
  25. package/extension/src/content/markdownDomRenderer.js +9 -4
  26. package/extension/src/content/modelPicker.js +1 -1
  27. package/extension/src/content/pageBridgeClient.js +18 -3
  28. package/extension/src/content/panelMaintenance.js +51 -120
  29. package/extension/src/content/panelRenderer.js +4 -0
  30. package/extension/src/content/pendingInputView.js +109 -76
  31. package/extension/src/content/providerSettingsCoordinator.js +17 -6
  32. package/extension/src/content/providerSettingsDialog.js +661 -108
  33. package/extension/src/content/recentProjects.js +364 -356
  34. package/extension/src/content/runActivitySummary.js +631 -0
  35. package/extension/src/content/runController.js +3 -1
  36. package/extension/src/content/runFailureNotice.js +14 -1
  37. package/extension/src/content/runGuidanceController.js +4 -3
  38. package/extension/src/content/runPresence.js +306 -0
  39. package/extension/src/content/runQueueScheduler.js +2 -1
  40. package/extension/src/content/runResultActions.js +123 -3
  41. package/extension/src/content/runTimelineView.js +194 -164
  42. package/extension/src/content/scopedPersistenceCoordinator.js +2 -1
  43. package/extension/src/content/scopedPersistencePanelState.js +45 -2
  44. package/extension/src/content/selectionContextView.js +300 -0
  45. package/extension/src/content/sessionPersistence.js +10 -2
  46. package/extension/src/content/settingsPanel.js +93 -54
  47. package/extension/src/content/settingsWorkbench.js +374 -0
  48. package/extension/src/content/sharedSessionViewSync.js +72 -0
  49. package/extension/src/content/subagentActivityView.js +195 -0
  50. package/extension/src/content/trackedChangeCaptureController.js +7 -3
  51. package/extension/src/content/updateNotice.js +121 -50
  52. package/extension/src/content/writebackController.js +257 -0
  53. package/extension/src/content/writebackOrchestrator.js +146 -141
  54. package/extension/src/content/writebackPlan.js +231 -0
  55. package/extension/src/content/writebackRecovery.js +122 -0
  56. package/extension/src/content/writingStyleSettings.js +576 -0
  57. package/extension/src/content/writtenChangesView.js +152 -0
  58. package/extension/src/page/binaryAssetUploader.js +97 -19
  59. package/extension/src/page/overleafProjectSnapshot.js +1 -0
  60. package/extension/src/page/referenceProjects.js +148 -0
  61. package/extension/src/page/saveState.js +58 -3
  62. package/extension/src/page/snapshotRouter.js +44 -13
  63. package/extension/src/page/textCoordinates.js +102 -0
  64. package/extension/src/page/textFileCreator.js +350 -59
  65. package/extension/src/page/trackedChangeCapture.js +42 -56
  66. package/extension/src/page/trackedChangeOwnership.js +198 -0
  67. package/extension/src/page/trackedChangeReplay.js +164 -0
  68. package/extension/src/page/trackedChangesLifecycle.js +139 -150
  69. package/extension/src/page/treeOperations.js +36 -29
  70. package/extension/src/page/writebackReceiptJournal.js +112 -0
  71. package/extension/src/page/writebackRouter.js +176 -136
  72. package/extension/src/pageBridge.js +59 -101
  73. package/extension/src/popup.js +203 -59
  74. package/extension/src/shared/agentTranscript.js +18 -4
  75. package/extension/src/shared/auditRecords.js +71 -0
  76. package/extension/src/shared/changeHistoryModel.js +94 -0
  77. package/extension/src/shared/compatibility.js +1 -1
  78. package/extension/src/shared/compileAdapter.js +42 -0
  79. package/extension/src/shared/failureReasons.js +20 -0
  80. package/extension/src/shared/globalPreferences.js +1 -1
  81. package/extension/src/shared/i18n.js +187 -65
  82. package/extension/src/shared/managedUpdateProjection.js +6 -3
  83. package/extension/src/shared/pageRpcContract.js +7 -1
  84. package/extension/src/shared/providerProfiles.js +109 -0
  85. package/extension/src/shared/runActivityModel.js +361 -0
  86. package/extension/src/shared/runExecutionSnapshot.js +8 -2
  87. package/extension/src/shared/runExecutionSnapshotCodec.js +16 -4
  88. package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
  89. package/extension/src/shared/selectionContext.js +28 -0
  90. package/extension/src/shared/sessionState.js +97 -6
  91. package/extension/src/shared/sharedSessionBridge.js +288 -0
  92. package/extension/src/shared/storageDb.js +23 -55
  93. package/extension/src/shared/storageMigration.js +3 -0
  94. package/extension/src/shared/storageRunActions.js +54 -4
  95. package/extension/src/shared/storageValuePruning.js +40 -0
  96. package/extension/src/shared/subagentActivityModel.js +174 -0
  97. package/extension/src/shared/undoOperations.js +87 -0
  98. package/extension/src/shared/updateConsent.js +37 -8
  99. package/extension/src/shared/writebackIntent.js +62 -0
  100. package/extension/src/shared/writebackSettlement.js +29 -10
  101. package/extension/src/shared/writingStyle.js +33 -0
  102. package/extension/styles/panel.css +2136 -744
  103. package/extension/styles/popup.css +110 -0
  104. package/native-host/src/anthropicBridgeRequest.js +2 -1
  105. package/native-host/src/codexModelRecovery.js +107 -0
  106. package/native-host/src/codexPromptAssembly.js +2 -0
  107. package/native-host/src/codexProviderLaunch.js +3 -3
  108. package/native-host/src/codexRuntimeIdentity.js +1 -0
  109. package/native-host/src/codexSessionRunner.js +146 -177
  110. package/native-host/src/codexSessionTiming.js +71 -0
  111. package/native-host/src/managedInstall.js +5 -4
  112. package/native-host/src/nativeEnvironment.js +70 -0
  113. package/native-host/src/nativeQuotas.js +15 -8
  114. package/native-host/src/overleafWorkspaceRules.js +16 -0
  115. package/native-host/src/processStopBarrier.js +80 -0
  116. package/native-host/src/providerModelCatalog.js +4 -3
  117. package/native-host/src/providerProfile.js +13 -1
  118. package/native-host/src/providerReasoning.js +9 -5
  119. package/native-host/src/providerStore.js +4 -0
  120. package/native-host/src/readProgressGuard.js +84 -17
  121. package/native-host/src/releaseTransport.js +14 -5
  122. package/native-host/src/selectionScope.js +58 -0
  123. package/native-host/src/skills/parallel-subagents/SKILL.md +31 -3
  124. package/native-host/src/skills/writing-style-builder/SKILL.md +146 -0
  125. package/native-host/src/subagentBroker.js +102 -98
  126. package/native-host/src/subagentTelemetry.js +316 -0
  127. package/native-host/src/subagentWorkspace.js +103 -0
  128. package/native-host/src/subagentWorkspacePath.js +31 -0
  129. package/native-host/src/taskRunnerRuntime.js +55 -5
  130. package/native-host/src/turnAttachments.js +113 -0
  131. package/native-host/src/updateManager.js +122 -12
  132. package/native-host/src/updateNetworkControl.js +75 -0
  133. package/native-host/src/updateTrust.js +21 -2
  134. package/native-host/src/vendor/pdfjs/LICENSE +177 -0
  135. package/native-host/src/vendor/pdfjs/SOURCE.txt +3 -0
  136. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  137. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  138. package/native-host/src/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
  139. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  140. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  141. package/native-host/src/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
  142. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  143. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  144. package/native-host/src/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  145. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  146. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  147. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  148. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  149. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  150. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  151. package/native-host/src/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
  152. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  153. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  154. package/native-host/src/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
  155. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  156. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  157. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  158. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  159. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  160. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  161. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  162. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  163. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  164. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  165. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  166. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  167. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  168. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  169. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  170. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  171. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  172. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  173. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  174. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  175. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  176. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  177. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  178. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  179. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  180. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  181. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  182. package/native-host/src/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
  183. package/native-host/src/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
  184. package/native-host/src/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  185. package/native-host/src/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  186. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  187. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  188. package/native-host/src/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  189. package/native-host/src/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  190. package/native-host/src/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  191. package/native-host/src/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  192. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  193. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  194. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  195. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  196. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  197. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  198. package/native-host/src/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
  199. package/native-host/src/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
  200. package/native-host/src/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
  201. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  202. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  203. package/native-host/src/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
  204. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  205. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  206. package/native-host/src/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
  207. package/native-host/src/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
  208. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  209. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  210. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  211. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  212. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  213. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  214. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  215. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  216. package/native-host/src/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
  217. package/native-host/src/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
  218. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  219. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  220. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  221. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  222. package/native-host/src/vendor/pdfjs/cmaps/H.bcmap +0 -0
  223. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  224. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  225. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  226. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  227. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  228. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  229. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  230. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  231. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  232. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  233. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  234. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  235. package/native-host/src/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
  236. package/native-host/src/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
  237. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  238. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  239. package/native-host/src/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
  240. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  241. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  242. package/native-host/src/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
  243. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  244. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  245. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  246. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  247. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  248. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  249. package/native-host/src/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
  250. package/native-host/src/vendor/pdfjs/cmaps/LICENSE +36 -0
  251. package/native-host/src/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
  252. package/native-host/src/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
  253. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  254. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  255. package/native-host/src/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
  256. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  257. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  258. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  259. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  260. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  261. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  262. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  263. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  264. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  265. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  266. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  267. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  268. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  269. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  270. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  271. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  272. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  273. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  274. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  275. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  276. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  277. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  278. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  279. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  280. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  281. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  282. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  283. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  284. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  285. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  286. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  287. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  288. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  289. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  290. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  291. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  292. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  293. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  294. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  295. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  296. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  297. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  298. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  299. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  300. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  301. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  302. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  303. package/native-host/src/vendor/pdfjs/cmaps/V.bcmap +0 -0
  304. package/native-host/src/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  305. package/native-host/src/vendor/pdfjs/pdf.mjs +26740 -0
  306. package/native-host/src/vendor/pdfjs/pdf.worker.mjs +62201 -0
  307. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  308. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  309. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  310. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  311. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  312. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  313. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  314. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  315. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  316. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  317. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  318. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
  319. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  320. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  321. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  322. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  323. package/native-host/src/writingStyleEvidence.js +102 -0
  324. package/native-host/src/writingStylePdfWorker.js +35 -0
  325. package/native-host/src/writingStyleProfile.js +165 -0
  326. package/native-host/src/writingStyleRuntime.js +447 -0
  327. package/package.json +1 -1
@@ -19,7 +19,7 @@ const {
19
19
  getNativeHostRegistrationTarget
20
20
  } = require('./nativeHostPlatform');
21
21
  const { buildRuntimeFileManifest } = require('./runtimeInstaller');
22
- const { parseSemver, updateError } = require('./updateTrust');
22
+ const { BOOTSTRAP_PROTOCOL, parseSemver, updateError } = require('./updateTrust');
23
23
 
24
24
  const MANAGED_BY = 'codex-overleaf-link';
25
25
  const EXTENSION_MARKER = '.codex-overleaf-managed-extension.json';
@@ -154,7 +154,7 @@ function buildManagedExtensionTree(options = {}) {
154
154
  fs.writeFileSync(path.join(targetRoot, EXTENSION_MARKER), JSON.stringify({
155
155
  managedBy: MANAGED_BY,
156
156
  kind: 'extension',
157
- bootstrapProtocol: 2,
157
+ bootstrapProtocol: BOOTSTRAP_PROTOCOL,
158
158
  version,
159
159
  releaseRef,
160
160
  releaseChannel,
@@ -199,7 +199,7 @@ function installManagedNativeVersion({ packageRoot, nativeRoot, version, release
199
199
  fs.writeFileSync(path.join(nativeRoot, NATIVE_MARKER), JSON.stringify({
200
200
  managedBy: MANAGED_BY,
201
201
  kind: 'native',
202
- bootstrapProtocol: 2,
202
+ bootstrapProtocol: BOOTSTRAP_PROTOCOL,
203
203
  version,
204
204
  installedAt: new Date().toISOString()
205
205
  }, null, 2) + '\n', 'utf8');
@@ -388,7 +388,8 @@ function readManagedMarker(root, markerName) {
388
388
  function isManagedMarker(marker, kind) {
389
389
  return marker?.managedBy === MANAGED_BY &&
390
390
  marker?.kind === kind &&
391
- (marker?.bootstrapProtocol === 1 || marker?.bootstrapProtocol === 2);
391
+ Number.isInteger(marker?.bootstrapProtocol) &&
392
+ marker.bootstrapProtocol >= 1 && marker.bootstrapProtocol <= BOOTSTRAP_PROTOCOL;
392
393
  }
393
394
 
394
395
  function readVersionPointer(nativeRoot, name) {
@@ -4,8 +4,10 @@ const fs = require('node:fs');
4
4
  const os = require('node:os');
5
5
  const path = require('node:path');
6
6
  const { spawnSync } = require('node:child_process');
7
+ const { logDebug } = require('./debugLog');
7
8
  const {
8
9
  buildCodexRuntimeIdentity,
10
+ discoverCodexCandidates,
9
11
  getCodexRuntimeIdentityFromEnv,
10
12
  serializeCodexRuntimeIdentity
11
13
  } = require('./codexRuntimeIdentity');
@@ -54,6 +56,69 @@ function buildNativeRuntimeEnv(baseEnv = process.env, options = {}) {
54
56
  return env;
55
57
  }
56
58
 
59
+ const codexRuntimeRefreshCache = new Map();
60
+
61
+ function refreshCodexRuntimeEnv(baseEnv = process.env, options = {}) {
62
+ const runtimeOptions = { ...options, platform: getNativeRuntimePlatform({ ...options, env: baseEnv }) };
63
+ const previous = getCodexRuntimeIdentityFromEnv(baseEnv);
64
+ const selectedPath = previous.selected?.path || String(baseEnv.CODEX_OVERLEAF_CODEX_PATH || '');
65
+ const pinned = previous.selectedBy === 'explicit-path'
66
+ || (previous.selectedBy === 'legacy-path' && Boolean(selectedPath));
67
+ const pathValue = mergePathSegments([
68
+ ...getPathValues(baseEnv, runtimeOptions),
69
+ ...getDefaultPathSegments(baseEnv, runtimeOptions)
70
+ ], runtimeOptions);
71
+ const candidates = discoverCodexCandidates(pathValue, { ...runtimeOptions, env: baseEnv });
72
+ const paths = [...new Set([selectedPath, ...candidates].filter(Boolean))];
73
+ const signatures = paths.map(candidate => {
74
+ try {
75
+ const resolved = fs.realpathSync(candidate);
76
+ const stat = fs.statSync(resolved);
77
+ return [candidate, resolved, stat.size, stat.mtimeMs, stat.ctimeMs];
78
+ } catch (_) { return [candidate, 'missing']; }
79
+ });
80
+ const key = JSON.stringify([runtimeOptions.platform, pinned ? selectedPath : '', pathValue, signatures]);
81
+ const cached = codexRuntimeRefreshCache.get(key);
82
+ let identity = cached?.identity;
83
+ if (options.force || !cached || Date.now() - cached.createdAt > 30000) {
84
+ identity = buildCodexRuntimeIdentity({
85
+ selectedPath,
86
+ selectionPolicy: pinned ? 'explicit-path' : 'newest-version',
87
+ pathValue,
88
+ delimiter: runtimeOptions.delimiter,
89
+ env: { ...baseEnv, PATH: pathValue },
90
+ platform: runtimeOptions.platform
91
+ });
92
+ codexRuntimeRefreshCache.set(key, { identity, createdAt: Date.now() });
93
+ while (codexRuntimeRefreshCache.size > 4) {
94
+ codexRuntimeRefreshCache.delete(codexRuntimeRefreshCache.keys().next().value);
95
+ }
96
+ if (identity.selected?.path !== previous.selected?.path
97
+ || identity.selected?.version !== previous.selected?.version) {
98
+ logDebug('codex.runtime.refreshed', {
99
+ previousVersion: previous.selected?.version || '',
100
+ selectedVersion: identity.selected?.version || '',
101
+ selectedPath: identity.selected?.displayPath || '',
102
+ selectedBy: identity.selectedBy,
103
+ reason: options.force ? 'model_version_rejection' : 'before_request'
104
+ });
105
+ }
106
+ }
107
+ // Keep each in-flight run on its own environment snapshot.
108
+ const env = {
109
+ ...baseEnv,
110
+ CODEX_OVERLEAF_ENV_READY: '1',
111
+ CODEX_OVERLEAF_PLATFORM: runtimeOptions.platform,
112
+ CODEX_OVERLEAF_CODEX_PATH: identity.selected?.path || '',
113
+ CODEX_OVERLEAF_CODEX_RUNTIME_JSON: serializeCodexRuntimeIdentity(identity),
114
+ CODEX_OVERLEAF_CODEX_VERSION: identity.selected?.version || '',
115
+ CODEX_OVERLEAF_CODEX_SOURCE: identity.selected?.source || ''
116
+ };
117
+ normalizePathKeys(env, pathValue, runtimeOptions);
118
+ env.PATH = pathValue;
119
+ return env;
120
+ }
121
+
57
122
  function readLoginShellEnv(baseEnv = process.env, options = {}) {
58
123
  if (getNativeRuntimePlatform(options) === 'win32') {
59
124
  return null;
@@ -169,6 +234,10 @@ function getDefaultPathSegments(env = process.env, options = {}) {
169
234
 
170
235
  return [
171
236
  ...commonSegments.slice(0, 4),
237
+ platformPath.join(home, 'Applications/ChatGPT.app/Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS'),
238
+ platformPath.join(home, 'Applications/Codex.app/Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS'),
239
+ '/Applications/ChatGPT.app/Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS',
240
+ '/Applications/Codex.app/Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS',
172
241
  platformPath.join(home, 'Applications/ChatGPT.app/Contents/Resources'),
173
242
  platformPath.join(home, 'Applications/Codex.app/Contents/Resources'),
174
243
  '/Applications/ChatGPT.app/Contents/Resources',
@@ -344,6 +413,7 @@ module.exports = {
344
413
  mergePathSegments,
345
414
  parseMarkedShellEnv,
346
415
  readLoginShellEnv,
416
+ refreshCodexRuntimeEnv,
347
417
  resolveExecutable,
348
418
  summarizeNativeEnvironment
349
419
  };
@@ -1,5 +1,12 @@
1
1
  'use strict';
2
2
 
3
+ const { REFERENCE_LIMITS } = require('../../extension/src/shared/writingStyle');
4
+ const WRITING_STYLE_ATTACHMENT_QUOTAS = Object.freeze({
5
+ maxAttachmentCount: REFERENCE_LIMITS.maxSources,
6
+ maxAttachmentBytes: REFERENCE_LIMITS.maxPdfBytes,
7
+ maxAttachmentTotalBytes: REFERENCE_LIMITS.maxAttachmentTotalBytes
8
+ });
9
+
3
10
  const NATIVE_REQUEST_QUOTAS = Object.freeze({
4
11
  maxProjectFiles: 1000,
5
12
  maxProjectTextBytes: 32 * 1024 * 1024,
@@ -21,7 +28,7 @@ function validateNativeRequestQuotas(request = {}) {
21
28
  validateOperationListQuota(params.fileOverlays, 'fileOverlays'),
22
29
  validateFilePayloadQuota(params.fileOverlays, 'fileOverlays'),
23
30
  validateCompileLogQuota(params),
24
- validateAttachmentQuota(params.attachments),
31
+ validateAttachmentQuota(params.attachments, params.writingStyleBuild ? WRITING_STYLE_ATTACHMENT_QUOTAS : NATIVE_REQUEST_QUOTAS),
25
32
  validateSkillContentQuota(params.skillContent)
26
33
  ]);
27
34
  case 'mirror.sync':
@@ -211,27 +218,27 @@ function validateCompileLogQuota(params = {}) {
211
218
  : null;
212
219
  }
213
220
 
214
- function validateAttachmentQuota(attachments) {
221
+ function validateAttachmentQuota(attachments, quotas = NATIVE_REQUEST_QUOTAS) {
215
222
  const items = Array.isArray(attachments) ? attachments : [];
216
- if (items.length > NATIVE_REQUEST_QUOTAS.maxAttachmentCount) {
217
- return quotaViolation('attachments', NATIVE_REQUEST_QUOTAS.maxAttachmentCount, items.length, 'too many attachments');
223
+ if (items.length > quotas.maxAttachmentCount) {
224
+ return quotaViolation('attachments', quotas.maxAttachmentCount, items.length, 'too many attachments');
218
225
  }
219
226
 
220
227
  let totalBytes = 0;
221
228
  for (const item of items) {
222
229
  const bytes = getDeclaredOrEstimatedBinaryBytes(item);
223
- if (bytes > NATIVE_REQUEST_QUOTAS.maxAttachmentBytes) {
230
+ if (bytes > quotas.maxAttachmentBytes) {
224
231
  return quotaViolation(
225
232
  'attachments.contentBase64',
226
- NATIVE_REQUEST_QUOTAS.maxAttachmentBytes,
233
+ quotas.maxAttachmentBytes,
227
234
  bytes,
228
235
  'attachment payload is too large'
229
236
  );
230
237
  }
231
238
  totalBytes += bytes;
232
239
  }
233
- return totalBytes > NATIVE_REQUEST_QUOTAS.maxAttachmentTotalBytes
234
- ? quotaViolation('attachments', NATIVE_REQUEST_QUOTAS.maxAttachmentTotalBytes, totalBytes, 'attachment payload is too large')
240
+ return totalBytes > quotas.maxAttachmentTotalBytes
241
+ ? quotaViolation('attachments', quotas.maxAttachmentTotalBytes, totalBytes, 'attachment payload is too large')
235
242
  : null;
236
243
  }
237
244
 
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ // Shared by project turns and broker workers. Skill-install turns run outside
4
+ // the project mirror and retain their existing installer command policy.
5
+ function formatOverleafWorkspaceRules() {
6
+ return [
7
+ 'Overleaf workspace rules (also apply to delegated subagents):',
8
+ '- This directory is a synchronized Overleaf project mirror without .git metadata.',
9
+ '- Do not run Git commands in this mirror, including git status, git diff, git rev-parse, or git init. Do not create .git metadata or search parent directories for a repository.',
10
+ '- Verify changes through direct file reads and searches. Run compilation checks only when needed and permitted by the current task and mode; never compile solely to replace an unavailable Git check.',
11
+ '- The plugin compares the workspace against its synchronized baseline, collects file changes, and handles writeback to Overleaf. No Git-based diff, staging, or commit is required.',
12
+ '- Include these workspace rules in every delegated subagent task so workers follow the same constraints.'
13
+ ].join('\n');
14
+ }
15
+
16
+ module.exports = { formatOverleafWorkspaceRules };
@@ -0,0 +1,80 @@
1
+ 'use strict';
2
+
3
+ // A stop acknowledgement is not proof of process exit. This quarantine survives
4
+ // Native Host restarts and only permits work after positive exit evidence.
5
+ const fs = require('node:fs');
6
+ const path = require('node:path');
7
+ const { getProjectMirror } = require('./mirrorWorkspace');
8
+ const pending = new Map();
9
+
10
+ function location(projectId, rootDir) {
11
+ const mirror = getProjectMirror(projectId, { rootDir });
12
+ return path.join(path.dirname(mirror.workspacePath), '.codex-stop-barrier.json');
13
+ }
14
+
15
+ function load(file) {
16
+ if (pending.has(file)) return pending.get(file);
17
+ let records = [];
18
+ try {
19
+ if (fs.statSync(file).size > 65536) throw new Error('Oversized stop barrier');
20
+ const value = JSON.parse(fs.readFileSync(file, 'utf8'));
21
+ if (!Array.isArray(value) || value.length > 64) throw new Error('Invalid stop barrier');
22
+ records = value;
23
+ } catch (error) {
24
+ if (error.code !== 'ENOENT') records = [{ unknown: true }];
25
+ }
26
+ pending.set(file, records);
27
+ return records;
28
+ }
29
+
30
+ function persist(file, records) {
31
+ fs.mkdirSync(path.dirname(file), { recursive: true });
32
+ const temp = file + '.' + process.pid + '.tmp';
33
+ const fd = fs.openSync(temp, 'w', 0o600);
34
+ try {
35
+ fs.writeFileSync(fd, JSON.stringify(records.map(({ isStopped, ...record }) => record)));
36
+ fs.fsyncSync(fd);
37
+ } finally { fs.closeSync(fd); }
38
+ fs.renameSync(temp, file);
39
+ }
40
+
41
+ function stopped(record) {
42
+ if (typeof record.isStopped === 'function') {
43
+ try { return record.isStopped() === true; } catch (_) { return false; }
44
+ }
45
+ // Recovered POSIX process-group identities can be checked without signalling
46
+ // or killing anything. Unknown/Windows trees remain quarantined.
47
+ if (record.processGroup !== true || record.platform !== process.platform
48
+ || !Number.isInteger(record.processId) || record.processId <= 0) return false;
49
+ try { process.kill(-record.processId, 0); return false; }
50
+ catch (error) { return error.code === 'ESRCH'; }
51
+ }
52
+
53
+ function record(projectId, rootDir, error) {
54
+ const file = location(projectId, rootDir);
55
+ const records = load(file);
56
+ records.push({
57
+ processId: error.processId, processGroup: error.processGroup === true,
58
+ platform: process.platform, createdAt: new Date().toISOString(),
59
+ isStopped: error.isStopped
60
+ });
61
+ try { persist(file, records); }
62
+ catch (failure) { error.stopBarrierPersistenceError = failure.message; }
63
+ }
64
+
65
+ function isBlocked(projectId, rootDir) {
66
+ const file = location(projectId, rootDir);
67
+ const records = load(file);
68
+ if (!records.length) return false;
69
+ const remaining = records.filter(value => !stopped(value));
70
+ if (remaining.length !== records.length) {
71
+ try {
72
+ persist(file, remaining);
73
+ pending.set(file, remaining);
74
+ } catch (_) { return true; }
75
+ }
76
+ return remaining.length > 0;
77
+ }
78
+
79
+ module.exports = { record, isBlocked };
80
+
@@ -79,9 +79,10 @@ function buildModelEntry(model, launch, index) {
79
79
  }
80
80
 
81
81
  function normalizeEfforts(...values) {
82
- const allowed = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh']);
83
- const normalized = values
84
- .flatMap(value => Array.isArray(value) ? value : [])
82
+ const allowed = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']);
83
+ // Explicit model capabilities must not inherit the selected model's levels.
84
+ const configured = values.find(value => Array.isArray(value) && value.length) || [];
85
+ const normalized = configured
85
86
  .map(value => String(value || '').trim().toLowerCase())
86
87
  .filter(value => allowed.has(value));
87
88
  return Array.from(new Set(normalized.length ? normalized : ['none']));
@@ -7,7 +7,7 @@ const {
7
7
  } = require('./providerReasoning');
8
8
 
9
9
  const ALLOWED_WIRE_APIS = new Set(['auto', 'responses', 'chat', 'anthropic']);
10
- const ALLOWED_REASONING_EFFORTS = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh']);
10
+ const ALLOWED_REASONING_EFFORTS = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']);
11
11
  const ALLOWED_UPSTREAM_RESPONSE_MODES = new Set(['auto', 'streaming', 'buffered']);
12
12
  const ALLOWED_AUTH_MODES = new Set(['bearer', 'x-api-key', 'api-key', 'custom', 'none']);
13
13
  const ALLOWED_INPUT_MODALITIES = new Set(['text', 'image']);
@@ -93,6 +93,9 @@ function normalizeModels(values) {
93
93
  upstreamResponseMode: normalizeUpstreamResponseMode(value?.upstreamResponseMode, true),
94
94
  resolvedUpstreamResponseMode: normalizeUpstreamResponseMode(value?.resolvedUpstreamResponseMode, false),
95
95
  contextWindow: normalizeContextWindow(value?.contextWindow),
96
+ maxOutputTokens: normalizeModelOutputTokens(value?.maxOutputTokens),
97
+ reasoningAdapter: value?.reasoningAdapter ? normalizeReasoningAdapter(value.reasoningAdapter) : '',
98
+ reasoningCapability: value?.reasoningCapability ? normalizeReasoningCapability(value.reasoningCapability) : '',
96
99
  supportsParallelToolCalls: value?.supportsParallelToolCalls === true,
97
100
  inputModalities: normalizeInputModalities(value?.inputModalities),
98
101
  baseInstructions: normalizeOptionalText(value?.baseInstructions, 8000)
@@ -101,6 +104,15 @@ function normalizeModels(values) {
101
104
  return result;
102
105
  }
103
106
 
107
+ function normalizeModelOutputTokens(value) {
108
+ if (value === undefined || value === null || value === '') return null;
109
+ const number = Number(value);
110
+ if (!Number.isSafeInteger(number) || number < 256 || number > 65536) {
111
+ throw providerError('provider_configuration_invalid', 'Model output limit must be an integer between 256 and 65536.');
112
+ }
113
+ return number;
114
+ }
115
+
104
116
  function normalizeBaseUrl(value) {
105
117
  const text = normalizeRequiredText(value, 'provider_base_url_invalid', 'Base URL is required.', 2048);
106
118
  let parsed;
@@ -12,7 +12,7 @@ const REASONING_ADAPTERS = new Set([
12
12
  'reasoning_split'
13
13
  ]);
14
14
  const REASONING_CAPABILITIES = new Set(['auto', 'none', 'toggle', 'effort']);
15
- const REASONING_EFFORTS = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh']);
15
+ const REASONING_EFFORTS = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']);
16
16
  const DEEPSEEK_MAX_REASONING_OUTPUT_TOKENS = 65536;
17
17
 
18
18
  function normalizeReasoningAdapter(value) {
@@ -67,6 +67,10 @@ function getSupportedReasoningEfforts(profile = {}, model = {}) {
67
67
  }
68
68
 
69
69
  function getReasoningControl(profile = {}, model = {}) {
70
+ profile = { ...profile,
71
+ reasoningAdapter: model.reasoningAdapter || profile.reasoningAdapter,
72
+ reasoningCapability: model.reasoningCapability || profile.reasoningCapability
73
+ };
70
74
  const explicit = Array.isArray(model.reasoningEfforts)
71
75
  ? model.reasoningEfforts.map(normalizeEffort).filter(Boolean)
72
76
  : [];
@@ -85,7 +89,7 @@ function getReasoningControl(profile = {}, model = {}) {
85
89
  }
86
90
  if (adapter === 'deepseek') {
87
91
  return {
88
- efforts: ['none', 'high', 'xhigh'],
92
+ efforts: ['none', 'high', 'max'],
89
93
  defaultEffort: 'high',
90
94
  presentation: 'deepseek'
91
95
  };
@@ -134,11 +138,11 @@ function applyReasoningControl(chatBody, responsesRequest = {}, launch = {}) {
134
138
  if (adapter === 'deepseek') {
135
139
  chatBody.thinking = { type: enabled ? 'enabled' : 'disabled' };
136
140
  if (enabled) {
137
- chatBody.reasoning_effort = requested === 'xhigh' ? 'max' : 'high';
141
+ chatBody.reasoning_effort = ['xhigh', 'max'].includes(requested) ? 'max' : 'high';
138
142
  }
139
143
  } else if (adapter === 'reasoning_effort') {
140
144
  if (enabled) {
141
- chatBody.reasoning_effort = clampEffort(requested, false);
145
+ chatBody.reasoning_effort = clampEffort(requested, true);
142
146
  }
143
147
  } else if (adapter === 'openrouter') {
144
148
  chatBody.reasoning = { effort: clampEffort(requested, true) };
@@ -164,7 +168,7 @@ function resolveReasoningMaxOutputTokens(value, responsesRequest = {}, launch =
164
168
  const normalized = Math.max(1, Math.floor(number));
165
169
  const effort = resolveRequestedReasoningEffort(responsesRequest, launch);
166
170
  const adapter = resolveReasoningAdapter(launch, modelId || launch.modelId);
167
- return adapter === 'deepseek' && effort === 'xhigh'
171
+ return adapter === 'deepseek' && ['xhigh', 'max'].includes(effort)
168
172
  ? Math.max(normalized, DEEPSEEK_MAX_REASONING_OUTPUT_TOKENS)
169
173
  : normalized;
170
174
  }
@@ -261,6 +261,10 @@ function recordProviderDiagnosticUnlocked(params = {}, env = process.env) {
261
261
  return { recorded: false };
262
262
  }
263
263
  const modelId = String(params.modelId || '').trim();
264
+ // Draft tests may cover models that are not saved yet; only saved models carry diagnostics.
265
+ if (!profile.models.some(model => model.id === modelId)) {
266
+ return { recorded: false };
267
+ }
264
268
  const secret = state.secrets.secrets[providerId] || '';
265
269
  const connectionFingerprint = computeConnectionFingerprint(profile, secret, modelId);
266
270
  if (connectionFingerprint !== String(params.connectionFingerprint || '') || !isResolvedWireApi(params.wireApi)) {
@@ -19,6 +19,36 @@ function buildReadProgressRules() {
19
19
  ].join('\n');
20
20
  }
21
21
 
22
+ function createRunEventScope(getTurn = () => ({})) {
23
+ const owners = new Map();
24
+ const identity = params => ({
25
+ threadId: String(params?.threadId || params?.thread?.id || ''),
26
+ turnId: String(params?.turnId || params?.turn?.id || '')
27
+ });
28
+ const itemId = params => String(params?.itemId || params?.item?.id || '');
29
+ const matches = owner => {
30
+ const active = getTurn() || {};
31
+ return (!owner.threadId || owner.threadId === active.threadId)
32
+ && (!owner.turnId || !active.turnId || owner.turnId === active.turnId);
33
+ };
34
+ return {
35
+ accepts(params = {}) {
36
+ const owner = identity(params);
37
+ const id = itemId(params);
38
+ if (owner.threadId || owner.turnId) {
39
+ if (id) owners.set(id, owner);
40
+ return matches(owner);
41
+ }
42
+ return !owners.has(id) || matches(owners.get(id));
43
+ },
44
+ owns(params = {}) {
45
+ const explicit = identity(params);
46
+ const owner = explicit.threadId || explicit.turnId ? explicit : owners.get(itemId(params));
47
+ return Boolean((getTurn() || {}).turnId && owner?.threadId && matches(owner));
48
+ }
49
+ };
50
+ }
51
+
22
52
  function createReadProgressGuard(options = {}) {
23
53
  const settings = {
24
54
  minReadCommands: positiveInteger(options.minReadCommands, DEFAULT_MIN_READ_COMMANDS),
@@ -37,11 +67,19 @@ function createReadProgressGuard(options = {}) {
37
67
  let redundantStreak = 0;
38
68
  let postSteerRedundantStreak = 0;
39
69
  let steerIssued = false;
70
+ let steerAcknowledged = false;
40
71
  let abortIssued = false;
41
72
 
42
73
  return {
43
74
  observe(item) {
44
75
  if (abortIssued) return noAction();
76
+ if (item?.type === 'fileChange') {
77
+ coverageByFile.clear();
78
+ commandCounts.clear();
79
+ readCount = redundantStreak = postSteerRedundantStreak = 0;
80
+ steerIssued = steerAcknowledged = false;
81
+ return noAction();
82
+ }
45
83
  const inspection = extractReadInspection(item, settings.workspacePath);
46
84
  if (!inspection) {
47
85
  if (item?.type === 'commandExecution') {
@@ -52,8 +90,9 @@ function createReadProgressGuard(options = {}) {
52
90
  }
53
91
 
54
92
  readCount += 1;
55
- const signatureCount = (commandCounts.get(inspection.signature) || 0) + 1;
56
- commandCounts.set(inspection.signature, signatureCount);
93
+ const signatureKey = inspection.fileKey + '\0' + inspection.signature;
94
+ const signatureCount = (commandCounts.get(signatureKey) || 0) + 1;
95
+ commandCounts.set(signatureKey, signatureCount);
57
96
  let overlapRatio = 0;
58
97
  let redundant = signatureCount > 1;
59
98
 
@@ -85,6 +124,7 @@ function createReadProgressGuard(options = {}) {
85
124
  });
86
125
 
87
126
  if (steerIssued) {
127
+ if (!steerAcknowledged) return noAction(evidence);
88
128
  postSteerRedundantStreak = redundant ? postSteerRedundantStreak + 1 : 0;
89
129
  if (postSteerRedundantStreak >= settings.postSteerRedundantStreak) {
90
130
  abortIssued = true;
@@ -101,12 +141,20 @@ function createReadProgressGuard(options = {}) {
101
141
  return noAction(evidence);
102
142
  },
103
143
 
144
+ acknowledgeSteer() {
145
+ if (steerIssued && !abortIssued) {
146
+ steerAcknowledged = true;
147
+ postSteerRedundantStreak = 0;
148
+ }
149
+ },
150
+
104
151
  snapshot() {
105
152
  return {
106
153
  readCount,
107
154
  redundantStreak,
108
155
  postSteerRedundantStreak,
109
156
  steerIssued,
157
+ steerAcknowledged,
110
158
  abortIssued
111
159
  };
112
160
  }
@@ -120,9 +168,15 @@ function createReadProgressController({ input = {}, request, fail, getTurn, emit
120
168
  });
121
169
  let pendingSteer = null;
122
170
  let steerInFlight = false;
171
+ let generation = 0;
123
172
 
124
173
  return {
125
174
  observe(item) {
175
+ if (item?.type === 'fileChange') {
176
+ generation += 1;
177
+ pendingSteer = null;
178
+ steerInFlight = false;
179
+ }
126
180
  const decision = guard.observe(item);
127
181
  if (decision.action === 'steer') {
128
182
  steer(decision);
@@ -153,6 +207,7 @@ function createReadProgressController({ input = {}, request, fail, getTurn, emit
153
207
  return;
154
208
  }
155
209
  steerInFlight = true;
210
+ const steerGeneration = generation;
156
211
  emitEvent('codex.no_progress.steered', 'Repeated file reads detected; asking Codex to synthesize', {
157
212
  ...decision.evidence,
158
213
  guardAction: 'steer'
@@ -165,7 +220,10 @@ function createReadProgressController({ input = {}, request, fail, getTurn, emit
165
220
  text: buildReadProgressSteerText(decision.evidence, input.mode),
166
221
  text_elements: []
167
222
  }]
223
+ }).then(() => {
224
+ if (steerGeneration === generation) guard.acknowledgeSteer();
168
225
  }).catch(error => {
226
+ if (steerGeneration !== generation) return;
169
227
  const progressError = createNoProgressError(decision.evidence);
170
228
  progressError.message += ` Automatic steering failed: ${String(error?.message || error).slice(0, 500)}`;
171
229
  fail(progressError);
@@ -175,30 +233,35 @@ function createReadProgressController({ input = {}, request, fail, getTurn, emit
175
233
 
176
234
  function extractReadInspection(item = {}, workspacePath = '') {
177
235
  if (item.type !== 'commandExecution') return null;
236
+ if (item.status && item.status !== 'completed') return null;
237
+ if (Number.isInteger(item.exitCode) && item.exitCode !== 0) return null;
178
238
  const command = String(item.command || '').trim();
179
239
  if (!command) return null;
240
+ const cwd = typeof item.cwd === 'string' && item.cwd ? path.resolve(workspacePath || '.', item.cwd) : workspacePath;
180
241
  const actions = Array.isArray(item.commandActions) ? item.commandActions : [];
181
- const readAction = actions.find(action => action?.type === 'read');
182
- if (!readAction && !looksLikeReadCommand(command)) return null;
183
-
242
+ const readActions = actions.filter(action => action?.type === 'read');
243
+ if (!readActions.length && !looksLikeReadCommand(command)) return null;
244
+ const paths = [...new Set(readActions.map(action => normalizeFileKey(action.path, cwd)).filter(Boolean))];
245
+ if (paths.length > 1) return null;
184
246
  const bounded = extractBoundedRange(command);
185
- const rawPath = bounded?.path || readAction?.path || '';
186
- const fileKey = normalizeFileKey(rawPath, workspacePath);
187
- const displayPath = safeDisplayPath(fileKey, workspacePath) || path.basename(fileKey) || 'project file';
188
- const range = bounded
189
- ? { startLine: bounded.startLine, endLine: bounded.endLine }
190
- : null;
247
+ const boundedKey = normalizeFileKey(bounded?.path, cwd);
248
+ if (boundedKey && paths[0] && boundedKey !== paths[0]) return null;
249
+ const fileKey = paths[0] || boundedKey;
250
+ if (!fileKey) return null;
191
251
  return {
192
- fileKey: fileKey || displayPath,
193
- displayPath,
194
- range,
252
+ fileKey,
253
+ displayPath: safeDisplayPath(fileKey, workspacePath) || path.basename(fileKey),
254
+ range: bounded && boundedKey === fileKey
255
+ ? { startLine: bounded.startLine, endLine: bounded.endLine } : null,
195
256
  signature: normalizeCommandSignature(command, workspacePath)
196
257
  };
197
258
  }
198
259
 
199
260
  function extractBoundedRange(command) {
200
261
  const source = String(command || '');
201
- const sedMatch = source.match(/\bsed\s+(?:-[A-Za-z]+\s+)*["']?(\d+)\s*,\s*(\d+)p["']?(?:\s+((?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|[^\s;&|]+)))?/i);
262
+ // Stream pagination and compound commands do not prove source-file ranges.
263
+ if (/[|;&<>\x60]/.test(source)) return null;
264
+ const sedMatch = source.match(/\bsed\s+(?:-[A-Za-z]+\s+)*["']?(\d+)\s*,\s*(\d+)p["']?\s+((?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|[^\s;&|]+))/i);
202
265
  if (sedMatch) {
203
266
  return normalizeRangeMatch(sedMatch[1], sedMatch[2], sedMatch[3]);
204
267
  }
@@ -212,13 +275,15 @@ function extractBoundedRange(command) {
212
275
  function normalizeRangeMatch(startValue, endValue, pathValue) {
213
276
  const startLine = Number(startValue);
214
277
  const endLine = Number(endValue);
278
+ const filePath = unquoteShellWord(pathValue);
279
+ if (!filePath || filePath === '-') return null;
215
280
  if (!Number.isSafeInteger(startLine) || !Number.isSafeInteger(endLine) || startLine < 1 || endLine < startLine) {
216
281
  return null;
217
282
  }
218
283
  return {
219
284
  startLine,
220
285
  endLine,
221
- path: unquoteShellWord(pathValue)
286
+ path: filePath
222
287
  };
223
288
  }
224
289
 
@@ -228,8 +293,9 @@ function looksLikeReadCommand(command) {
228
293
  }
229
294
 
230
295
  function normalizeFileKey(value, workspacePath) {
296
+ if (typeof value !== 'string') return '';
231
297
  const source = unquoteShellWord(value);
232
- if (!source) return '';
298
+ if (!source || source === '-' || source.startsWith('~') || /[$\x60*?\[\]{}]/.test(source)) return '';
233
299
  if (path.isAbsolute(source)) return path.normalize(source);
234
300
  return path.resolve(workspacePath || '.', source);
235
301
  }
@@ -355,6 +421,7 @@ module.exports = {
355
421
  createNoProgressError,
356
422
  createReadProgressController,
357
423
  createReadProgressGuard,
424
+ createRunEventScope,
358
425
  extractBoundedRange,
359
426
  extractReadInspection
360
427
  };