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
@@ -0,0 +1,380 @@
1
+ (function (root, factory) {
2
+ const api = factory();
3
+ if (typeof module === 'object' && module.exports) module.exports = api;
4
+ if (root) root.CodexOverleafSharedSessionsBackground = api;
5
+ })(typeof globalThis !== 'undefined' ? globalThis : this, function () {
6
+ 'use strict';
7
+ const MESSAGE = 'codex-overleaf/shared-sessions-v1';
8
+ const LOCK_PORT = 'codex-overleaf/shared-session-lock-v1';
9
+ const CHANGE_KEY = 'codex-overleaf-shared-sessions-changed-v1';
10
+ const HOSTS = ['overleaf.com', 'www.overleaf.com', 'cn.overleaf.com'];
11
+ const META_PREFIX = 'codex-overleaf-scoped-persistence-v1:';
12
+ const MAX_BYTES = 8 * 1024 * 1024;
13
+ const own = (value, key) => Object.prototype.hasOwnProperty.call(value || {}, key);
14
+ const clone = value => value === undefined ? undefined : JSON.parse(JSON.stringify(value));
15
+ const equal = (a, b) => JSON.stringify(a) === JSON.stringify(b);
16
+ const failure = (code, message) => Object.assign(new Error(message), { code });
17
+ function part(value) {
18
+ if (typeof value !== 'string' || !value.trim() || value.length > 256 || /[\0\r\n]/.test(value))
19
+ throw failure('shared_store_scope_invalid', 'The shared session identity is invalid.');
20
+ return value;
21
+ }
22
+ function scope(input) {
23
+ return { accountScopeId: part(input?.accountScopeId), projectId: typeof input?.projectId === 'string' ? input.projectId : '' };
24
+ }
25
+ function keyFor(kind, value) {
26
+ return kind === 'preferences' ? 'preferences'
27
+ : 'state:' + encodeURIComponent(value.accountScopeId);
28
+ }
29
+ function metaKey(value) {
30
+ return META_PREFIX + encodeURIComponent(value.accountScopeId) + ':' + encodeURIComponent(value.projectId);
31
+ }
32
+
33
+ // Three-way merge preserves changes made by another tab to untouched fields.
34
+ // Conflicting edits fail closed; removed records are never silently revived.
35
+ function mergeValue(base, current, incoming, field = '') {
36
+ if (equal(incoming, base)) return clone(current);
37
+ if (equal(current, base) || equal(current, incoming)) return clone(incoming);
38
+ if (field === 'updatedAt' || field === 'lastActivityAt')
39
+ return (Date.parse(current) || 0) >= (Date.parse(incoming) || 0) ? current : incoming;
40
+ if (Array.isArray(base) && Array.isArray(current) && Array.isArray(incoming)) {
41
+ if (['runs', 'pendingInputs'].includes(field)
42
+ && [base, current, incoming].every(items => items.every(item => item && typeof item.id === 'string')
43
+ && new Set(items.map(item => item.id)).size === items.length)) {
44
+ const before = new Map(base.map(item => [item.id, item]));
45
+ const latest = new Map(current.map(item => [item.id, item]));
46
+ const proposed = new Map(incoming.map(item => [item.id, item]));
47
+ const ids = [...current.map(item => item.id), ...incoming.map(item => item.id).filter(id => !latest.has(id))];
48
+ return ids.map(id => mergeValue(before.get(id), latest.get(id), proposed.get(id)))
49
+ .filter(item => item !== undefined);
50
+ }
51
+ const extendsBase = items => items.length >= base.length && base.every((item, i) => equal(item, items[i]));
52
+ if (extendsBase(current) && extendsBase(incoming)) {
53
+ const result = clone(current), seen = new Set(result.map(item => JSON.stringify(item)));
54
+ for (const item of incoming.slice(base.length)) {
55
+ const key = JSON.stringify(item);
56
+ if (!seen.has(key)) { result.push(clone(item)); seen.add(key); }
57
+ }
58
+ return result;
59
+ }
60
+ }
61
+ if (base && current && incoming && !Array.isArray(base) && !Array.isArray(current) && !Array.isArray(incoming)
62
+ && [base, current, incoming].every(value => typeof value === 'object')) {
63
+ const result = {};
64
+ for (const key of new Set([...Object.keys(base), ...Object.keys(current), ...Object.keys(incoming)])) {
65
+ if (key === 'sharedRevision') continue;
66
+ const value = mergeValue(base[key], current[key], incoming[key], key);
67
+ if (value !== undefined) Object.defineProperty(result, key, { value, enumerable: true, configurable: true, writable: true });
68
+ }
69
+ return result;
70
+ }
71
+ throw failure('shared_session_conflict', 'The same session was edited in another tab. Refresh its history before retrying; the local draft was kept.');
72
+ }
73
+
74
+ function createService(options = {}) {
75
+ const chromeApi = options.chromeApi, idb = options.indexedDB, ranges = options.IDBKeyRange;
76
+ const locks = new Map(), queues = new Map();
77
+ // Account-wide writes serialize cross-project clears and shared preference saves.
78
+ // IndexedDB transactions still provide the atomic boundary for session batches.
79
+ let opening;
80
+ function openDb() {
81
+ if (!opening) opening = new Promise((resolve, reject) => {
82
+ const request = idb.open('codex-overleaf-shared-sessions', 1);
83
+ request.onupgradeneeded = () => {
84
+ const db = request.result;
85
+ const sessions = db.createObjectStore('sessions', { keyPath: ['accountScopeId', 'id'] });
86
+ sessions.createIndex('account', 'accountScopeId');
87
+ sessions.createIndex('project', ['accountScopeId', 'projectId']);
88
+ db.createObjectStore('tombstones', { keyPath: ['accountScopeId', 'id'] });
89
+ db.createObjectStore('migrations', { keyPath: ['accountScopeId', 'origin'] });
90
+ };
91
+ request.onsuccess = () => resolve(request.result);
92
+ request.onerror = () => { opening = null; reject(request.error); };
93
+ });
94
+ return opening;
95
+ }
96
+ const readRequest = request => new Promise((resolve, reject) => {
97
+ request.onsuccess = () => resolve(request.result);
98
+ request.onerror = () => reject(request.error);
99
+ });
100
+ const finished = tx => new Promise((resolve, reject) => {
101
+ tx.oncomplete = () => resolve();
102
+ tx.onabort = tx.onerror = () => reject(tx.error || failure('shared_store_transaction_failed', 'The shared session transaction failed.'));
103
+ });
104
+ async function readOne(store, key) {
105
+ const db = await openDb();
106
+ return readRequest(db.transaction(store, 'readonly').objectStore(store).get(key));
107
+ }
108
+ function senderOrigin(sender) {
109
+ const url = new URL(sender?.url || sender?.tab?.url || '');
110
+ if (sender?.id !== chromeApi.runtime.id || !sender.tab || (sender.frameId != null && sender.frameId !== 0)
111
+ || url.protocol !== 'https:' || !HOSTS.includes(url.hostname) || !/^\/project(?:\/|$)/.test(url.pathname))
112
+ throw failure('forbidden_sender', 'Shared sessions require an authorized Overleaf project page.');
113
+ return url.origin;
114
+ }
115
+ function ensureLock(message, value, sender) {
116
+ const held = locks.get(keyFor('state', value));
117
+ if (!held || held.disconnected || held.token !== message.lockToken || held.tabId !== sender.tab.id)
118
+ throw failure('storage_lock_lost', 'The shared persistence lock was lost.');
119
+ }
120
+ async function notify(value, clientId) {
121
+ // A missed refresh notification must not turn a committed write into a failure.
122
+ await chromeApi.storage.local.set({ [CHANGE_KEY]: {
123
+ accountScopeId: value.accountScopeId, projectId: value.projectId,
124
+ clientId, nonce: crypto.randomUUID(), at: Date.now()
125
+ } }).catch(() => {});
126
+ }
127
+ async function list(value, after = '') {
128
+ const db = await openDb();
129
+ return new Promise((resolve, reject) => {
130
+ const result = []; let bytes = 0, last = after;
131
+ const cursor = db.transaction('sessions', 'readonly').objectStore('sessions')
132
+ .openCursor(ranges.bound([value.accountScopeId, after], [value.accountScopeId, '\uffff'], Boolean(after), false));
133
+ cursor.onerror = () => reject(cursor.error);
134
+ cursor.onsuccess = () => {
135
+ const item = cursor.result;
136
+ if (!item) { resolve({ records: result, next: '' }); return; }
137
+ const stored = item.value;
138
+ if (value.projectId && stored.projectId !== value.projectId) { item.continue(); return; }
139
+ const record = { ...stored.record, sharedRevision: stored.revision };
140
+ const size = JSON.stringify(record).length * 2;
141
+ if (result.length && (result.length >= 8 || bytes + size > MAX_BYTES)) {
142
+ resolve({ records: result, next: last }); return;
143
+ }
144
+ result.push(record); bytes += size; last = stored.id; item.continue();
145
+ };
146
+ });
147
+ }
148
+ async function legacyDeleted(record) {
149
+ const key = 'codexOverleafSessionTombstone:v2:' + encodeURIComponent(record.projectId) + ':' + encodeURIComponent(record.id);
150
+ const meta = metaKey(record);
151
+ const stored = await chromeApi.storage.local.get([key, meta, 'codexOverleafSessionTombstones']);
152
+ return Boolean(stored[key] || stored[meta]?.sessionTombstones?.[record.id]
153
+ || stored.codexOverleafSessionTombstones?.[record.projectId]?.includes(record.id));
154
+ }
155
+ function recoveryCopy(record, origin) {
156
+ const suffix = origin.replace(/^https:\/\//, '').replace(/\W/g, '-');
157
+ return { ...record, id: record.id.slice(0, 200) + ':recovered:' + suffix, codexThreadId: '', pendingInputs: [],
158
+ titleSource: 'manual', title: (record.title || 'Recovered session') + ' [' + suffix + ']',
159
+ runs: (record.runs || []).map(run => ({ ...run, forkSnapshot: true, codexThreadId: '',
160
+ status: run.status === 'running' ? 'interrupted' : run.status,
161
+ undoOperations: [], undoBaseFiles: [], undoExpectedFiles: [], undoTrackedChanges: [],
162
+ appliedOperations: [], trackedChangeCaptures: [], undoStatus: '' })) };
163
+ }
164
+ async function writeMany(message, value, importing, origin, sender) {
165
+ const entries = (importing ? [{ record: message.record }] : message.entries || [])
166
+ .map(entry => ({ record: clone(entry.record), base: clone(entry.base) }));
167
+ if (JSON.stringify(entries).length * 2 > MAX_BYTES * 3)
168
+ throw failure('shared_session_too_large', 'The session batch exceeds the shared storage transfer limit.');
169
+ for (const { record, base } of entries) {
170
+ if (!record || record.accountScopeId !== value.accountScopeId || record.projectId !== value.projectId)
171
+ throw failure('shared_store_scope_mismatch', 'The session does not belong to the captured account and project.');
172
+ part(record.id); part(record.projectId);
173
+ delete record.sharedRevision;
174
+ if (base && (base.id !== record.id || base.accountScopeId !== value.accountScopeId || base.projectId !== value.projectId))
175
+ throw failure('shared_store_scope_mismatch', 'The session baseline belongs to a different scope.');
176
+ }
177
+ if (importing && await legacyDeleted(entries[0].record)) return [];
178
+ ensureLock(message, value, sender);
179
+ const db = await openDb();
180
+ // Recheck after opening the database; a disconnected owner cannot commit.
181
+ ensureLock(message, value, sender);
182
+ return new Promise((resolve, reject) => {
183
+ const tx = db.transaction(['sessions', 'tombstones', 'migrations'], 'readwrite');
184
+ const store = tx.objectStore('sessions'), deleted = tx.objectStore('tombstones');
185
+ const results = []; let caught;
186
+ const abort = error => { caught = error; tx.abort(); };
187
+ tx.oncomplete = () => resolve(results);
188
+ tx.onabort = tx.onerror = () => reject(caught || tx.error || failure('shared_store_write_failed', 'The session could not be saved.'));
189
+ const marker = tx.objectStore('migrations').get([value.accountScopeId, '*']);
190
+ marker.onsuccess = () => {
191
+ for (const entry of entries) {
192
+ if (marker.result?.clearedAt && (importing || (Date.parse(entry.record.createdAt) || 0) <= marker.result.clearedAt)) {
193
+ if (importing) continue;
194
+ abort(failure('shared_session_deleted', 'This history was cleared and cannot be restored by a stale tab.'));
195
+ return;
196
+ }
197
+ putAt(entry.record, entry.base);
198
+ }
199
+ };
200
+ function putAt(candidate, base, copy = false) {
201
+ const key = [value.accountScopeId, candidate.id];
202
+ const tombstone = deleted.get(key);
203
+ tombstone.onsuccess = () => {
204
+ if (tombstone.result) {
205
+ if (importing) return;
206
+ abort(failure('shared_session_deleted', 'This session was deleted in another tab.')); return;
207
+ }
208
+ const request = store.get(key);
209
+ request.onsuccess = () => {
210
+ try {
211
+ const existing = request.result;
212
+ if (existing && existing.projectId !== candidate.projectId)
213
+ throw failure('shared_store_scope_mismatch', 'Session identity conflicts with another project.');
214
+ let next = candidate;
215
+ if (importing && existing) {
216
+ if (equal(existing.record, candidate) || copy) {
217
+ results.push({ ...existing.record, sharedRevision: existing.revision }); return;
218
+ }
219
+ putAt(recoveryCopy(candidate, origin), null, true); return;
220
+ }
221
+ if (existing) {
222
+ if (!base) throw failure('shared_session_conflict', 'Reload the session before updating existing history.');
223
+ // Keep the established first-durable-review-decision policy.
224
+ const reviewed = options.mergeSessionReviewState?.(candidate, existing.record, message.reviewRunIds || []) || candidate;
225
+ next = mergeValue(base, existing.record, reviewed);
226
+ } else if (base && !importing) {
227
+ throw failure('shared_session_deleted', 'The session no longer exists.');
228
+ }
229
+ const revision = (existing?.revision || 0) + 1;
230
+ store.put({ accountScopeId: value.accountScopeId, projectId: value.projectId,
231
+ id: next.id, record: next, revision });
232
+ results.push({ ...next, sharedRevision: revision });
233
+ } catch (error) { abort(error); }
234
+ };
235
+ };
236
+ }
237
+ });
238
+ }
239
+ async function erase(value, id, all, message, sender) {
240
+ const db = await openDb();
241
+ ensureLock(message, value, sender);
242
+ const tx = db.transaction(['sessions', 'tombstones', 'migrations'], 'readwrite');
243
+ const done = finished(tx), sessions = tx.objectStore('sessions'), tombstones = tx.objectStore('tombstones');
244
+ if (id) {
245
+ const request = sessions.get([value.accountScopeId, id]);
246
+ request.onsuccess = () => {
247
+ const existing = request.result;
248
+ if (existing && value.projectId && existing.projectId !== value.projectId) { tx.abort(); return; }
249
+ tombstones.put({ accountScopeId: value.accountScopeId, id, deletedAt: Date.now() });
250
+ sessions.delete([value.accountScopeId, id]);
251
+ };
252
+ } else {
253
+ const cursor = sessions.index('account').openCursor(ranges.only(value.accountScopeId));
254
+ cursor.onsuccess = () => {
255
+ const item = cursor.result;
256
+ if (!item) return;
257
+ if (all || item.value.projectId === value.projectId) {
258
+ tombstones.put({ accountScopeId: value.accountScopeId, id: item.value.id, deletedAt: Date.now() });
259
+ item.delete();
260
+ }
261
+ item.continue();
262
+ };
263
+ if (all) tx.objectStore('migrations').put({ accountScopeId: value.accountScopeId, origin: '*', clearedAt: Date.now() });
264
+ }
265
+ await done;
266
+ }
267
+ async function handle(message, sender) {
268
+ const origin = senderOrigin(sender), value = scope(message.scope);
269
+ const method = message.method;
270
+ if (method === 'list') return list(value, typeof message.after === 'string' ? message.after : '');
271
+ if (method === 'get') {
272
+ const record = await readOne('sessions', [value.accountScopeId, part(message.id)]);
273
+ return record && (!value.projectId || value.projectId === record.projectId)
274
+ ? { ...record.record, sharedRevision: record.revision } : null;
275
+ }
276
+ if (method === 'migration-status') {
277
+ const cleared = await readOne('migrations', [value.accountScopeId, '*']);
278
+ return cleared?.clearedAt ? { complete: true, clearedAt: cleared.clearedAt }
279
+ : await readOne('migrations', [value.accountScopeId, origin]) || { complete: false };
280
+ }
281
+ if (method === 'migration-complete') {
282
+ ensureLock(message, value, sender);
283
+ const db = await openDb(), tx = db.transaction('migrations', 'readwrite'), done = finished(tx);
284
+ tx.objectStore('migrations').put({ ...value, origin, complete: true, at: Date.now() });
285
+ await done; return { complete: true };
286
+ }
287
+ if (method === 'put' || method === 'import') {
288
+ const result = await writeMany(message, value, method === 'import', origin, sender);
289
+ if (result.length) await notify(value, message.clientId);
290
+ return result;
291
+ }
292
+ if (method === 'delete' || method === 'clear-project' || method === 'clear-account') {
293
+ if (method === 'clear-project') part(value.projectId);
294
+ await erase(value, method === 'delete' ? part(message.id) : '', method === 'clear-account', message, sender);
295
+ await notify(value, message.clientId); return true;
296
+ }
297
+ if (method === 'meta-read' || method === 'meta-write') {
298
+ const key = metaKey(value);
299
+ if (method === 'meta-read') return (await chromeApi.storage.local.get(key))[key] || {};
300
+ const held = locks.get(keyFor('state', value));
301
+ if (!held || held.token !== message.lockToken || held.tabId !== sender.tab.id)
302
+ throw failure('storage_lock_lost', 'The shared persistence lock was lost.');
303
+ await chromeApi.storage.local.set({ [key]: message.meta }); return message.meta;
304
+ }
305
+ throw failure('shared_store_method_invalid', 'Unsupported shared session operation.');
306
+ }
307
+ function connect(port) {
308
+ if (port.name !== LOCK_PORT) return;
309
+ try { senderOrigin(port.sender); } catch (_error) { port.disconnect(); return; }
310
+ let heldKey = '', job = null, closed = false;
311
+ function pump(key) {
312
+ if (locks.has(key)) return;
313
+ const queue = queues.get(key);
314
+ while (queue?.length) {
315
+ const next = queue.shift();
316
+ if (next.closed()) continue;
317
+ const token = crypto.randomUUID();
318
+ const held = { token, tabId: next.tabId, port: next.port, inFlight: 0, disconnected: false,
319
+ release() {
320
+ if (locks.get(key) !== held) return;
321
+ locks.delete(key); pump(key);
322
+ }
323
+ };
324
+ locks.set(key, held);
325
+ next.grant(token); return;
326
+ }
327
+ queues.delete(key);
328
+ }
329
+ port.onMessage.addListener(message => {
330
+ if (message?.type === 'ping') { port.postMessage({ type: 'pong' }); return; }
331
+ if (message?.type !== 'acquire' || job) return;
332
+ try {
333
+ const value = scope(message.scope), kind = message.kind === 'preferences' ? 'preferences' : 'state';
334
+ heldKey = keyFor(kind, value);
335
+ job = { port, tabId: port.sender.tab.id, closed: () => closed, grant: token => port.postMessage({ type: 'granted', token }) };
336
+ if (!queues.has(heldKey)) queues.set(heldKey, []);
337
+ queues.get(heldKey).push(job);
338
+ pump(heldKey);
339
+ } catch (_error) { port.disconnect(); }
340
+ });
341
+ port.onDisconnect.addListener(() => {
342
+ closed = true;
343
+ const held = locks.get(heldKey);
344
+ if (held?.port === port) {
345
+ held.disconnected = true;
346
+ if (!held.inFlight) held.release();
347
+ } else if (heldKey) pump(heldKey);
348
+ });
349
+ }
350
+ function install() {
351
+ chromeApi.runtime.onConnect.addListener(connect);
352
+ chromeApi.runtime.onMessage.addListener((message, sender, respond) => {
353
+ if (message?.type !== MESSAGE) return undefined;
354
+ let held;
355
+ try {
356
+ const candidate = locks.get(keyFor('state', scope(message.scope)));
357
+ if (candidate?.token === message.lockToken && candidate.tabId === sender?.tab?.id) {
358
+ held = candidate; held.inFlight += 1;
359
+ }
360
+ } catch (_error) { /* The handler returns the scoped validation error. */ }
361
+ handle(message, sender).then(result => respond({ ok: true, result }),
362
+ error => respond({ ok: false, error: { code: error.code || 'shared_store_unavailable',
363
+ message: error.code ? error.message : 'Shared session storage is unavailable.' } }))
364
+ .finally(() => {
365
+ if (!held) return;
366
+ held.inFlight -= 1;
367
+ if (held.disconnected && !held.inFlight) held.release();
368
+ });
369
+ return true;
370
+ });
371
+ }
372
+ return { install, handle };
373
+ }
374
+ function installBackground(chromeApi) {
375
+ const service = createService({ chromeApi, indexedDB, IDBKeyRange,
376
+ mergeSessionReviewState: globalThis.CodexOverleafStorageRunActions?.mergeSessionReviewState });
377
+ service.install(); return service;
378
+ }
379
+ return { createService, installBackground, mergeValue };
380
+ });