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
@@ -4,14 +4,18 @@
4
4
  require('./i18n'),
5
5
  require('./settlementFacts'),
6
6
  require('./runInputQueue'),
7
+ require('./selectionContext'),
7
8
  require('./lineReferences'),
8
9
  require('./pathRedaction'),
9
- require('./sessionTitle')
10
+ require('./sessionTitle'),
11
+ require('./runActivityModel'),
12
+ require('./subagentActivityModel'),
13
+ require('./writebackIntent')
10
14
  );
11
15
  } else {
12
16
  root.CodexOverleafModuleRegistry.define(
13
17
  'SessionState',
14
- ['I18n', 'SettlementFacts', 'RunInputQueue', 'LineReferences', 'PathRedaction', 'SessionTitle'],
18
+ ['I18n', 'SettlementFacts', 'RunInputQueue', 'SelectionContext', 'LineReferences', 'PathRedaction', 'SessionTitle', 'RunActivityModel', 'SubagentActivityModel', 'WritebackIntent'],
15
19
  factory
16
20
  );
17
21
  }
@@ -19,9 +23,13 @@
19
23
  i18n,
20
24
  SettlementFacts,
21
25
  RunInputQueue,
26
+ SelectionContext,
22
27
  LineReferences,
23
28
  PathRedaction,
24
- SessionTitle
29
+ SessionTitle,
30
+ RunActivityModel,
31
+ SubagentActivityModel,
32
+ WritebackIntent
25
33
  ) {
26
34
  'use strict';
27
35
 
@@ -232,6 +240,7 @@
232
240
  : fallbackState.speedTier,
233
241
  requireReviewing: session.requireReviewing !== false,
234
242
  focusFiles: normalizeFocusFiles(session.focusFiles),
243
+ selectionContext: SelectionContext.normalize(session.selectionContext),
235
244
  projectReferenceFiles: normalizeProjectReferenceFiles(session.projectReferenceFiles),
236
245
  codexThreadId: typeof session.codexThreadId === 'string' ? session.codexThreadId : '',
237
246
  forkedFromSessionId: typeof session.forkedFromSessionId === 'string' ? session.forkedFromSessionId : '',
@@ -319,6 +328,7 @@
319
328
  state.runs = Array.isArray(active.runs) ? active.runs : [];
320
329
  state.task = typeof active.task === 'string' ? active.task : '';
321
330
  state.focusFiles = normalizeFocusFiles(active.focusFiles);
331
+ state.selectionContext = SelectionContext.normalize(active.selectionContext);
322
332
  state.mode = normalizeMode(active.mode);
323
333
  state.requireReviewing = active.requireReviewing !== false;
324
334
 
@@ -354,6 +364,7 @@
354
364
  : DEFAULT_PANEL_STATE.speedTier,
355
365
  requireReviewing: overrides.requireReviewing !== false,
356
366
  focusFiles: normalizeFocusFiles(overrides.focusFiles),
367
+ selectionContext: SelectionContext.normalize(overrides.selectionContext),
357
368
  projectReferenceFiles: normalizeProjectReferenceFiles(overrides.projectReferenceFiles),
358
369
  codexThreadId: typeof overrides.codexThreadId === 'string' ? overrides.codexThreadId : '',
359
370
  forkedFromSessionId: typeof overrides.forkedFromSessionId === 'string' ? overrides.forkedFromSessionId : '',
@@ -592,7 +603,48 @@
592
603
  .slice(-20);
593
604
  }
594
605
 
606
+ function recordedRunFailure(run) {
607
+ const event = [...(Array.isArray(run?.events) ? run.events : [])].reverse()
608
+ .find(item => item && item.kind !== 'technical' && item.subagent !== true);
609
+ if (!event || event.status !== 'failed' || (event.kind && event.kind !== 'activity')
610
+ || event.streamRole || event.streamKey || event.guidanceId) return null;
611
+ if (!['Codex returned a result, but local post-processing of this run failed.',
612
+ 'Codex 已经返回了结果,但本地处理这一轮时出错了。'].includes(event.title)) return null;
613
+ const meta = RunActivityModel.capture(event);
614
+ // Capture encodes even an unscoped local event as [threadId, turnId].
615
+ const scoped = meta?.scope && meta.scope !== JSON.stringify(['', '']);
616
+ if (meta?.kind !== 'notice' || meta.state !== 'failed' || meta.id || scoped || meta.noticeSource) return null;
617
+ const ended = Date.parse(event.timestamp), started = Date.parse(run.startedAt);
618
+ if (!Number.isFinite(ended) || (Number.isFinite(started) && ended < started)) return null;
619
+ return event;
620
+ }
621
+
622
+ // On restore only: a run that already finished (finishedAt plus a terminal
623
+ // report as its last visible event) but was persisted as running by a stale
624
+ // status write. Live retries also carry an old finishedAt, so never in memory.
625
+ function recoverSettledRunningRun(run) {
626
+ if (run?.status !== 'running' || !Number.isFinite(Date.parse(run.finishedAt))) return run;
627
+ const last = [...(Array.isArray(run.events) ? run.events : [])].reverse()
628
+ .find(item => item && item.kind !== 'technical' && item.subagent !== true);
629
+ if (last?.kind !== 'report' || !['completed', 'failed'].includes(last.status)
630
+ || Date.parse(last.timestamp) > Date.parse(run.finishedAt)) return run;
631
+ return { ...run, status: last.status };
632
+ }
633
+
634
+ function recoverRecordedRunFailure(run, locale = i18n.DEFAULT_LOCALE) {
635
+ if (run?.status !== 'running') return run;
636
+ const event = recordedRunFailure(run);
637
+ if (!event) return run;
638
+ // This acknowledgement is emitted only by the parent's terminal catch.
639
+ // It survives a render failure that prevented the old owner from settling.
640
+ return { ...run, status: 'failed',
641
+ statusText: i18n.t(locale, 'processedFailed', { elapsed: '' }).trim(),
642
+ finishedAt: Number.isFinite(Date.parse(run.finishedAt)) ? run.finishedAt : event.timestamp };
643
+ }
644
+
595
645
  function normalizeRun(run, options = {}) {
646
+ if (options.restoreRunningRuns === true || options.recoverSettledRuns === true) run = recoverSettledRunningRun(run);
647
+ run = recoverRecordedRunFailure(run, options.locale);
596
648
  const shouldStopRestoredRun = options.restoreRunningRuns === true && run.status === 'running';
597
649
  const locale = options.locale || i18n.DEFAULT_LOCALE;
598
650
  const events = normalizeRunEvents(run.events);
@@ -622,12 +674,13 @@
622
674
  model: typeof run.model === 'string' ? run.model : '',
623
675
  reasoningEffort: typeof run.reasoningEffort === 'string' ? run.reasoningEffort : '',
624
676
  speedTier: typeof run.speedTier === 'string' ? run.speedTier : '',
625
- status: shouldStopRestoredRun ? 'interrupted' : normalizeRunStatus(run.status),
677
+ status: shouldStopRestoredRun ? 'interrupted' : normalizeRunStatus(run.status, run),
626
678
  statusText: shouldStopRestoredRun ? i18n.t(locale, 'restoredRunStoppedStatus') : sanitizeAssistantVisibleText(run.statusText),
627
679
  runProjectId: normalizeProjectPrefKey(run.runProjectId),
628
680
  startedAt: typeof run.startedAt === 'string' ? run.startedAt : '',
629
681
  finishedAt: shouldStopRestoredRun ? new Date().toISOString() : typeof run.finishedAt === 'string' ? run.finishedAt : '',
630
682
  events: events.slice(-MAX_RUN_EVENTS),
683
+ ...(run.subagents?.length ? { subagents: SubagentActivityModel.normalize(run.subagents, sanitizeAssistantVisibleText) } : {}),
631
684
  attachments: normalizeRunAttachments(run.attachments, STORAGE_DEFAULT_LIMITS),
632
685
  appliedOperations: Array.isArray(run.appliedOperations) ? run.appliedOperations : [],
633
686
  undoOperations: Array.isArray(run.undoOperations) ? run.undoOperations : [],
@@ -660,6 +713,7 @@
660
713
  normalized.trackedChangeCaptures = sanitizeAssistantVisibleValue(run.trackedChangeCaptures);
661
714
  }
662
715
  applyTrackedChangeStatus(normalized, run.trackedChangeStatus);
716
+ Object.assign(normalized, pickWritebackRecovery(run));
663
717
 
664
718
  return normalized;
665
719
  }
@@ -722,13 +776,20 @@
722
776
  'running',
723
777
  'completed',
724
778
  'failed',
779
+ 'cancelled',
725
780
  'interrupted',
726
781
  'background_completed',
727
782
  'needs_review_after_navigation',
728
783
  'abandoned_after_navigation'
729
784
  ]);
730
785
 
731
- function normalizeRunStatus(status) {
786
+ function normalizeRunStatus(status, run = {}) {
787
+ if (status === 'running' && recordedRunFailure(run)) return 'failed';
788
+ if (status === 'rejected') return 'cancelled';
789
+ // Older normalizers rewrote cancelled runs to pending or completed.
790
+ // Recover only with a terminal timestamp and an explicit plugin event.
791
+ if (['pending', 'completed'].includes(status) && Number.isFinite(Date.parse(run.finishedAt))
792
+ && Array.isArray(run.events) && run.events.some(RunActivityModel.isRoutineCancellationEvent)) return 'cancelled';
732
793
  if (VALID_RUN_STATUS.has(status)) return status;
733
794
  // Legacy persisted runs without an explicit status fall back to `completed`
734
795
  // (the historical default for the recovery branch); unknown values land on
@@ -753,6 +814,9 @@
753
814
  timestamp: typeof event.timestamp === 'string' ? event.timestamp : '',
754
815
  kind: typeof event.kind === 'string' ? event.kind : 'activity',
755
816
  technicalDetail: sanitizeAssistantVisibleValue(event.technicalDetail),
817
+ activity: RunActivityModel.capture(event, sanitizeAssistantVisibleText),
818
+ streamPhase: RunActivityModel.normalizePhase(event.streamPhase),
819
+ subagent: event.subagent === true ? true : undefined,
756
820
  guidanceId: sanitizeAssistantVisibleText(event.guidanceId),
757
821
  streamKey: sanitizeAssistantVisibleText(event.streamKey),
758
822
  streamRole: sanitizeAssistantVisibleText(event.streamRole)
@@ -1123,6 +1187,7 @@
1123
1187
  speedTier: normalizeSpeedTier(session.speedTier || fallbackState.speedTier),
1124
1188
  requireReviewing: session.requireReviewing !== false,
1125
1189
  focusFiles: normalizeFocusFiles(session.focusFiles),
1190
+ selectionContext: SelectionContext.normalize(session.selectionContext),
1126
1191
  projectReferenceFiles: normalizeProjectReferenceFiles(session.projectReferenceFiles),
1127
1192
  codexThreadId: typeof session.codexThreadId === 'string' ? session.codexThreadId : '',
1128
1193
  forkedFromSessionId: normalizeTextField(session.forkedFromSessionId, 160),
@@ -1196,6 +1261,7 @@
1196
1261
  }
1197
1262
 
1198
1263
  function compactRunForStorage(run, limits, keepUndoPayload, settlementFacts = null) {
1264
+ run = recoverRecordedRunFailure(run);
1199
1265
  const undoPayload = compactUndoPayload(run, limits, keepUndoPayload);
1200
1266
  const compact = {
1201
1267
  id: run.id,
@@ -1204,12 +1270,13 @@
1204
1270
  model: normalizeTextField(run.model, 80),
1205
1271
  reasoningEffort: typeof run.reasoningEffort === 'string' ? run.reasoningEffort : '',
1206
1272
  speedTier: typeof run.speedTier === 'string' ? run.speedTier : '',
1207
- status: normalizeRunStatus(run.status),
1273
+ status: normalizeRunStatus(run.status, run),
1208
1274
  statusText: summarizeTextForStorage(run.statusText, 'status text'),
1209
1275
  runProjectId: normalizeProjectPrefKey(run.runProjectId),
1210
1276
  startedAt: typeof run.startedAt === 'string' ? run.startedAt : '',
1211
1277
  finishedAt: typeof run.finishedAt === 'string' ? run.finishedAt : '',
1212
1278
  events: compactRunEvents(run.events, limits),
1279
+ ...(run.subagents?.length ? { subagents: SubagentActivityModel.normalize(run.subagents, sanitizeAssistantVisibleText) } : {}),
1213
1280
  attachments: compactRunAttachmentsForStorage(run.attachments, limits),
1214
1281
  appliedOperations: [],
1215
1282
  undoOperations: undoPayload.undoOperations,
@@ -1236,6 +1303,7 @@
1236
1303
  if (run.interruptedDraft) {
1237
1304
  compact.interruptedDraft = sanitizeAssistantVisibleValue(run.interruptedDraft);
1238
1305
  }
1306
+ Object.assign(compact, pickWritebackRecovery(run));
1239
1307
  if (VALID_TRACKED_CHANGE_STATUS.has(run.trackedChangeStatus)) {
1240
1308
  compact.trackedChangeStatus = run.trackedChangeStatus;
1241
1309
  }
@@ -1256,6 +1324,8 @@
1256
1324
  streamKey: typeof event.streamKey === 'string' ? event.streamKey : '',
1257
1325
  streamRole: typeof event.streamRole === 'string' ? event.streamRole : ''
1258
1326
  };
1327
+ compact.activity = RunActivityModel.capture(event, sanitizeAssistantVisibleText);
1328
+ compact.streamPhase = RunActivityModel.normalizePhase(event.streamPhase);
1259
1329
  if (event.subagent === true) {
1260
1330
  compact.subagent = true;
1261
1331
  }
@@ -1616,7 +1686,24 @@
1616
1686
  return new Blob([serialized]).size;
1617
1687
  }
1618
1688
 
1689
+ function pickWritebackRecovery(run = {}) {
1690
+ if (run.forkSnapshot === true || run.undoStatus === 'applied' || run.trackedChangeStatus === 'rejected') return {};
1691
+ const result = {};
1692
+ const retry = WritebackIntent.normalize(run.retryWriteback);
1693
+ if (retry && retry.runId === run.id && retry.projectId === normalizeProjectPrefKey(run.runProjectId)
1694
+ && retry.operations.every(op => (op.type === 'create' && typeof op.content === 'string')
1695
+ || (op.type === 'edit' && (op.patches?.length || typeof op.replaceAll === 'string')
1696
+ && retry.baseFiles.some(file => file.path === op.path))
1697
+ || (op.type === 'delete' && retry.baseFiles.some(file => file.path === op.path)))
1698
+ && !containsSecretLikeText(retry)) result.retryWriteback = retry;
1699
+ const check = WritebackIntent.normalizeSaveCheck(run.saveCheck);
1700
+ if (check && check.runId === run.id && check.projectId === normalizeProjectPrefKey(run.runProjectId)) result.saveCheck = check;
1701
+ if (typeof run.saveConfirmedAt === 'string' && Number.isFinite(Date.parse(run.saveConfirmedAt))) result.saveConfirmedAt = run.saveConfirmedAt;
1702
+ return result;
1703
+ }
1704
+
1619
1705
  return {
1706
+ pickWritebackRecovery,
1620
1707
  DEFAULT_PANEL_STATE,
1621
1708
  createSession,
1622
1709
  deleteSession,
@@ -1630,7 +1717,11 @@
1630
1717
  setActiveSession,
1631
1718
  updateActiveSession,
1632
1719
  normalizeRuns,
1720
+ normalizeRunStatus,
1721
+ recoverRecordedRunFailure,
1722
+ recoverSettledRunningRun,
1633
1723
  normalizeProjectReferenceFiles,
1724
+ normalizeSelectionContext: SelectionContext.normalize,
1634
1725
  prepareStateForStorage,
1635
1726
  estimateJsonBytes,
1636
1727
  computeSafeTaskSummary
@@ -0,0 +1,288 @@
1
+ (function (root, factory) {
2
+ if (typeof module === 'object' && module.exports) module.exports = factory();
3
+ else root.CodexOverleafModuleRegistry.define('SharedSessionBridge', [], factory);
4
+ })(typeof globalThis !== 'undefined' ? globalThis : this, function () {
5
+ 'use strict';
6
+ const MESSAGE = 'codex-overleaf/shared-sessions-v1';
7
+ const LOCK_PORT = 'codex-overleaf/shared-session-lock-v1';
8
+ const CHANGE_KEY = 'codex-overleaf-shared-sessions-changed-v1';
9
+ const BASE = Symbol('shared-session-base');
10
+ const failure = (code, message) => Object.assign(new Error(message), { code });
11
+ const clone = value => value == null ? value : JSON.parse(JSON.stringify(value));
12
+ const clean = record => {
13
+ const result = clone(record);
14
+ if (result) delete result.sharedRevision;
15
+ return result;
16
+ };
17
+
18
+ function createBridge(environment = globalThis) {
19
+ const chromeApi = environment.chrome;
20
+ const clientId = environment.crypto?.randomUUID?.() || 'page-' + Date.now() + '-' + Math.random();
21
+ const migrations = new Map(), baselines = new Map(), heldLocks = new Map();
22
+ let legacy, wrapped;
23
+ function enabled() {
24
+ return Boolean(chromeApi?.runtime?.sendMessage && chromeApi?.runtime?.connect
25
+ && environment.location?.protocol === 'https:'
26
+ && ['overleaf.com', 'www.overleaf.com', 'cn.overleaf.com'].includes(environment.location?.hostname)
27
+ && /^\/project(?:\/|$)/.test(environment.location?.pathname || ''));
28
+ }
29
+ function capture(projectId = '', accountScopeId) {
30
+ const current = environment.codexOverleafDeriveAccountScopeId?.();
31
+ if (!current || (accountScopeId && current !== accountScopeId))
32
+ throw failure('account_scope_unavailable', 'A stable matching Overleaf account is required for shared history.');
33
+ return { accountScopeId: current, projectId };
34
+ }
35
+ function assertScope(value) { capture(value.projectId, value.accountScopeId); }
36
+ const cacheKey = (value, id) => value.accountScopeId + ':' + id;
37
+ const lockKey = (kind, value) => kind === 'preferences' ? 'preferences' : 'state:' + value.accountScopeId;
38
+ async function request(method, value, args = {}) {
39
+ assertScope(value);
40
+ const lock = heldLocks.get(lockKey('state', value));
41
+ if (lock?.lost) throw failure('storage_lock_lost', 'The background storage connection was lost.');
42
+ const response = await chromeApi.runtime.sendMessage({
43
+ ...args, type: MESSAGE, method, scope: value, clientId, lockToken: lock?.token || ''
44
+ });
45
+ assertScope(value);
46
+ if (!response?.ok)
47
+ throw failure(response?.error?.code || 'shared_store_unavailable',
48
+ response?.error?.message || 'Shared history is unavailable. Reload the extension and this page.');
49
+ return response.result;
50
+ }
51
+
52
+ // Live ports own the locks. Worker/page termination releases them without
53
+ // allowing a stale client to silently fall back to an origin-local lock.
54
+ async function acquire(kind, value, work) {
55
+ assertScope(value);
56
+ const key = lockKey(kind, value), port = chromeApi.runtime.connect({ name: LOCK_PORT });
57
+ let timer, heartbeat, released = false, lock = null, rejectGrant;
58
+ const granted = new Promise((resolve, reject) => {
59
+ rejectGrant = reject;
60
+ port.onMessage.addListener(message => {
61
+ if (message?.type !== 'granted' || lock || released) return;
62
+ clearTimeout(timer);
63
+ lock = { token: message.token, lost: false };
64
+ heldLocks.set(key, lock);
65
+ resolve();
66
+ });
67
+ port.onDisconnect.addListener(() => {
68
+ // Read lastError to consume the runtime's disconnected-port warning.
69
+ void chromeApi.runtime.lastError;
70
+ if (lock) lock.lost = true;
71
+ if (!released) reject(failure('storage_lock_lost', 'The shared history lock disconnected.'));
72
+ });
73
+ timer = environment.setTimeout(() => reject(failure('storage_lock_timeout',
74
+ 'Another page is saving history. Retry after it finishes.')), 20000);
75
+ });
76
+ try {
77
+ heartbeat = environment.setInterval(() => {
78
+ try { port.postMessage({ type: 'ping' }); }
79
+ catch (_error) {
80
+ if (lock) lock.lost = true;
81
+ rejectGrant(failure('storage_lock_lost', 'The shared history lock disconnected.'));
82
+ }
83
+ }, 15000);
84
+ port.postMessage({ type: 'acquire', kind, scope: value });
85
+ await granted;
86
+ assertScope(value);
87
+ const result = await work();
88
+ assertScope(value);
89
+ if (lock.lost) throw failure('storage_lock_lost', 'The shared history lock was lost before completion.');
90
+ return result;
91
+ } finally {
92
+ released = true;
93
+ environment.clearTimeout(timer);
94
+ environment.clearInterval(heartbeat);
95
+ if (heldLocks.get(key) === lock) heldLocks.delete(key);
96
+ port.disconnect();
97
+ }
98
+ }
99
+ async function migrate(value) {
100
+ const account = value.accountScopeId;
101
+ if (!migrations.has(account)) {
102
+ const pending = (async () => {
103
+ const status = await request('migration-status', value);
104
+ if (status.complete) return;
105
+ if (!legacy) throw failure('shared_store_unavailable', 'Legacy history storage is not ready.');
106
+ // Read the original site DB once. Only explicitly owned records may
107
+ // cross origins. Unknown-account rows remain untouched for recovery.
108
+ const records = (await legacy.getAllSessions())
109
+ .filter(record => record?.accountScopeId === account && record.projectId && record.id);
110
+ await acquire('state', value, async () => {
111
+ for (const record of records) {
112
+ const recordScope = capture(record.projectId, account);
113
+ await request('import', recordScope, {
114
+ record: legacy.buildSessionRecord(record, { preserveRunActionPayload: true })
115
+ });
116
+ }
117
+ await request('migration-complete', value);
118
+ });
119
+ })();
120
+ migrations.set(account, pending);
121
+ pending.catch(() => { if (migrations.get(account) === pending) migrations.delete(account); });
122
+ }
123
+ await migrations.get(account);
124
+ assertScope(value);
125
+ }
126
+ async function withLock(kind, input, work) {
127
+ const value = capture(input.projectId, input.accountScopeId);
128
+ await migrate(value); // Before acquiring either lock: no migration/lock cycle.
129
+ return acquire(kind, value, work);
130
+ }
131
+ async function withWrite(value, work) {
132
+ await migrate(value);
133
+ const held = heldLocks.get(lockKey('state', value));
134
+ if (held) {
135
+ if (held.lost) throw failure('storage_lock_lost', 'The shared history lock was lost.');
136
+ return work();
137
+ }
138
+ return acquire('state', value, work);
139
+ }
140
+ function tag(record, value, adopt) {
141
+ if (!record) return record;
142
+ const base = clean(record);
143
+ if (adopt) baselines.set(cacheKey(value, record.id), base);
144
+ Object.defineProperty(record, BASE, { value: base, enumerable: true });
145
+ return record;
146
+ }
147
+ async function list(projectId = '', adopt = true) {
148
+ const value = capture(projectId);
149
+ await migrate(value);
150
+ const result = []; let after = '';
151
+ do {
152
+ const page = await request('list', value, { after });
153
+ for (const record of page.records) {
154
+ result.push(tag(record, value, adopt && !heldLocks.has(lockKey('state', value))));
155
+ }
156
+ after = page.next;
157
+ } while (after);
158
+ return result;
159
+ }
160
+ function adopt(records) {
161
+ const value = capture();
162
+ for (const record of records) {
163
+ if (record.accountScopeId === value.accountScopeId)
164
+ baselines.set(cacheKey(value, record.id), clean(record));
165
+ }
166
+ }
167
+ function hasLocalChanges(session) {
168
+ const base = baselines.get(cacheKey(capture(), session.id));
169
+ return Boolean(base && (session.updatedAt !== base.updatedAt || session.task !== base.task));
170
+ }
171
+ function wasStored(id) { return baselines.has(cacheKey(capture(), id)); }
172
+ async function put(records, options = {}) {
173
+ if (!records.length) return [];
174
+ const value = capture(records[0].projectId, records[0].accountScopeId);
175
+ if (records.some(record => record.projectId !== value.projectId || record.accountScopeId !== value.accountScopeId))
176
+ throw failure('shared_store_scope_mismatch', 'A session batch must belong to one account and project.');
177
+ return withWrite(value, async () => {
178
+ const entries = records.map(record => ({
179
+ record: clean(record),
180
+ base: record[BASE] || baselines.get(cacheKey(value, record.id)) || null
181
+ }));
182
+ const written = await request('put', value, { entries, reviewRunIds: options.reviewRunIds || [] });
183
+ // Keep the caller's submitted view as its merge baseline. A merged
184
+ // remote change has not necessarily been applied to the visible UI.
185
+ for (const entry of entries) baselines.set(cacheKey(value, entry.record.id), clean(entry.record));
186
+ return written;
187
+ });
188
+ }
189
+ async function get(id) {
190
+ const value = capture();
191
+ await migrate(value);
192
+ const record = await request('get', value, { id });
193
+ return tag(record, value, !heldLocks.has(lockKey('state', value)));
194
+ }
195
+ async function erase(method, projectId = '', id) {
196
+ const value = capture(projectId);
197
+ return withWrite(value, () => request(method, value, { id }));
198
+ }
199
+ function decorate(api) {
200
+ legacy = api;
201
+ wrapped = { ...api };
202
+ const route = (name, shared) => {
203
+ wrapped[name] = function (...args) {
204
+ return enabled() ? shared(...args) : api[name](...args);
205
+ };
206
+ };
207
+ route('buildSessionRecord', (input, options) => {
208
+ const record = api.buildSessionRecord(input, options);
209
+ const base = input[BASE] || baselines.get(cacheKey({ accountScopeId: record.accountScopeId }, record.id));
210
+ if (base) Object.defineProperty(record, BASE, { value: clone(base), enumerable: true });
211
+ return record;
212
+ });
213
+ route('getAllSessions', () => list());
214
+ route('getRecord', (store, id) => store === 'sessions' ? get(id) : api.getRecord(store, id));
215
+ route('getAllByIndex', async (store, index, value) => {
216
+ if (store !== 'sessions') return api.getAllByIndex(store, index, value);
217
+ const records = await list(index === 'projectId' ? value : '');
218
+ return records.filter(record => record[index] === value);
219
+ });
220
+ route('claimSessionsForAccount', async (projectId, accountScopeId, deleted = []) => {
221
+ capture(projectId, accountScopeId);
222
+ return (await list(projectId)).filter(record => !deleted.includes(record.id));
223
+ });
224
+ route('putRecord', async (store, record) =>
225
+ store === 'sessions' ? (await put([record]))[0] : api.putRecord(store, record));
226
+ route('putRecords', (store, records, options) =>
227
+ store === 'sessions' ? put(records, options) : api.putRecords(store, records));
228
+ route('deleteRecord', (store, id) =>
229
+ store === 'sessions' ? erase('delete', '', id) : api.deleteRecord(store, id));
230
+ route('deleteByIndex', async (store, index, value) => {
231
+ if (store !== 'sessions') return api.deleteByIndex(store, index, value);
232
+ if (index === 'projectId') return erase('clear-project', value);
233
+ for (const record of (await list()).filter(record => record[index] === value))
234
+ await erase('delete', record.projectId, record.id);
235
+ });
236
+ route('clearStore', store =>
237
+ store === 'sessions' ? erase('clear-account') : api.clearStore(store));
238
+ route('clearAllStores', async () => {
239
+ const value = capture();
240
+ await erase('clear-account');
241
+ // Preserve other accounts' legacy backups. Auxiliary stores remain
242
+ // site-local and retain their existing explicit clear-all semantics.
243
+ for (const record of await api.getAllSessions()) {
244
+ if (record.accountScopeId === value.accountScopeId) await api.deleteRecord('sessions', record.id);
245
+ }
246
+ for (const store of Object.keys(api.STORES)) if (store !== 'sessions') await api.clearStore(store);
247
+ baselines.clear();
248
+ });
249
+ route('listRecentProjectsAcrossAccount', async options => {
250
+ if (!options?.accountScopeId) return [];
251
+ capture('', options.accountScopeId);
252
+ return api.filterRecentProjectsAcrossAccount(await list(), options);
253
+ });
254
+ Object.assign(wrapped, {
255
+ sharedSessionsEnabled: enabled,
256
+ withSharedLock: withLock,
257
+ readSharedProjectSnapshot: projectId => list(projectId, false),
258
+ adoptSharedSessionBaseline: adopt,
259
+ hasUnpersistedSharedSession: hasLocalChanges,
260
+ wasSharedSessionStored: wasStored
261
+ });
262
+ return wrapped;
263
+ }
264
+ function subscribe(listener) {
265
+ if (!enabled() || !chromeApi.storage?.onChanged) return () => {};
266
+ const onChange = (changes, area) => {
267
+ const change = changes[CHANGE_KEY]?.newValue;
268
+ if (area !== 'local' || !change || change.clientId === clientId) return;
269
+ const account = environment.codexOverleafDeriveAccountScopeId?.();
270
+ if (account && change.accountScopeId === account) listener(change);
271
+ };
272
+ chromeApi.storage.onChanged.addListener(onChange);
273
+ return () => chromeApi.storage.onChanged.removeListener(onChange);
274
+ }
275
+ return { enabled, decorate, withLock, subscribe,
276
+ async readMeta(input) {
277
+ const value = capture(input.projectId, input.accountScopeId);
278
+ await migrate(value);
279
+ return request('meta-read', value);
280
+ },
281
+ async writeMeta(input, meta) {
282
+ const value = capture(input.projectId, input.accountScopeId);
283
+ return request('meta-write', value, { meta });
284
+ }
285
+ };
286
+ }
287
+ return { createBridge, ...createBridge() };
288
+ });