codex-overleaf-link 2.4.1 → 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 (324) hide show
  1. package/README.md +272 -314
  2. package/README.zh-CN.md +287 -329
  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 +507 -507
  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 +8330 -1349
  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 +48 -121
  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 +10 -1
  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 +186 -154
  42. package/extension/src/content/selectionContextView.js +300 -0
  43. package/extension/src/content/sessionPersistence.js +6 -1
  44. package/extension/src/content/settingsPanel.js +77 -52
  45. package/extension/src/content/settingsWorkbench.js +374 -0
  46. package/extension/src/content/sharedSessionViewSync.js +72 -0
  47. package/extension/src/content/subagentActivityView.js +195 -0
  48. package/extension/src/content/trackedChangeCaptureController.js +7 -3
  49. package/extension/src/content/updateNotice.js +121 -50
  50. package/extension/src/content/writebackController.js +257 -0
  51. package/extension/src/content/writebackOrchestrator.js +146 -141
  52. package/extension/src/content/writebackPlan.js +231 -0
  53. package/extension/src/content/writebackRecovery.js +122 -0
  54. package/extension/src/content/writingStyleSettings.js +576 -0
  55. package/extension/src/content/writtenChangesView.js +152 -0
  56. package/extension/src/page/binaryAssetUploader.js +97 -19
  57. package/extension/src/page/overleafProjectSnapshot.js +1 -0
  58. package/extension/src/page/referenceProjects.js +148 -0
  59. package/extension/src/page/saveState.js +14 -2
  60. package/extension/src/page/snapshotRouter.js +44 -13
  61. package/extension/src/page/textCoordinates.js +102 -0
  62. package/extension/src/page/textFileCreator.js +350 -59
  63. package/extension/src/page/trackedChangeCapture.js +42 -56
  64. package/extension/src/page/trackedChangeOwnership.js +198 -0
  65. package/extension/src/page/trackedChangeReplay.js +164 -0
  66. package/extension/src/page/trackedChangesLifecycle.js +135 -149
  67. package/extension/src/page/treeOperations.js +26 -2
  68. package/extension/src/page/writebackReceiptJournal.js +112 -0
  69. package/extension/src/page/writebackRouter.js +175 -135
  70. package/extension/src/pageBridge.js +56 -101
  71. package/extension/src/popup.js +203 -59
  72. package/extension/src/shared/agentTranscript.js +18 -4
  73. package/extension/src/shared/auditRecords.js +71 -0
  74. package/extension/src/shared/changeHistoryModel.js +94 -0
  75. package/extension/src/shared/compatibility.js +1 -1
  76. package/extension/src/shared/compileAdapter.js +42 -0
  77. package/extension/src/shared/failureReasons.js +20 -0
  78. package/extension/src/shared/globalPreferences.js +1 -1
  79. package/extension/src/shared/i18n.js +93 -25
  80. package/extension/src/shared/managedUpdateProjection.js +6 -3
  81. package/extension/src/shared/pageRpcContract.js +7 -1
  82. package/extension/src/shared/providerProfiles.js +109 -0
  83. package/extension/src/shared/runActivityModel.js +361 -0
  84. package/extension/src/shared/runExecutionSnapshot.js +8 -2
  85. package/extension/src/shared/runExecutionSnapshotCodec.js +16 -4
  86. package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
  87. package/extension/src/shared/selectionContext.js +28 -0
  88. package/extension/src/shared/sessionState.js +97 -6
  89. package/extension/src/shared/sharedSessionBridge.js +288 -0
  90. package/extension/src/shared/storageDb.js +22 -55
  91. package/extension/src/shared/storageMigration.js +3 -0
  92. package/extension/src/shared/storageRunActions.js +10 -4
  93. package/extension/src/shared/storageValuePruning.js +40 -0
  94. package/extension/src/shared/subagentActivityModel.js +174 -0
  95. package/extension/src/shared/undoOperations.js +87 -0
  96. package/extension/src/shared/updateConsent.js +37 -8
  97. package/extension/src/shared/writebackIntent.js +62 -0
  98. package/extension/src/shared/writebackSettlement.js +29 -10
  99. package/extension/src/shared/writingStyle.js +33 -0
  100. package/extension/styles/panel.css +1972 -384
  101. package/extension/styles/popup.css +110 -0
  102. package/native-host/src/anthropicBridgeRequest.js +2 -1
  103. package/native-host/src/codexModelRecovery.js +107 -0
  104. package/native-host/src/codexPromptAssembly.js +2 -0
  105. package/native-host/src/codexProviderLaunch.js +3 -3
  106. package/native-host/src/codexRuntimeIdentity.js +1 -0
  107. package/native-host/src/codexSessionRunner.js +106 -140
  108. package/native-host/src/codexSessionTiming.js +3 -0
  109. package/native-host/src/managedInstall.js +5 -4
  110. package/native-host/src/nativeEnvironment.js +70 -0
  111. package/native-host/src/nativeQuotas.js +15 -8
  112. package/native-host/src/overleafWorkspaceRules.js +16 -0
  113. package/native-host/src/processStopBarrier.js +80 -0
  114. package/native-host/src/providerModelCatalog.js +4 -3
  115. package/native-host/src/providerProfile.js +13 -1
  116. package/native-host/src/providerReasoning.js +9 -5
  117. package/native-host/src/providerStore.js +4 -0
  118. package/native-host/src/releaseTransport.js +14 -5
  119. package/native-host/src/selectionScope.js +58 -0
  120. package/native-host/src/skills/parallel-subagents/SKILL.md +31 -3
  121. package/native-host/src/skills/writing-style-builder/SKILL.md +146 -0
  122. package/native-host/src/subagentBroker.js +102 -98
  123. package/native-host/src/subagentTelemetry.js +316 -0
  124. package/native-host/src/subagentWorkspace.js +103 -0
  125. package/native-host/src/subagentWorkspacePath.js +31 -0
  126. package/native-host/src/taskRunnerRuntime.js +55 -5
  127. package/native-host/src/turnAttachments.js +113 -0
  128. package/native-host/src/updateManager.js +122 -12
  129. package/native-host/src/updateNetworkControl.js +75 -0
  130. package/native-host/src/updateTrust.js +21 -2
  131. package/native-host/src/vendor/pdfjs/LICENSE +177 -0
  132. package/native-host/src/vendor/pdfjs/SOURCE.txt +3 -0
  133. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  134. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  135. package/native-host/src/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
  136. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  137. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  138. package/native-host/src/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
  139. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  140. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  141. package/native-host/src/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  142. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  143. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  144. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  145. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  146. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  147. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  148. package/native-host/src/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
  149. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  150. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  151. package/native-host/src/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
  152. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  153. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  154. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  155. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  156. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  157. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  158. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  159. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  160. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  161. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  162. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  163. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  164. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  165. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  166. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  167. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  168. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  169. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  170. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  171. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  172. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  173. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  174. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  175. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  176. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  177. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  178. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  179. package/native-host/src/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
  180. package/native-host/src/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
  181. package/native-host/src/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  182. package/native-host/src/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  183. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  184. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  185. package/native-host/src/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  186. package/native-host/src/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  187. package/native-host/src/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  188. package/native-host/src/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  189. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  190. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  191. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  192. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  193. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  194. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  195. package/native-host/src/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
  196. package/native-host/src/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
  197. package/native-host/src/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
  198. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  199. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  200. package/native-host/src/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
  201. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  202. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  203. package/native-host/src/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
  204. package/native-host/src/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
  205. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  206. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  207. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  208. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  209. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  210. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  211. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  212. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  213. package/native-host/src/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
  214. package/native-host/src/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
  215. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  216. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  217. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  218. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  219. package/native-host/src/vendor/pdfjs/cmaps/H.bcmap +0 -0
  220. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  221. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  222. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  223. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  224. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  225. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  226. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  227. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  228. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  229. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  230. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  231. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  232. package/native-host/src/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
  233. package/native-host/src/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
  234. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  235. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  236. package/native-host/src/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
  237. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  238. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  239. package/native-host/src/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
  240. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  241. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  242. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  243. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  244. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  245. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  246. package/native-host/src/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
  247. package/native-host/src/vendor/pdfjs/cmaps/LICENSE +36 -0
  248. package/native-host/src/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
  249. package/native-host/src/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
  250. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  251. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  252. package/native-host/src/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
  253. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  254. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  255. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  256. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  257. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  258. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  259. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  260. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  261. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  262. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  263. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  264. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  265. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  266. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  267. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  268. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  269. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  270. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  271. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  272. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  273. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  274. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  275. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  276. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  277. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  278. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  279. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  280. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  281. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  282. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  283. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  284. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  285. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  286. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  287. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  288. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  289. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  290. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  291. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  292. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  293. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  294. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  295. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  296. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  297. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  298. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  299. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  300. package/native-host/src/vendor/pdfjs/cmaps/V.bcmap +0 -0
  301. package/native-host/src/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  302. package/native-host/src/vendor/pdfjs/pdf.mjs +26740 -0
  303. package/native-host/src/vendor/pdfjs/pdf.worker.mjs +62201 -0
  304. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  305. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  306. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  307. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  308. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  309. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  310. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  311. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  312. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  313. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  314. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  315. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
  316. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  317. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  318. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  319. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  320. package/native-host/src/writingStyleEvidence.js +102 -0
  321. package/native-host/src/writingStylePdfWorker.js +35 -0
  322. package/native-host/src/writingStyleProfile.js +165 -0
  323. package/native-host/src/writingStyleRuntime.js +447 -0
  324. package/package.json +1 -1
@@ -9,6 +9,105 @@
9
9
 
10
10
  const BUILTIN_PROVIDER_ID = 'builtin';
11
11
 
12
+ const PROVIDER_CONNECTIONS = {
13
+ kimi: {
14
+ anthropic: { baseUrl: 'https://api.moonshot.cn/anthropic', wireApiPreference: 'anthropic', authMode: 'bearer', reasoningAdapter: 'anthropic' },
15
+ chat: { baseUrl: 'https://api.moonshot.cn/v1', wireApiPreference: 'chat', authMode: 'bearer', reasoningAdapter: 'auto' }
16
+ },
17
+ glm: {
18
+ anthropic: { baseUrl: 'https://open.bigmodel.cn/api/anthropic', wireApiPreference: 'anthropic', authMode: 'bearer', reasoningAdapter: 'anthropic' },
19
+ chat: { baseUrl: 'https://open.bigmodel.cn/api/paas/v4', wireApiPreference: 'chat', authMode: 'bearer', reasoningAdapter: 'auto' }
20
+ },
21
+ deepseek: {
22
+ anthropic: { baseUrl: 'https://api.deepseek.com/anthropic', wireApiPreference: 'anthropic', authMode: 'x-api-key', reasoningAdapter: 'anthropic' },
23
+ chat: { baseUrl: 'https://api.deepseek.com', wireApiPreference: 'chat', authMode: 'bearer', reasoningAdapter: 'deepseek' }
24
+ }
25
+ };
26
+
27
+ // Shortcuts select a protocol-specific connection, never an active provider.
28
+ const PROVIDER_PRESETS = [
29
+ { id: 'custom', name: 'Custom connection', short: '+', baseUrl: '', wireApiPreference: 'auto' },
30
+ { id: 'openai-compatible', name: 'OpenAI-compatible API', short: 'API', baseUrl: '', wireApiPreference: 'auto' },
31
+ { id: 'anthropic-compatible', name: 'Anthropic-compatible API', short: 'API', baseUrl: '', wireApiPreference: 'anthropic', authMode: 'x-api-key', reasoningAdapter: 'anthropic' },
32
+ { id: 'kimi', name: 'Kimi', short: 'K', ...PROVIDER_CONNECTIONS.kimi.anthropic },
33
+ { id: 'glm', name: 'GLM', short: 'G', ...PROVIDER_CONNECTIONS.glm.anthropic },
34
+ { id: 'deepseek', name: 'DeepSeek', short: 'D', ...PROVIDER_CONNECTIONS.deepseek.anthropic }
35
+ ];
36
+ const MODEL_EFFORTS = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];
37
+
38
+ function getPresetConnectionInfo(baseUrl) {
39
+ const normalized = normalizeText(baseUrl).replace(/\/+$/, '');
40
+ for (const [id, variants] of Object.entries(PROVIDER_CONNECTIONS)) {
41
+ for (const connection of Object.values(variants)) {
42
+ if (normalized === connection.baseUrl) return { id, connection: { ...connection } };
43
+ }
44
+ }
45
+ return null;
46
+ }
47
+
48
+ function getPresetConnection(id, protocol) {
49
+ const variants = Object.prototype.hasOwnProperty.call(PROVIDER_CONNECTIONS, id)
50
+ ? PROVIDER_CONNECTIONS[id] : null;
51
+ const connection = variants && Object.prototype.hasOwnProperty.call(variants, protocol)
52
+ ? variants[protocol] : null;
53
+ return connection ? { ...connection } : null;
54
+ }
55
+
56
+ function getProviderPresets() {
57
+ return PROVIDER_PRESETS.map(preset => ({ ...preset }));
58
+ }
59
+
60
+ function buildPresetDraft(id) {
61
+ const preset = PROVIDER_PRESETS.find(item => item.id === id) || PROVIDER_PRESETS[0];
62
+ const { id: _id, short: _short, ...connection } = preset;
63
+ return { ...buildEmptyDraft(), ...connection,
64
+ name: preset.id === 'custom' ? 'Custom provider' : preset.name };
65
+ }
66
+
67
+ function updateDraftModel(draft, originalId, patch) {
68
+ const models = Array.isArray(draft.models) ? draft.models : [];
69
+ const existing = models.find(model => model.id === originalId);
70
+ const fail = (message, field) => { throw Object.assign(new Error(message), { field }); };
71
+ const id = normalizeText(patch.id);
72
+ if (!id || id.length > 200 || /[\0\r\n"&|<>^%!\x60]/.test(id))
73
+ fail('Enter a valid model ID (up to 200 characters).', 'id');
74
+ if (models.some(model => model.id === id && model.id !== originalId))
75
+ fail('This model ID is already configured.', 'id');
76
+ if (!existing && models.length >= 32) fail('A provider can contain up to 32 models.', 'id');
77
+ const contextWindow = Number(patch.contextWindow);
78
+ if (!Number.isSafeInteger(contextWindow) || contextWindow < 8192 || contextWindow > 4000000)
79
+ fail('Context window must be an integer between 8192 and 4000000.', 'contextWindow');
80
+ const maxOutputTokens = patch.maxOutputTokens === '' || patch.maxOutputTokens == null
81
+ ? null : Number(patch.maxOutputTokens);
82
+ if (maxOutputTokens !== null && (!Number.isSafeInteger(maxOutputTokens)
83
+ || maxOutputTokens < 256 || maxOutputTokens > 65536 || maxOutputTokens >= contextWindow))
84
+ fail('Output limit must be between 256 and 65536 and smaller than the context window.', 'maxOutputTokens');
85
+ const model = { ...existing, id, label: normalizeText(patch.label).slice(0, 200) || id,
86
+ contextWindow, maxOutputTokens,
87
+ inputModalities: normalizeInputModalities(patch.inputModalities),
88
+ supportsParallelToolCalls: patch.supportsParallelToolCalls === true,
89
+ upstreamResponseMode: normalizeUpstreamResponseMode(patch.upstreamResponseMode, true),
90
+ reasoningEfforts: MODEL_EFFORTS.filter(effort => patch.reasoningEfforts?.includes(effort)),
91
+ reasoningAdapter: patch.reasoningAdapter ? normalizeReasoningAdapter(patch.reasoningAdapter) : '',
92
+ reasoningCapability: patch.reasoningCapability ? normalizeReasoningCapability(patch.reasoningCapability)
93
+ : patch.reasoningEfforts?.length ? 'effort' : '',
94
+ baseInstructions: normalizeText(patch.baseInstructions).slice(0, 8000)
95
+ };
96
+ model.resolvedUpstreamResponseMode = model.upstreamResponseMode === existing?.upstreamResponseMode
97
+ ? existing.resolvedUpstreamResponseMode || '' : '';
98
+ return { ...draft,
99
+ models: existing ? models.map(item => item.id === originalId ? model : item) : [...models, model],
100
+ defaultModelId: !draft.defaultModelId || draft.defaultModelId === originalId ? id : draft.defaultModelId
101
+ };
102
+ }
103
+
104
+ function removeDraftModel(draft, id) {
105
+ const models = (draft.models || []).filter(model => model.id !== id);
106
+ return { ...draft, models, defaultModelId: draft.defaultModelId === id
107
+ ? models[0]?.id || '' : draft.defaultModelId };
108
+ }
109
+
110
+
12
111
  function normalizeCatalog(value = {}) {
13
112
  const providers = Array.isArray(value.providers)
14
113
  ? value.providers.map(normalizeProvider).filter(Boolean)
@@ -110,6 +209,9 @@
110
209
  upstreamResponseMode: normalizeUpstreamResponseMode(value?.upstreamResponseMode, true),
111
210
  resolvedUpstreamResponseMode: normalizeUpstreamResponseMode(value?.resolvedUpstreamResponseMode, false),
112
211
  contextWindow: normalizeInteger(value?.contextWindow) || 262144,
212
+ maxOutputTokens: value?.maxOutputTokens == null ? null : Math.min(65536, Math.max(256, normalizeInteger(value.maxOutputTokens))),
213
+ reasoningAdapter: value?.reasoningAdapter ? normalizeReasoningAdapter(value.reasoningAdapter) : '',
214
+ reasoningCapability: value?.reasoningCapability ? normalizeReasoningCapability(value.reasoningCapability) : '',
113
215
  supportsParallelToolCalls: value?.supportsParallelToolCalls === true,
114
216
  inputModalities: normalizeInputModalities(value?.inputModalities),
115
217
  baseInstructions: normalizeText(value?.baseInstructions)
@@ -286,6 +388,13 @@
286
388
 
287
389
  return {
288
390
  BUILTIN_PROVIDER_ID,
391
+ MODEL_EFFORTS,
392
+ getProviderPresets,
393
+ getPresetConnectionInfo,
394
+ getPresetConnection,
395
+ buildPresetDraft,
396
+ updateDraftModel,
397
+ removeDraftModel,
289
398
  buildBuiltinProvider,
290
399
  buildEmptyDraft,
291
400
  buildRunSelection,
@@ -0,0 +1,361 @@
1
+ (function initRunActivityModel(root, factory) {
2
+ if (typeof module === 'object' && module.exports) module.exports = factory();
3
+ else root.CodexOverleafModuleRegistry.define('RunActivityModel', [], factory);
4
+ })(typeof globalThis !== 'undefined' ? globalThis : window, function runActivityModelFactory() {
5
+ 'use strict';
6
+
7
+ // Project event facts. Cancellation recognition is also shared by history recovery.
8
+ const KINDS = new Set(['explore', 'command', 'edit', 'tool', 'sync', 'compile', 'notice', 'plan', 'agent', 'lifecycle', 'message']);
9
+ const STATES = new Set(['running', 'pending', 'completed', 'failed', 'warning', 'cancelled', 'skipped', 'triggered', 'unknown', 'info']);
10
+ const TERMINAL = new Set(['completed', 'failed', 'cancelled', 'skipped', 'warning', 'triggered', 'unknown']);
11
+ const NOTICE_SOURCES = new Set(['warning', 'guardianWarning', 'configWarning']);
12
+ const MAX_FILES = 12;
13
+ const text = value => typeof value === 'string' ? value : '';
14
+ const count = value => Number.isSafeInteger(value) && value >= 0 ? value : undefined;
15
+ const phase = value => ['commentary', 'final_answer'].includes(value) ? value : '';
16
+
17
+ function normalize(value, sanitize = text) {
18
+ if (!value || !KINDS.has(value.kind)) return undefined;
19
+ const clip = (input, limit) => text(sanitize(text(input))).slice(0, limit);
20
+ const paths = Array.isArray(value.paths) ? value.paths : [];
21
+ const files = Array.isArray(value.files) ? value.files : [];
22
+ const normalizedPaths = [...new Set(paths.map(path => clip(path, 320)).filter(Boolean))].slice(0, MAX_FILES);
23
+ const normalizedFiles = files.slice(0, MAX_FILES).filter(file => file && typeof file.path === 'string').map(file => ({
24
+ path: clip(file.path, 320),
25
+ operation: ['add', 'delete', 'update', 'move'].includes(file.operation) ? file.operation : 'update',
26
+ added: count(file.added),
27
+ removed: count(file.removed),
28
+ preview: clip(file.preview, 1800),
29
+ clipped: file.clipped === true || text(file.preview).length > 1800
30
+ }));
31
+ return {
32
+ v: 1, kind: value.kind, messagePhase: phase(value.messagePhase), id: clip(value.id, 600), scope: clip(value.scope, 400),
33
+ state: STATES.has(value.state) ? value.state : 'info',
34
+ action: ['read', 'search', 'list'].includes(value.action) ? value.action : '',
35
+ target: clip(value.target, 320), command: clip(value.command, 400),
36
+ output: clip(value.output, 1200), paths: normalizedPaths, files: normalizedFiles,
37
+ durationMs: count(value.durationMs), exitCode: Number.isSafeInteger(value.exitCode) ? value.exitCode : undefined,
38
+ written: count(value.written), skipped: count(value.skipped),
39
+ resolvedBy: clip(value.resolvedBy, 600),
40
+ noticeSource: NOTICE_SOURCES.has(value.noticeSource) ? value.noticeSource : '',
41
+ clipped: value.clipped === true || paths.length > MAX_FILES || files.length > MAX_FILES
42
+ || text(value.command).length > 400 || text(value.output).length > 1200
43
+ };
44
+ }
45
+
46
+ function changeSummary(change) {
47
+ if (!change || typeof change.path !== 'string') return null;
48
+ const diff = text(change.diff);
49
+ const lines = diff.split(/\r?\n/);
50
+ const isDiff = lines.some(line => line.startsWith('@@') || line.startsWith('diff --git')
51
+ || line.startsWith('+++ ') || line.startsWith('--- '));
52
+ const selected = lines.filter(line => line.startsWith('@@') || line.startsWith('+') || line.startsWith('-'));
53
+ return {
54
+ path: change.path,
55
+ operation: typeof change.kind === 'string' ? change.kind : change.kind?.type,
56
+ added: isDiff ? lines.filter(line => line.startsWith('+') && !line.startsWith('+++ ')).length : undefined,
57
+ removed: isDiff ? lines.filter(line => line.startsWith('-') && !line.startsWith('--- ')).length : undefined,
58
+ preview: (isDiff ? selected : lines).slice(0, 24).join('\n'),
59
+ clipped: (isDiff ? selected : lines).length > 24
60
+ };
61
+ }
62
+
63
+ // Start-up steps before the model's first response. Plugin titles are matched in both locales so
64
+ // persisted history (which drops technicalDetail) still classifies; `written` carries a file count.
65
+ const SETUP_TITLES = [
66
+ ['editing', /^(?:Checking Overleaf (?:Editing mode|Reviewing\/Track Changes) before starting\.|正在确认 Overleaf (?:Editing 模式|留痕状态)。)$/],
67
+ ['editing', /(?:Starting the task\.|开始处理任务。)$/],
68
+ ['read', /^(?:Syncing the Overleaf project to the local Codex workspace\.|正在同步 Overleaf 项目到本地 Codex workspace。)$/],
69
+ ['read', /^(?:Read Overleaf project: (\d+) text file|已读取 Overleaf 项目:(\d+) 个文本文件)/],
70
+ ['warm', /^(?:Using the warmed local workspace|使用已预热的本地 workspace)/],
71
+ ['workspace', /^(?:Syncing the Overleaf project into the local Codex workspace(?:: (\d+))?|正在同步 Overleaf 项目到本地 Codex workspace:(\d+)|Synced (\d+) text files\.|已同步 (\d+) 个文本文件)/],
72
+ ['codex', /^(?:Local Codex session is starting\.|本地 Codex session 开始运行。)$/],
73
+ ['codex', /^Using Codex CLI ([^;\s]+?)(?:;|\.?$)/],
74
+ ['hidden', /^Disabled non-Overleaf Codex skills/]
75
+ ];
76
+ function captureSetup(event, type, detail, sanitize) {
77
+ const title = text(event.title).trim();
78
+ let step = type.startsWith('overleaf.sync.') && type !== 'overleaf.sync.changes' ? 'workspace'
79
+ : type === 'codex.runtime.selected' ? 'codex' : type === 'codex.skill_isolation.applied' ? 'hidden' : '';
80
+ let match = null;
81
+ if (!step) for (const [name, pattern] of SETUP_TITLES) if ((match = pattern.exec(title))) { step = name; break; }
82
+ if (!step) return undefined;
83
+ const fileCount = Number(detail.fileCount) || Number(match?.slice(1).find(Boolean)) || undefined;
84
+ const version = text(detail.version) || (step === 'codex' && match?.[1]) || '';
85
+ return normalize({ kind: 'lifecycle', target: 'setup.' + step, state: event.status === 'running' ? 'running' : 'completed',
86
+ written: Number.isSafeInteger(fileCount) ? fileCount : undefined, output: version }, sanitize);
87
+ }
88
+
89
+ function capture(event = {}, sanitize = text) {
90
+ if (event.activity?.v === 1) return normalize(event.activity, sanitize);
91
+ if (event.kind === 'report' || event.kind === 'guidance' || event.kind === 'stream') return undefined;
92
+ const raw = event.technicalDetail || (event.kind === 'technical' ? event.detail : null) || {};
93
+ const detail = raw.detail || {};
94
+ const setup = event.kind === 'activity' || !event.kind ? captureSetup(event, text(raw.type), detail, sanitize) : undefined;
95
+ if (setup) return setup;
96
+ const params = detail.params || {};
97
+ const item = params.item || {};
98
+ const type = text(raw.type);
99
+ const method = text(detail.method);
100
+ const thread = text(params.threadId || detail.threadId);
101
+ const turn = text(params.turnId || detail.turnId);
102
+ const itemId = text(item.id || params.itemId || detail.itemId);
103
+ const scope = JSON.stringify([thread, turn]);
104
+ const id = itemId ? JSON.stringify([thread, turn, itemId]) : '';
105
+ const base = { id, scope, state: event.status };
106
+ if (NOTICE_SOURCES.has(method)) {
107
+ return normalize({ ...base, kind: 'notice', noticeSource: method,
108
+ output: text(params.details), state: event.status === 'failed' ? 'failed' : 'warning' }, sanitize);
109
+ }
110
+ if (item.type === 'commandExecution' || type.startsWith('codex.command.')) {
111
+ const actions = Array.isArray(item.commandActions || detail.commandActions)
112
+ ? (item.commandActions || detail.commandActions) : [];
113
+ const exploring = actions.length > 0 && actions.every(action => ['read', 'search', 'listFiles'].includes(action?.type));
114
+ const first = actions[0] || {};
115
+ const output = text(item.aggregatedOutput || detail.output);
116
+ return normalize({
117
+ ...base, kind: exploring ? 'explore' : 'command',
118
+ action: first.type === 'listFiles' ? 'list' : first.type,
119
+ paths: actions.map(action => text(action.path)).filter(Boolean),
120
+ target: first.path || first.query || first.name,
121
+ command: item.command || detail.command,
122
+ output: output.split(/\r?\n/).slice(-8).join('\n').slice(-1200),
123
+ clipped: output.length > 1200 || output.split(/\r?\n/).length > 8,
124
+ exitCode: item.exitCode ?? detail.exitCode,
125
+ durationMs: item.durationMs ?? detail.durationMs,
126
+ state: method === 'item/completed' || type.endsWith('.completed')
127
+ ? (item.status === 'failed' || event.status === 'failed' || Number(item.exitCode ?? detail.exitCode) > 0 ? 'failed' : 'completed')
128
+ : 'running'
129
+ }, sanitize);
130
+ }
131
+ if (item.type === 'fileChange' || method === 'item/fileChange/patchUpdated') {
132
+ const changes = Array.isArray(item.changes || params.changes) ? (item.changes || params.changes) : [];
133
+ const files = changes.map(changeSummary).filter(Boolean);
134
+ return normalize({
135
+ ...base, kind: 'edit', files, paths: files.map(file => file.path),
136
+ state: method === 'item/completed'
137
+ ? (item.status === 'failed' ? 'failed' : item.status === 'declined' ? 'skipped' : 'completed') : 'running'
138
+ }, sanitize);
139
+ }
140
+ if (['mcpToolCall', 'dynamicToolCall'].includes(item.type)) {
141
+ return normalize({ ...base, kind: 'tool', target: item.tool || item.server,
142
+ durationMs: item.durationMs, state: method === 'item/completed'
143
+ ? (item.status === 'failed' || item.success === false || item.error ? 'failed' : 'completed') : 'running' }, sanitize);
144
+ }
145
+ if (method === 'turn/plan/updated' || item.type === 'plan') {
146
+ const plan = Array.isArray(params.plan) ? params.plan : [];
147
+ return normalize({ ...base, kind: 'plan', id: id || scope + ':plan',
148
+ output: plan.map(step => text(step.status) + ': ' + text(step.step)).join('\n'),
149
+ state: method === 'item/completed' || (plan.length && plan.every(step => step.status === 'completed')) ? 'completed' : 'info' }, sanitize);
150
+ }
151
+ if (event.subagent || type.startsWith('codex.subagent.')) {
152
+ return normalize({ ...base, kind: 'agent', id: id || text(detail.jobId),
153
+ target: detail.label || detail.jobId }, sanitize);
154
+ }
155
+ if (method === 'turn/completed' || type === 'codex.agent.result') {
156
+ return normalize({ ...base, kind: 'lifecycle', target: 'local_completed' }, sanitize);
157
+ }
158
+ if (method === 'turn/started' || item.type === 'reasoning') {
159
+ return normalize({ ...base, kind: 'lifecycle', target: 'working' }, sanitize);
160
+ }
161
+ if (type === 'codex.agent.message') return normalize({ ...base, kind: 'message', messagePhase: detail.phase }, sanitize);
162
+ if (type === 'codex.session.request') {
163
+ // Some requests are resolved automatically. A log must not invent an approval gate.
164
+ return normalize({ ...base, kind: 'notice', state: 'info' }, sanitize);
165
+ }
166
+ if (event.failure || ['failed', 'warning', 'blocked'].includes(event.status)) {
167
+ return normalize({ ...base, kind: 'notice', state: event.status === 'failed' ? 'failed' : 'warning' }, sanitize);
168
+ }
169
+ return undefined;
170
+ }
171
+
172
+ function eventKey(event, index) {
173
+ return text(event.guidanceId || event.streamKey) || text(event.timestamp) + ':' + index;
174
+ }
175
+
176
+ function isAssistantMessage(event) {
177
+ return event?.kind === 'stream' && event.streamRole === 'assistant'
178
+ || event?.activity?.kind === 'message' || event?.technicalDetail?.type === 'codex.agent.message';
179
+ }
180
+
181
+ function isRoutineCancellationEvent(event) {
182
+ if (!event || event.failure || (event.kind && event.kind !== 'activity')
183
+ || event.streamRole || event.technicalDetail) return false;
184
+ const meta = event.activity;
185
+ if (meta?.v === 1 && meta.kind === 'lifecycle')
186
+ return meta.state === 'cancelled' && meta.target === 'cancelled';
187
+ if (meta && (meta.kind !== 'notice' || meta.id || meta.noticeSource)) return false;
188
+ // Exact plugin acknowledgements only: assistant prose and tool failures
189
+ // must never change the terminal state of a saved run.
190
+ return ['Current Codex task was cancelled.', '已中断当前 Codex 任务。',
191
+ 'Cancelled: user chose not to create a new thread.', '已取消:用户选择不新建线程。']
192
+ .includes(text(event.title).trim());
193
+ }
194
+
195
+ function isDiagnosticNotice(event, meta) {
196
+ if (isRoutineCancellationEvent(event)) return true;
197
+ if (meta?.kind !== 'notice' || event.failure || meta.state === 'failed'
198
+ || meta.noticeSource === 'guardianWarning') return false;
199
+ // Native advisory messages are not requests for user intervention. Fatal
200
+ // errors, writeback outcomes and safety warnings keep their own channels.
201
+ if (['warning', 'configWarning'].includes(meta.noticeSource)) return true;
202
+ // Old compacted records no longer have the native method. Only migrate
203
+ // known advisory copy; never guess that an unknown warning is harmless.
204
+ const title = text(event.title).trim();
205
+ return title === 'Codex returned a runtime notice.'
206
+ || title === 'Codex 返回了一条运行提示。'
207
+ || /^Codex is ignoring \d+ unrecognized configuration settings?\b/i.test(title);
208
+ }
209
+
210
+ function needsUserAttention(row) {
211
+ const meta = row.meta;
212
+ if (!['failed', 'warning'].includes(meta?.state) && !(row.kind === 'sync' && meta?.skipped > 0)) return false;
213
+ if (row.event.failure) return true;
214
+ if (['notice', 'sync', 'compile'].includes(row.kind)) return true;
215
+ if (row.kind === 'agent') return meta.state === 'warning';
216
+ // A failed local compilation affects the deliverable even if edits synced.
217
+ // Other tool attempts remain inspectable without becoming task warnings.
218
+ return row.kind === 'command'
219
+ && /(?:^|[\/\s"';&|])(?:latexmk|pdflatex|xelatex|lualatex|bibtex|biber)(?=\s|["']|$)/i.test(meta.command);
220
+ }
221
+
222
+ function project(run = {}, incoming, options = {}) {
223
+ const saved = Array.isArray(run.events) ? run.events : [];
224
+ const events = incoming && !saved.includes(incoming) ? saved.concat(incoming) : saved;
225
+ const ordered = [];
226
+ const diagnostics = [];
227
+ const diagnosticNotices = new Set();
228
+ const byId = new Map();
229
+ const report = events.filter(event => event?.kind === 'report').at(-1);
230
+ const finalText = text(report?.detailStructured?.conclusion
231
+ || report?.detail?.Conclusion || report?.detail?.['结论']).trim();
232
+ let lastAssistant = -1;
233
+ events.forEach((event, index) => {
234
+ if (isAssistantMessage(event)) lastAssistant = index;
235
+ });
236
+ let stage = 'preparing';
237
+ let clipped = false;
238
+ let previousAt = '';
239
+ // Start-up rows until the first thought, message or tool step: a running row is updated in place by its finish.
240
+ const setup = { steps: [], done: false, firstWorkAt: '' };
241
+ const startWork = event => {
242
+ if (setup.done) return;
243
+ setup.done = true;
244
+ setup.firstWorkAt = text(event.timestamp);
245
+ for (const entry of setup.steps) if (entry.state === 'running') Object.assign(entry, { state: 'completed', endAt: setup.firstWorkAt || entry.at });
246
+ };
247
+ const addSetupStep = (step, event, meta) => {
248
+ if (setup.done || step === 'hidden') return;
249
+ if (step === 'note') {
250
+ // Snapshot advisories ("Note: 1 file(s) have empty/loading content.") attach to the project read.
251
+ const owner = setup.steps.findLast(entry => entry.step === 'read') || setup.steps.at(-1);
252
+ if (owner) (owner.notes ||= []).push(text(event.title).trim().replace(/^(?:Note: |提示:)/, ''));
253
+ return;
254
+ }
255
+ const last = setup.steps.at(-1);
256
+ const state = meta?.state || (event.status === 'running' ? 'running' : 'completed');
257
+ const at = text(event.timestamp);
258
+ // A finished step closes any step still running before it (start-up is sequential).
259
+ for (const entry of setup.steps) if (entry.state === 'running' && entry.step !== step) Object.assign(entry, { state: 'completed', endAt: at });
260
+ const entry = { step, state, at, endAt: state === 'running' ? '' : at, count: meta?.written, version: meta?.output || '',
261
+ reviewing: /Reviewing|留痕/.test(text(event.title)) };
262
+ if (last && last.step === step && last.state === 'running') {
263
+ Object.assign(last, { ...entry, at: last.at, count: entry.count ?? last.count, version: entry.version || last.version });
264
+ } else setup.steps.push(entry);
265
+ };
266
+ events.forEach((event, index) => {
267
+ if (!event || event.kind === 'report') return;
268
+ const key = eventKey(event, index);
269
+ // A stream event keeps only its latest timestamp; the event before it marks when it began.
270
+ const startedAt = previousAt || text(event.timestamp);
271
+ previousAt = text(event.timestamp) || previousAt;
272
+ if (event.kind === 'guidance' || event.guidanceId || options.isGuidance?.(event)) {
273
+ const id = 'guidance:' + key;
274
+ const existing = byId.get(id);
275
+ if (existing) existing.event = event;
276
+ else { const row = { key: id, kind: 'guidance', event }; ordered.push(row); byId.set(id, row); }
277
+ return;
278
+ }
279
+ if (event.kind === 'stream' && event.streamRole === 'reasoning' && text(event.title).trim()) {
280
+ startWork(event);
281
+ ordered.push({ key: 'thought:' + key, kind: 'thought', event, startedAt });
282
+ stage = 'working';
283
+ return;
284
+ }
285
+ if (event.kind === 'stream' && event.streamRole !== 'assistant') { diagnostics.push({ key, event }); return; }
286
+ if (isAssistantMessage(event)) {
287
+ const body = text(event.title).trim();
288
+ const alreadyFinal = report && (phase(event.streamPhase || event.activity?.messagePhase) === 'final_answer'
289
+ || (index === lastAssistant && body && finalText
290
+ && (finalText === body || finalText.startsWith(body + '\n') || finalText.startsWith(body + ' '))));
291
+ if (!body || alreadyFinal) return;
292
+ startWork(event);
293
+ ordered.push({ key: 'message:' + key, kind: 'message', event });
294
+ stage = 'working';
295
+ return;
296
+ }
297
+ const meta = event.activity?.v === 1 ? event.activity : capture(event);
298
+ clipped ||= meta?.clipped === true;
299
+ if (isDiagnosticNotice(event, meta)) {
300
+ const noticeKey = JSON.stringify([meta?.noticeSource || '', event.title]);
301
+ if (!diagnosticNotices.has(noticeKey)) diagnostics.push({ key, event });
302
+ diagnosticNotices.add(noticeKey);
303
+ return;
304
+ }
305
+ if (meta?.kind === 'lifecycle' && meta.target.startsWith('setup.')) {
306
+ addSetupStep(meta.target.slice(6), event, meta);
307
+ diagnostics.push({ key, event });
308
+ return;
309
+ }
310
+ if (meta?.kind === 'lifecycle' && meta.target === 'working' && !setup.steps.some(entry => entry.step === 'waiting')) {
311
+ addSetupStep('waiting', event, { state: 'running' });
312
+ } else if (!meta && /^(?:Note: |提示:)/.test(text(event.title))) addSetupStep('note', event);
313
+ if (!meta || meta.kind === 'lifecycle' || event.kind === 'technical') {
314
+ diagnostics.push({ key, event });
315
+ if (meta?.kind === 'lifecycle') stage = meta.target;
316
+ return;
317
+ }
318
+ const identity = meta.id ? 'item:' + meta.scope + ':' + meta.id : 'event:' + key;
319
+ const previous = byId.get(identity);
320
+ if (previous) {
321
+ // Delayed start packets cannot regress an authoritative terminal item.
322
+ if (!(TERMINAL.has(previous.meta.state) && ['running', 'pending'].includes(meta.state))) {
323
+ previous.meta = { ...previous.meta, ...meta,
324
+ paths: meta.paths?.length ? meta.paths : previous.meta.paths,
325
+ files: meta.files?.length ? meta.files : previous.meta.files,
326
+ output: meta.output || previous.meta.output,
327
+ command: meta.command || previous.meta.command };
328
+ previous.event = event;
329
+ }
330
+ } else {
331
+ if (meta.kind !== 'notice') startWork(event);
332
+ const row = { key: identity, kind: meta.kind, meta, event, startedAt: event.timestamp };
333
+ byId.set(identity, row);
334
+ ordered.push(row);
335
+ }
336
+ stage = meta.kind === 'sync' || meta.kind === 'compile' ? meta.kind : 'working';
337
+ });
338
+ const blocks = [];
339
+ const notices = [];
340
+ const files = new Set();
341
+ for (const row of ordered) {
342
+ const meta = row.meta;
343
+ if (row.kind === 'edit' && meta.state === 'completed') for (const path of meta.paths || []) files.add(path);
344
+ const resolved = meta?.resolvedBy
345
+ && byId.get('item:' + meta.scope + ':' + meta.resolvedBy)?.meta.state === 'completed';
346
+ if (!resolved && needsUserAttention(row)) notices.push(row);
347
+ if (row.kind === 'explore') {
348
+ const prior = blocks.at(-1);
349
+ if (prior?.kind === 'exploreGroup' && prior.scope === meta.scope) prior.items.push(row);
350
+ else blocks.push({ key: 'explore:' + row.key, kind: 'exploreGroup', scope: meta.scope, items: [row] });
351
+ } else if (row.kind === 'edit' && meta.files?.length) {
352
+ for (const file of meta.files) blocks.push({ ...row, key: row.key + ':file:' + file.path, file });
353
+ } else blocks.push(row);
354
+ }
355
+ const legacy = diagnostics.some(({ event }) => event.kind !== 'technical' && !event.technicalDetail && !event.activity);
356
+ if (stage === 'local_completed') startWork({});
357
+ return { blocks, diagnostics, notices, stage, setup, fileCount: files.size, clipped, hasReport: Boolean(report), legacy };
358
+ }
359
+
360
+ return { normalize, capture, project, normalizePhase: phase, isRoutineCancellationEvent };
361
+ });
@@ -39,6 +39,9 @@
39
39
  let inferred = false;
40
40
  for (const field of Codec.TUPLE_FIELDS) {
41
41
  if (Codec.hasOwn(raw, field)) captured[field] = Codec.cloneValue(raw[field]);
42
+ // Old queued tasks never opted into a later selection or style profile.
43
+ // These references cannot be inferred from the current composer.
44
+ else if (field === 'writingStyle' || field === 'selectionContext') captured[field] = null;
42
45
  else {
43
46
  captured[field] = Codec.cloneValue(fallback[field]);
44
47
  inferred = true;
@@ -109,7 +112,9 @@
109
112
  speedTier: snapshot.speedTier,
110
113
  autoRecompile: snapshot.autoRecompile,
111
114
  requireReviewing: snapshot.requireReviewing,
112
- focusFiles: [...snapshot.focusFiles]
115
+ focusFiles: [...snapshot.focusFiles],
116
+ selectionContext: snapshot.selectionContext ? { ...snapshot.selectionContext } : null,
117
+ writingStyle: snapshot.writingStyle ? { ...snapshot.writingStyle } : null
113
118
  };
114
119
  }
115
120
 
@@ -135,7 +140,8 @@
135
140
  reasoningEffort: snapshot.reasoningEffort,
136
141
  speedTier: snapshot.speedTier,
137
142
  mode: snapshot.mode,
138
- focusFiles: [...snapshot.focusFiles]
143
+ focusFiles: [...snapshot.focusFiles],
144
+ selectionContext: snapshot.selectionContext ? { ...snapshot.selectionContext } : null
139
145
  };
140
146
  }
141
147
 
@@ -1,18 +1,28 @@
1
1
  (function initCodexOverleafRunExecutionSnapshotCodec(root, factory) {
2
2
  if (typeof module === 'object' && module.exports) {
3
- module.exports = factory();
3
+ module.exports = factory(require('./selectionContext'), require('./writingStyle'));
4
4
  } else {
5
- root.CodexOverleafRunExecutionSnapshotCodec = factory();
5
+ root.CodexOverleafModuleRegistry.define('RunExecutionSnapshotCodec', ['SelectionContext', 'WritingStyle'], factory);
6
6
  }
7
- })(typeof window !== 'undefined' ? window : globalThis, function runExecutionSnapshotCodecFactory() {
7
+ })(typeof window !== 'undefined' ? window : globalThis, function runExecutionSnapshotCodecFactory(SelectionContext, WritingStyle) {
8
8
  'use strict';
9
9
 
10
+ function normalizeSelectionContext(value) {
11
+ const selection = SelectionContext.normalize(value);
12
+ if (value != null && !selection) throw snapshotError('selected_context_unresolved', 'The captured selection is invalid. Attach it again.');
13
+ return selection;
14
+ }
15
+
16
+ function normalizeWritingStyle(value) {
17
+ return WritingStyle.normalizeSnapshot(value);
18
+ }
19
+
10
20
  const SCHEMA_VERSION = 1;
11
21
  const VALID_MODES = new Set(['ask', 'auto']);
12
22
  const VALID_SOURCES = new Set(['submitted', 'legacy-captured', 'legacy-inferred']);
13
23
  const TUPLE_FIELDS = Object.freeze([
14
24
  'mode', 'providerId', 'providerRevision', 'model', 'reasoningEffort',
15
- 'speedTier', 'autoRecompile', 'requireReviewing', 'focusFiles'
25
+ 'speedTier', 'autoRecompile', 'requireReviewing', 'focusFiles', 'selectionContext', 'writingStyle'
16
26
  ]);
17
27
  const SECRET_FIELD_PATTERN = /(?:api.?key|authorization|password|secret|access.?token|refresh.?token)/i;
18
28
 
@@ -36,6 +46,8 @@
36
46
  autoRecompile: input.autoRecompile !== false,
37
47
  requireReviewing: input.requireReviewing !== false,
38
48
  focusFiles: normalizePaths(input.focusFiles),
49
+ selectionContext: normalizeSelectionContext(input.selectionContext),
50
+ writingStyle: normalizeWritingStyle(input.writingStyle),
39
51
  capturedAt: normalizeTimestamp(input.capturedAt),
40
52
  source: VALID_SOURCES.has(options.source || input.source)
41
53
  ? (options.source || input.source)
@@ -1,14 +1,14 @@
1
1
  (function (root, factory) {
2
2
  if (typeof module === 'object' && module.exports) {
3
- module.exports = factory(require('./scopedPersistenceQueuePolicy'));
3
+ module.exports = factory(require('./scopedPersistenceQueuePolicy'), require('./sharedSessionBridge'));
4
4
  } else {
5
5
  root.CodexOverleafModuleRegistry.define(
6
6
  'ScopedPersistenceBrowserAdapter',
7
- ['ScopedPersistenceQueuePolicy'],
7
+ ['ScopedPersistenceQueuePolicy', 'SharedSessionBridge'],
8
8
  factory
9
9
  );
10
10
  }
11
- })(typeof globalThis !== 'undefined' ? globalThis : this, function (QueuePolicy) {
11
+ })(typeof globalThis !== 'undefined' ? globalThis : this, function (QueuePolicy, SharedSessions) {
12
12
  'use strict';
13
13
 
14
14
  var META_PREFIX = 'codex-overleaf-scoped-persistence-v1:';
@@ -42,6 +42,7 @@
42
42
  : (typeof navigator !== 'undefined' ? navigator.locks : null);
43
43
  return {
44
44
  async read(scope) {
45
+ if (SharedSessions.enabled()) return normalizeMeta(await SharedSessions.readMeta(scope));
45
46
  var key = scopeKey(scope);
46
47
  if (!chromeApi || !chromeApi.storage || !chromeApi.storage.local) {
47
48
  return normalizeMeta(fallbackMeta.get(key));
@@ -50,6 +51,7 @@
50
51
  return normalizeMeta(stored && stored[key]);
51
52
  },
52
53
  async write(scope, meta) {
54
+ if (SharedSessions.enabled()) return SharedSessions.writeMeta(scope, normalizeMeta(meta));
53
55
  var key = scopeKey(scope);
54
56
  var normalized = normalizeMeta(meta);
55
57
  if (!chromeApi || !chromeApi.storage || !chromeApi.storage.local) {
@@ -60,6 +62,7 @@
60
62
  return normalized;
61
63
  },
62
64
  withLock(scope, work) {
65
+ if (SharedSessions.enabled()) return SharedSessions.withLock('state', scope, work);
63
66
  var key = scopeKey(scope);
64
67
  if (locksApi && typeof locksApi.request === 'function') {
65
68
  return locksApi.request(key, { mode: 'exclusive' }, work);
@@ -0,0 +1,28 @@
1
+ (function (root, factory) {
2
+ if (typeof module === 'object' && module.exports) module.exports = factory();
3
+ else root.CodexOverleafModuleRegistry.define('SelectionContext', [], factory);
4
+ })(typeof globalThis !== 'undefined' ? globalThis : window, function () {
5
+ 'use strict';
6
+ const MAX_TEXT = 20000;
7
+ function normalize(value) {
8
+ if (!value || typeof value !== 'object') return null;
9
+ const path = typeof value.path === 'string' ? value.path.replace(/\\/g, '/') : '';
10
+ if (!path || path.startsWith('/') || /^[A-Za-z]:/.test(path)
11
+ || path.split('/').some(part => !part || part === '.' || part === '..')) return null;
12
+ if (typeof value.projectId !== 'string' || !value.projectId
13
+ || typeof value.text !== 'string' || !value.text.length || value.text.length > MAX_TEXT
14
+ || !Number.isSafeInteger(value.from) || !Number.isSafeInteger(value.to)
15
+ || value.from < 0 || value.to <= value.from || value.to - value.from !== value.text.length
16
+ || !/^[a-f0-9]{64}$/i.test(value.documentHash || '')) return null;
17
+ return Object.freeze({
18
+ projectId: value.projectId.slice(0, 160), path: path.slice(0, 320),
19
+ from: value.from, to: value.to, text: value.text,
20
+ lineStart: Number.isSafeInteger(value.lineStart) && value.lineStart > 0 ? value.lineStart : 1,
21
+ lineEnd: Number.isSafeInteger(value.lineEnd) && value.lineEnd > 0 ? value.lineEnd : 1,
22
+ documentHash: value.documentHash.toLowerCase(),
23
+ mode: value.mode === 'edit' ? 'edit' : 'reference',
24
+ capturedAt: typeof value.capturedAt === 'string' ? value.capturedAt.slice(0, 64) : ''
25
+ });
26
+ }
27
+ return { normalize, MAX_TEXT };
28
+ });