codex-overleaf-link 2.4.1 → 2.5.1

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 (397) hide show
  1. package/README.md +275 -305
  2. package/README.zh-CN.md +290 -320
  3. package/extension/bootstrap/background.js +99 -19
  4. package/extension/bootstrap/manifest.template.json +9 -4
  5. package/extension/bootstrap/popup.html +11 -16
  6. package/extension/bootstrap/popupFallback.js +55 -0
  7. package/extension/bootstrap/update.js +25 -2
  8. package/extension/bootstrap/updateStatus.js +1 -0
  9. package/extension/runtime-manifest.json +3 -1
  10. package/extension/src/background.js +234 -56
  11. package/extension/src/backgroundBootstrapMigration.js +181 -0
  12. package/extension/src/backgroundSharedSessions.js +440 -0
  13. package/extension/src/backgroundUpdateCoordinator.js +541 -381
  14. package/extension/src/backgroundUpdateSafety.js +173 -0
  15. package/extension/src/content/activeTurnControl.js +16 -2
  16. package/extension/src/content/applyResultFormatters.js +46 -73
  17. package/extension/src/content/assetTransferBroker.js +244 -12
  18. package/extension/src/content/changeHistoryView.js +175 -0
  19. package/extension/src/content/composerAttachments.js +117 -67
  20. package/extension/src/content/composerPanel.js +41 -8
  21. package/extension/src/content/contentRuntime.js +1084 -1099
  22. package/extension/src/content/diagnosticsController.js +122 -97
  23. package/extension/src/content/diagnosticsExport.js +236 -0
  24. package/extension/src/content/diagnosticsPanel.js +78 -19
  25. package/extension/src/content/diffReviewPanel.js +8 -5
  26. package/extension/src/content/directoryCleanupRecovery.js +54 -0
  27. package/extension/src/content/generated/content.bundle.js +14680 -3606
  28. package/extension/src/content/generated/content.bundle.meta.json +30 -3
  29. package/extension/src/content/globalPreferencesController.js +1 -1
  30. package/extension/src/content/legacyGlobalRegistry.js +25 -1
  31. package/extension/src/content/localSkillsPanel.js +141 -16
  32. package/extension/src/content/markdownDomRenderer.js +9 -4
  33. package/extension/src/content/markdownText.js +5 -6
  34. package/extension/src/content/modelPicker.js +8 -5
  35. package/extension/src/content/nativeCompatibilityController.js +45 -20
  36. package/extension/src/content/otWarmMirror.js +4 -5
  37. package/extension/src/content/otWarmMirrorController.js +17 -20
  38. package/extension/src/content/pageBridgeClient.js +33 -5
  39. package/extension/src/content/panelMaintenance.js +87 -132
  40. package/extension/src/content/panelRenderer.js +10 -0
  41. package/extension/src/content/pendingInputView.js +109 -76
  42. package/extension/src/content/projectProviderSelection.js +13 -4
  43. package/extension/src/content/projectSessionCleanup.js +109 -62
  44. package/extension/src/content/projectSettingsCoordinator.js +39 -2
  45. package/extension/src/content/providerSettingsCoordinator.js +63 -14
  46. package/extension/src/content/providerSettingsDialog.js +724 -113
  47. package/extension/src/content/recentProjects.js +21 -6
  48. package/extension/src/content/runActivitySummary.js +665 -0
  49. package/extension/src/content/runCompletionMeta.js +344 -0
  50. package/extension/src/content/runController.js +40 -15
  51. package/extension/src/content/runFailureNotice.js +34 -12
  52. package/extension/src/content/runGuidanceController.js +76 -30
  53. package/extension/src/content/runGuidanceView.js +59 -10
  54. package/extension/src/content/runPresence.js +306 -0
  55. package/extension/src/content/runQueueScheduler.js +150 -43
  56. package/extension/src/content/runRecoveryActions.js +146 -0
  57. package/extension/src/content/runResultActions.js +11 -8
  58. package/extension/src/content/runReviewController.js +574 -0
  59. package/extension/src/content/runScrollLayout.js +21 -2
  60. package/extension/src/content/runTimelineView.js +315 -290
  61. package/extension/src/content/scopedPersistencePanelState.js +51 -6
  62. package/extension/src/content/selectionContextView.js +300 -0
  63. package/extension/src/content/sensitivePreflight.js +140 -0
  64. package/extension/src/content/sessionForkController.js +80 -17
  65. package/extension/src/content/sessionManager.js +1 -1
  66. package/extension/src/content/sessionPersistence.js +6 -1
  67. package/extension/src/content/settingsPanel.js +84 -55
  68. package/extension/src/content/settingsWorkbench.js +379 -0
  69. package/extension/src/content/sharedSessionViewSync.js +109 -0
  70. package/extension/src/content/subagentActivityView.js +195 -0
  71. package/extension/src/content/trackedChangeCaptureController.js +7 -3
  72. package/extension/src/content/updateIdle.js +4 -1
  73. package/extension/src/content/updateNotice.js +179 -56
  74. package/extension/src/content/updateSafetyReceiver.js +58 -0
  75. package/extension/src/content/writebackController.js +308 -2
  76. package/extension/src/content/writebackOrchestrator.js +213 -199
  77. package/extension/src/content/writebackPlan.js +231 -0
  78. package/extension/src/content/writebackRecovery.js +122 -0
  79. package/extension/src/content/writingStyleSettings.js +600 -0
  80. package/extension/src/content/writtenChangesView.js +152 -0
  81. package/extension/src/page/binaryAssetUploader.js +223 -23
  82. package/extension/src/page/fileMover.js +256 -0
  83. package/extension/src/page/overleafProjectSnapshot.js +1 -0
  84. package/extension/src/page/ownedDirectoryCleanup.js +94 -0
  85. package/extension/src/page/referenceProjects.js +149 -0
  86. package/extension/src/page/reviewContext.js +113 -0
  87. package/extension/src/page/saveState.js +20 -6
  88. package/extension/src/page/snapshotRouter.js +124 -48
  89. package/extension/src/page/textCoordinates.js +102 -0
  90. package/extension/src/page/textFileCreator.js +442 -71
  91. package/extension/src/page/trackedChangeCapture.js +53 -57
  92. package/extension/src/page/trackedChangeOwnership.js +216 -0
  93. package/extension/src/page/trackedChangeReplay.js +184 -0
  94. package/extension/src/page/trackedChangesLifecycle.js +343 -339
  95. package/extension/src/page/treeOperations.js +33 -12
  96. package/extension/src/page/updateSafetyProbe.js +41 -0
  97. package/extension/src/page/writebackReceiptJournal.js +114 -0
  98. package/extension/src/page/writebackRouter.js +242 -201
  99. package/extension/src/pageBridge.js +73 -102
  100. package/extension/src/popup.js +261 -65
  101. package/extension/src/shared/agentTranscript.js +41 -4
  102. package/extension/src/shared/auditRecords.js +73 -0
  103. package/extension/src/shared/changeHistoryModel.js +94 -0
  104. package/extension/src/shared/compatibility.js +22 -6
  105. package/extension/src/shared/compileAdapter.js +101 -37
  106. package/extension/src/shared/composerAttachmentDraft.js +151 -0
  107. package/extension/src/shared/directoryCleanupProof.js +43 -0
  108. package/extension/src/shared/failureReasons.js +329 -3
  109. package/extension/src/shared/globalPreferences.js +31 -14
  110. package/extension/src/shared/governanceRules.js +4 -37
  111. package/extension/src/shared/i18n.js +389 -25
  112. package/extension/src/shared/managedUpdateProjection.js +8 -5
  113. package/extension/src/shared/nativeRequestIdentity.js +1 -0
  114. package/extension/src/shared/pageRpcContract.js +9 -2
  115. package/extension/src/shared/projectFiles.js +21 -44
  116. package/extension/src/shared/providerProfiles.js +114 -3
  117. package/extension/src/shared/runActivityModel.js +361 -0
  118. package/extension/src/shared/runExecutionSnapshot.js +8 -2
  119. package/extension/src/shared/runExecutionSnapshotCodec.js +16 -4
  120. package/extension/src/shared/runInputQueue.js +48 -5
  121. package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
  122. package/extension/src/shared/selectionContext.js +37 -0
  123. package/extension/src/shared/sessionState.js +166 -30
  124. package/extension/src/shared/settlementFacts.js +10 -2
  125. package/extension/src/shared/sharedSessionBridge.js +311 -0
  126. package/extension/src/shared/sharedSessionTransfer.js +140 -0
  127. package/extension/src/shared/staleGuard.js +118 -13
  128. package/extension/src/shared/storageDb.js +77 -78
  129. package/extension/src/shared/storageMigration.js +74 -111
  130. package/extension/src/shared/storageRunActions.js +211 -22
  131. package/extension/src/shared/storageValuePruning.js +40 -0
  132. package/extension/src/shared/subagentActivityModel.js +174 -0
  133. package/extension/src/shared/undoOperations.js +216 -6
  134. package/extension/src/shared/updateConsent.js +42 -11
  135. package/extension/src/shared/updateRuntimeIdentity.js +1 -1
  136. package/extension/src/shared/writebackIntent.js +78 -0
  137. package/extension/src/shared/writebackOperationEvidence.js +4 -15
  138. package/extension/src/shared/writebackSettlement.js +67 -48
  139. package/extension/src/shared/writingStyle.js +33 -0
  140. package/extension/styles/panel.css +1987 -385
  141. package/extension/styles/popup.css +110 -0
  142. package/native-host/src/anthropicBridgeRequest.js +6 -3
  143. package/native-host/src/anthropicBridgeResponse.js +6 -2
  144. package/native-host/src/anthropicMessagesBridge.js +24 -16
  145. package/native-host/src/bootstrapMigration.js +296 -0
  146. package/native-host/src/bootstrapMigrationContract.js +101 -0
  147. package/native-host/src/bootstrapUpdate.js +233 -0
  148. package/native-host/src/bootstrapUpdateWatchdog.js +44 -0
  149. package/native-host/src/chatBridgeResponse.js +10 -0
  150. package/native-host/src/chatCompletionsBridge.js +21 -15
  151. package/native-host/src/codexConfigPaths.js +106 -0
  152. package/native-host/src/codexHome.js +66 -73
  153. package/native-host/src/codexHomeScope.js +124 -0
  154. package/native-host/src/codexInheritedAuth.js +90 -0
  155. package/native-host/src/codexLocalSkills.js +301 -0
  156. package/native-host/src/codexModelRecovery.js +107 -0
  157. package/native-host/src/codexPromptAssembly.js +33 -12
  158. package/native-host/src/codexProviderLaunch.js +3 -3
  159. package/native-host/src/codexProviderTest.js +24 -26
  160. package/native-host/src/codexRuntimeIdentity.js +1 -0
  161. package/native-host/src/codexSessionRunner.js +211 -318
  162. package/native-host/src/codexSessionTiming.js +21 -8
  163. package/native-host/src/codexSkillIsolation.js +170 -0
  164. package/native-host/src/codexThreadFork.js +19 -3
  165. package/native-host/src/index.js +19 -7
  166. package/native-host/src/managedInstall.js +115 -39
  167. package/native-host/src/managedInstallRecovery.js +140 -0
  168. package/native-host/src/managedRuntimeEvidence.js +57 -0
  169. package/native-host/src/mirrorWorkspace.js +92 -22
  170. package/native-host/src/nativeDoctor.js +15 -0
  171. package/native-host/src/nativeEnvironment.js +70 -0
  172. package/native-host/src/nativeHelperLifecycle.js +21 -0
  173. package/native-host/src/nativeHostRegistration.js +33 -0
  174. package/native-host/src/nativeQuotas.js +15 -8
  175. package/native-host/src/nativeRunLifecycle.js +71 -0
  176. package/native-host/src/overleafWorkspaceRules.js +16 -0
  177. package/native-host/src/processStopBarrier.js +115 -0
  178. package/native-host/src/projectPathPlatform.js +30 -0
  179. package/native-host/src/providerHttp.js +80 -0
  180. package/native-host/src/providerModelCatalog.js +4 -3
  181. package/native-host/src/providerProfile.js +17 -3
  182. package/native-host/src/providerReasoning.js +10 -11
  183. package/native-host/src/providerRuntime.js +1 -0
  184. package/native-host/src/providerStore.js +76 -14
  185. package/native-host/src/releaseTransport.js +14 -5
  186. package/native-host/src/responsesPassthroughBridge.js +266 -52
  187. package/native-host/src/runtimeInstaller.js +21 -1
  188. package/native-host/src/selectionScope.js +86 -0
  189. package/native-host/src/skills/parallel-subagents/SKILL.md +31 -3
  190. package/native-host/src/skills/writing-style-builder/SKILL.md +146 -0
  191. package/native-host/src/subagentAdmission.js +26 -0
  192. package/native-host/src/subagentBroker.js +176 -159
  193. package/native-host/src/subagentTelemetry.js +325 -0
  194. package/native-host/src/subagentWorkspace.js +103 -0
  195. package/native-host/src/subagentWorkspacePath.js +34 -0
  196. package/native-host/src/taskRunnerRuntime.js +130 -57
  197. package/native-host/src/tomlStatements.js +140 -0
  198. package/native-host/src/turnAttachments.js +113 -0
  199. package/native-host/src/updateManager.js +406 -38
  200. package/native-host/src/updateNetworkControl.js +75 -0
  201. package/native-host/src/updateTrust.js +21 -2
  202. package/native-host/src/vendor/pdfjs/LICENSE +177 -0
  203. package/native-host/src/vendor/pdfjs/SOURCE.txt +3 -0
  204. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  205. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  206. package/native-host/src/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
  207. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  208. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  209. package/native-host/src/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
  210. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  211. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  212. package/native-host/src/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  213. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  214. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  215. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  216. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  217. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  218. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  219. package/native-host/src/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
  220. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  221. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  222. package/native-host/src/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
  223. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  224. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  225. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  226. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  227. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  228. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  229. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  230. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  231. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  232. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  233. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  234. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  235. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  236. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  237. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  238. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  239. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  240. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  241. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  242. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  243. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  244. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  245. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  246. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  247. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  248. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  249. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  250. package/native-host/src/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
  251. package/native-host/src/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
  252. package/native-host/src/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  253. package/native-host/src/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  254. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  255. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  256. package/native-host/src/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  257. package/native-host/src/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  258. package/native-host/src/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  259. package/native-host/src/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  260. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  261. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  262. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  263. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  264. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  265. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  266. package/native-host/src/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
  267. package/native-host/src/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
  268. package/native-host/src/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
  269. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  270. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  271. package/native-host/src/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
  272. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  273. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  274. package/native-host/src/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
  275. package/native-host/src/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
  276. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  277. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  278. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  279. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  280. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  281. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  282. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  283. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  284. package/native-host/src/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
  285. package/native-host/src/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
  286. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  287. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  288. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  289. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  290. package/native-host/src/vendor/pdfjs/cmaps/H.bcmap +0 -0
  291. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  292. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  293. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  294. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  295. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  296. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  297. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  298. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  299. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  300. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  301. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  302. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  303. package/native-host/src/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
  304. package/native-host/src/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
  305. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  306. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  307. package/native-host/src/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
  308. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  309. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  310. package/native-host/src/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
  311. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  312. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  313. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  314. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  315. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  316. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  317. package/native-host/src/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
  318. package/native-host/src/vendor/pdfjs/cmaps/LICENSE +36 -0
  319. package/native-host/src/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
  320. package/native-host/src/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
  321. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  322. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  323. package/native-host/src/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
  324. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  325. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  326. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  327. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  328. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  329. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  330. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  331. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  332. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  333. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  334. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  335. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  336. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  337. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  338. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  339. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  340. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  341. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  342. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  343. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  344. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  345. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  346. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  347. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  348. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  349. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  350. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  351. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  352. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  353. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  354. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  355. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  356. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  357. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  358. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  359. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  360. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  361. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  362. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  363. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  364. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  365. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  366. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  367. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  368. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  369. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  370. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  371. package/native-host/src/vendor/pdfjs/cmaps/V.bcmap +0 -0
  372. package/native-host/src/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  373. package/native-host/src/vendor/pdfjs/pdf.mjs +26740 -0
  374. package/native-host/src/vendor/pdfjs/pdf.worker.mjs +62201 -0
  375. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  376. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  377. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  378. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  379. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  380. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  381. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  382. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  383. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  384. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  385. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  386. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
  387. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  388. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  389. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  390. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  391. package/native-host/src/writingStyleEvidence.js +102 -0
  392. package/native-host/src/writingStylePdfWorker.js +35 -0
  393. package/native-host/src/writingStyleProfile.js +165 -0
  394. package/native-host/src/writingStyleRuntime.js +475 -0
  395. package/native-host/src/writingStyleStore.js +73 -0
  396. package/package.json +1 -1
  397. package/scripts/install-managed.mjs +1 -0
@@ -1,20 +1,26 @@
1
1
  'use strict';
2
2
 
3
+ globalThis.__CODEX_OVERLEAF_BOOTSTRAP_REVISION__ = '3.1';
4
+
3
5
  const CODEX_OVERLEAF_HOST = 'com.codex.overleaf';
4
6
  const RUNTIME_SCRIPT_ID = 'codex-overleaf-managed-runtime';
5
7
  const UPDATE_STATE_KEY = 'codex-overleaf-managed-update-state-v1';
6
8
  const UPDATE_RELOAD_TABS_KEY = 'codex-overleaf-managed-update-tabs-v1';
7
9
  const CHECK_ALARM = 'codex-overleaf-stable-update-check';
8
10
  const IDLE_ALARM = 'codex-overleaf-staged-update-idle';
9
- const OVERLEAF_EDITOR_MATCHES = [
10
- 'https://www.overleaf.com/project/*',
11
- 'https://overleaf.com/project/*'
12
- ];
13
- const OVERLEAF_MATCHES = [
11
+ // Built-in sites. The replaceable runtime manifest may list more; any extra
12
+ // site is used only after Chrome reports its permission as granted, so a later
13
+ // release can add an Overleaf site without changing this Bootstrap file.
14
+ const BUILT_IN_OVERLEAF_MATCHES = Object.freeze([
14
15
  'https://www.overleaf.com/project',
15
16
  'https://overleaf.com/project',
16
- ...OVERLEAF_EDITOR_MATCHES
17
- ];
17
+ 'https://cn.overleaf.com/project',
18
+ 'https://www.overleaf.com/project/*',
19
+ 'https://overleaf.com/project/*',
20
+ 'https://cn.overleaf.com/project/*'
21
+ ]);
22
+ let OVERLEAF_MATCHES = [...BUILT_IN_OVERLEAF_MATCHES];
23
+ let OVERLEAF_HOSTS = hostsOf(OVERLEAF_MATCHES);
18
24
  const APPLYING_STATES = new Set(['applying', 'awaiting_health', 'rolling_back']);
19
25
  const FAST_IDLE_RETRY_BLOCKERS = new Set(['recent_user_activity', 'save_state_not_stable']);
20
26
  const FAST_IDLE_RETRY_MS = 4000;
@@ -58,6 +64,10 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
58
64
  return undefined;
59
65
  });
60
66
 
67
+ // A newly granted site starts working without a reload or reinstall.
68
+ chrome.permissions?.onAdded?.addListener(() => { registerManagedRuntime().catch(() => {}); });
69
+ chrome.permissions?.onRemoved?.addListener(() => { registerManagedRuntime().catch(() => {}); });
70
+
61
71
  chrome.alarms.onAlarm.addListener(alarm => {
62
72
  if (alarm.name === CHECK_ALARM) {
63
73
  checkAndStage().catch(() => {});
@@ -67,7 +77,7 @@ chrome.alarms.onAlarm.addListener(alarm => {
67
77
  }
68
78
  });
69
79
 
70
- initializeBootstrap().catch(async error => {
80
+ globalThis.__CODEX_OVERLEAF_BOOTSTRAP_READY__ = initializeBootstrap().catch(async error => {
71
81
  await setUpdateState({ state: 'failed', code: safeCode(error), message: safeMessage(error) });
72
82
  });
73
83
 
@@ -83,6 +93,8 @@ async function initializeBootstrap() {
83
93
  return;
84
94
  }
85
95
 
96
+ const migration = await globalThis.CodexOverleafBootstrapMigration?.ready?.();
97
+ if (migration?.continueInitialization === false) return;
86
98
  const nativeStatus = await requestInternal({ method: 'update.status', params: {} }).catch(() => null);
87
99
  const transaction = nativeStatus?.ok ? nativeStatus.result?.transaction : null;
88
100
  if (transaction?.state === 'awaiting_health') {
@@ -105,6 +117,10 @@ async function registerManagedRuntime() {
105
117
  }
106
118
  const manifest = await response.json();
107
119
  validateRuntimeManifest(manifest);
120
+ const matches = await grantedMatches(manifest.matches);
121
+ if (!matches.length) throw new Error('No Overleaf site in the runtime manifest is permitted.');
122
+ OVERLEAF_MATCHES = [...new Set([...BUILT_IN_OVERLEAF_MATCHES, ...matches])];
123
+ OVERLEAF_HOSTS = hostsOf(OVERLEAF_MATCHES);
108
124
  managedRuntimeAssets = {
109
125
  js: ['bootstrap/runtimeContext.js', ...manifest.js.map(value => 'runtime/' + value)],
110
126
  css: manifest.css.map(value => 'runtime/' + value)
@@ -115,7 +131,7 @@ async function registerManagedRuntime() {
115
131
  }
116
132
  await chrome.scripting.registerContentScripts([{
117
133
  id: RUNTIME_SCRIPT_ID,
118
- matches: manifest.matches,
134
+ matches,
119
135
  js: managedRuntimeAssets.js,
120
136
  css: managedRuntimeAssets.css,
121
137
  runAt: manifest.runAt || 'document_idle',
@@ -127,7 +143,7 @@ function validateRuntimeManifest(manifest) {
127
143
  if (!manifest || manifest.schemaVersion !== 1 || !Array.isArray(manifest.matches) || !Array.isArray(manifest.js) || !Array.isArray(manifest.css)) {
128
144
  throw new Error('Managed runtime manifest is invalid.');
129
145
  }
130
- if (!manifest.matches.length || manifest.matches.some(value => !OVERLEAF_MATCHES.includes(value))) {
146
+ if (!manifest.matches.length || manifest.matches.some(value => !isProjectMatch(value))) {
131
147
  throw new Error('Managed runtime match patterns are invalid.');
132
148
  }
133
149
  const paths = [...manifest.js, ...manifest.css];
@@ -303,11 +319,36 @@ async function probeTabIdle(tab) {
303
319
  return { idle: false, blockers: ['tab_probe_unavailable'] };
304
320
  }
305
321
 
322
+ // Only project pages on overleaf.com or one of its subdomains: the same scope
323
+ // as optional_host_permissions and web_accessible_resources in the manifest.
324
+ function isProjectMatch(value) {
325
+ return typeof value === 'string'
326
+ && /^https:\/\/(?:[a-z0-9-]+\.)*overleaf\.com\/project(?:\/\*)?$/.test(value);
327
+ }
328
+
329
+ function hostsOf(matches) {
330
+ return new Set(matches.map(value => {
331
+ try { return new URL(value.replace(/\*$/, '')).host; } catch (_error) { return ''; }
332
+ }).filter(Boolean));
333
+ }
334
+
335
+ // Built-in sites are granted at install; a site a later runtime adds only
336
+ // counts once the user has approved Chrome's prompt for it (see the popup).
337
+ async function grantedMatches(matches) {
338
+ const result = [];
339
+ for (const value of matches) {
340
+ if (BUILT_IN_OVERLEAF_MATCHES.includes(value)) { result.push(value); continue; }
341
+ const granted = await chrome.permissions.contains({ origins: [value] }).catch(() => false);
342
+ if (granted) result.push(value);
343
+ }
344
+ return result;
345
+ }
346
+
306
347
  function isEditorProjectTab(tab) {
307
348
  try {
308
349
  const url = new URL(tab?.url || '');
309
350
  return url.protocol === 'https:' &&
310
- (url.hostname === 'www.overleaf.com' || url.hostname === 'overleaf.com') &&
351
+ OVERLEAF_HOSTS.has(url.host) &&
311
352
  /^\/project\/[^/]+(?:\/|$)/.test(url.pathname);
312
353
  } catch (_error) {
313
354
  return false;
@@ -344,12 +385,12 @@ async function confirmPendingUpdate(transaction) {
344
385
  const targetVersion = transaction.targetVersion;
345
386
  const runtimeHealthy = await verifyPendingRuntimeHealth(targetVersion);
346
387
  if (!runtimeHealthy) {
347
- await rollbackBrokenRuntime(new Error('Updated Overleaf content runtime did not report the target version.'));
388
+ await rollbackBrokenRuntime(new Error('Updated Overleaf content runtime did not report the target version.'), transaction);
348
389
  return;
349
390
  }
350
391
  const ping = await requestInternal({ method: 'bridge.ping', params: {} }).catch(() => null);
351
392
  if (!ping?.ok || ping.result?.version !== targetVersion) {
352
- await rollbackBrokenRuntime(new Error('Updated native host did not report the target version.'));
393
+ await rollbackBrokenRuntime(new Error('Updated native host did not report the target version.'), transaction);
353
394
  return;
354
395
  }
355
396
  const native = ping.result || {};
@@ -362,19 +403,20 @@ async function confirmPendingUpdate(transaction) {
362
403
  native.protocolVersion < protocolRange.min ||
363
404
  native.protocolVersion > protocolRange.max ||
364
405
  missingCapabilities.length) {
365
- await rollbackBrokenRuntime(new Error('Updated native host did not pass protocol and capability health checks.'));
406
+ await rollbackBrokenRuntime(new Error('Updated native host did not pass protocol and capability health checks.'), transaction);
366
407
  return;
367
408
  }
368
409
  const confirmed = await requestInternal({
369
410
  method: 'update.confirm',
370
411
  params: {
371
412
  transactionId: transaction.id,
413
+ bootstrapRevision: String(globalThis.__CODEX_OVERLEAF_BOOTSTRAP_REVISION__ || ''),
372
414
  extensionVersion: chrome.runtime.getManifest().version,
373
415
  nativeVersion: ping.result.version
374
416
  }
375
417
  });
376
418
  if (!confirmed?.ok) {
377
- await rollbackBrokenRuntime(nativeError(confirmed));
419
+ await rollbackBrokenRuntime(nativeError(confirmed), transaction);
378
420
  return;
379
421
  }
380
422
  await setUpdateState({
@@ -414,20 +456,56 @@ async function verifyPendingRuntimeHealth(targetVersion) {
414
456
  return remaining.size === 0;
415
457
  }
416
458
 
417
- async function rollbackBrokenRuntime(error) {
459
+ async function rollbackBrokenRuntime(error, transaction) {
418
460
  await setUpdateState({ state: 'rolling_back', code: safeCode(error), message: safeMessage(error) });
461
+ let pending = transaction;
462
+ let readback;
463
+ if (!pending) {
464
+ readback = await requestInternal({ method: 'update.status', params: {} }).catch(() => null);
465
+ pending = readback?.ok ? readback.result?.transaction : null;
466
+ }
467
+ // A status recovery may have completed an interrupted apply before this
468
+ // loader obtained its transaction. The same source-byte proof is required.
469
+ if (isRollbackReadback(readback, pending)) {
470
+ await setUpdateState({ state: 'rolled_back', code: safeCode(error), currentVersion: pending.sourceVersion, transactionId: pending.id });
471
+ chrome.runtime.reload();
472
+ return;
473
+ }
474
+ if (!pending?.id || !pending.sourceVersion || !['applying', 'bootstrap_pending', 'awaiting_health', 'committed'].includes(pending.state)) {
475
+ await setUpdateState({ state: 'failed', code: safeCode(error), message: safeMessage(error) });
476
+ return;
477
+ }
419
478
  const rolledBack = await requestInternal({
420
479
  method: 'update.rollback',
421
- params: { reasonCode: safeCode(error) }
480
+ params: { reasonCode: safeCode(error), transactionId: pending.id, expectedState: pending.state }
422
481
  }).catch(() => null);
423
- if (rolledBack?.ok) {
424
- await setUpdateState({ state: 'rolled_back', code: safeCode(error), currentVersion: rolledBack.result.version });
482
+ if (rolledBack?.ok && rolledBack.result?.transactionId === pending.id
483
+ && rolledBack.result?.state === 'rolled_back' && rolledBack.result?.version === pending.sourceVersion) {
484
+ readback = await requestInternal({ method: 'update.status', params: {} }).catch(() => null);
485
+ }
486
+ if (rolledBack?.result?.restoredPair && isRollbackReadback(readback, pending, rolledBack.result.restoredPair)) {
487
+ await setUpdateState({ state: 'rolled_back', code: safeCode(error), currentVersion: pending.sourceVersion, transactionId: pending.id });
425
488
  chrome.runtime.reload();
426
489
  return;
427
490
  }
428
491
  await setUpdateState({ state: 'failed', code: safeCode(error), message: safeMessage(error) });
429
492
  }
430
493
 
494
+ function isRollbackReadback(response, transaction, expectedPair) {
495
+ const status = response?.ok ? response.result : null;
496
+ const pair = status?.restoredPair;
497
+ return Boolean(transaction?.id && status?.transaction?.id === transaction.id
498
+ && status.transaction.state === 'rolled_back' && status.activeVersion === transaction.sourceVersion
499
+ && status.installedAligned === true && pair?.extensionVersion === transaction.sourceVersion
500
+ && pair?.nativeVersion === transaction.sourceVersion
501
+ && /^[0-9a-f]{64}$/.test(pair.extensionSha256 || '') && /^[0-9a-f]{64}$/.test(pair.nativeSha256 || '')
502
+ && (!(transaction.bootstrapRevision || status.transaction.bootstrapRevision || expectedPair?.bootstrapSha256)
503
+ || (/^[0-9a-f]{64}$/.test(pair.bootstrapSha256 || '')
504
+ && (!expectedPair || pair.bootstrapSha256 === expectedPair.bootstrapSha256)))
505
+ && (!expectedPair || ['extensionVersion', 'nativeVersion', 'extensionSha256', 'nativeSha256']
506
+ .every(key => pair[key] === expectedPair[key])));
507
+ }
508
+
431
509
  async function reloadPendingOverleafTabs() {
432
510
  const tabIds = await getPendingOverleafTabIds();
433
511
  await chrome.storage.local.remove(UPDATE_RELOAD_TABS_KEY);
@@ -448,6 +526,8 @@ async function postponeUpdate() {
448
526
  }
449
527
 
450
528
  async function requestInternal(payload) {
529
+ if (payload?.method === 'update.status') payload = { ...payload,
530
+ params: { ...payload.params, bootstrapRevision: String(globalThis.__CODEX_OVERLEAF_BOOTSTRAP_REVISION__ || '') } };
451
531
  if (globalThis.CodexOverleafNativeBridge?.requestInternal) {
452
532
  return globalThis.CodexOverleafNativeBridge.requestInternal({
453
533
  id: crypto.randomUUID(),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Codex Overleaf Link",
4
- "version": "2.4.0",
4
+ "version": "2.5.1",
5
5
  "description": "Connect the active Overleaf project to a local Codex bridge.",
6
6
  "icons": {
7
7
  "16": "assets/icons/icon16.png",
@@ -20,7 +20,12 @@
20
20
  "https://www.overleaf.com/project",
21
21
  "https://overleaf.com/project",
22
22
  "https://www.overleaf.com/project/*",
23
- "https://overleaf.com/project/*"
23
+ "https://overleaf.com/project/*",
24
+ "https://cn.overleaf.com/project",
25
+ "https://cn.overleaf.com/project/*"
26
+ ],
27
+ "optional_host_permissions": [
28
+ "https://*.overleaf.com/*"
24
29
  ],
25
30
  "background": {
26
31
  "service_worker": "bootstrap/background.js"
@@ -36,8 +41,8 @@
36
41
  "runtime/src/pageBridge.js"
37
42
  ],
38
43
  "matches": [
39
- "https://www.overleaf.com/*",
40
- "https://overleaf.com/*"
44
+ "https://overleaf.com/*",
45
+ "https://*.overleaf.com/*"
41
46
  ]
42
47
  }
43
48
  ],
@@ -1,24 +1,19 @@
1
1
  <!doctype html>
2
- <html>
2
+ <html lang="en" class="popup-minimal-root" data-popup-theme="dark">
3
3
  <head>
4
4
  <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
6
  <title>Codex Overleaf Link</title>
6
- <link rel="stylesheet" href="popup.css">
7
+ <link id="popup-styles" rel="stylesheet" href="../runtime/styles/popup.css">
7
8
  </head>
8
- <body>
9
- <h1 class="popup-brand">Codex Overleaf Link</h1>
10
- <div class="version-status" data-popup-context>
11
- <span id="compat-status-icon" class="status-icon incompatible" title="Native host incompatible">X</span>
12
- <span id="version-pair">Extension unknown / Native unknown</span>
13
- </div>
14
- <button id="open-panel" data-popup-context>Open panel in Overleaf</button>
15
- <p id="status" data-popup-context>Use this on an Overleaf project tab.</p>
16
- <div id="native-install" class="install" data-popup-context hidden>
17
- <strong>Native host attention required</strong>
18
- <p>Run this command in Terminal, then reload this extension in Chrome.</p>
19
- <code id="install-command"></code>
20
- <button id="copy-install-command" class="secondary" type="button">Copy install command</button>
21
- </div>
9
+ <body class="popup-minimal">
10
+ <!-- The popup body is drawn by the replaceable runtime (runtime/src/popup.js),
11
+ so popup changes ship through normal updates. This shell only holds
12
+ the fallback shown if the runtime cannot load. -->
13
+ <main id="popup-shell" data-bootstrap-shell>
14
+ <p class="popup-note">Codex Overleaf Link could not load its runtime. Rerun the installer, then reload the extension.</p>
15
+ </main>
16
+ <script src="popupFallback.js"></script>
22
17
  <script src="../runtime/src/shared/compatibility.js"></script>
23
18
  <script src="../runtime/src/popup.js"></script>
24
19
  <script src="updateStatus.js"></script>
@@ -0,0 +1,55 @@
1
+ (function localizePopupFallback() {
2
+ 'use strict';
3
+
4
+ const preferenceKeys = ['codexOverleafGlobalPrefsV1', 'codexOverleafPrefs'];
5
+ let revision = 0;
6
+ let recoveryReloaded = false;
7
+
8
+ async function refreshFallback() {
9
+ const requestRevision = ++revision;
10
+ let preferences = {};
11
+ try {
12
+ const stored = await chrome.storage.local.get(preferenceKeys);
13
+ preferences = stored.codexOverleafGlobalPrefsV1?.values || stored.codexOverleafPrefs || {};
14
+ } catch (_) { /* A missing language preference uses the product default. */ }
15
+ if (requestRevision !== revision) return;
16
+ const shell = document.querySelector('[data-bootstrap-shell]');
17
+ const message = shell?.querySelector('p');
18
+ // The healthy runtime replaces this shell. Late preference reads must
19
+ // never change the runtime's content or its current language.
20
+ if (!message) return;
21
+ const chinese = preferences.locale === 'zh';
22
+ document.documentElement.lang = chinese ? 'zh-CN' : 'en';
23
+ message.textContent = chinese
24
+ ? 'Codex Overleaf Link 无法加载运行组件。请重新运行安装程序,再重新加载扩展。'
25
+ : 'Codex Overleaf Link could not load its runtime. Rerun the installer, then reload the extension.';
26
+ }
27
+
28
+ chrome.storage.onChanged.addListener((changes, area) => {
29
+ if (area === 'local' && preferenceKeys.some(key => changes[key])) refreshFallback();
30
+ });
31
+ refreshFallback();
32
+
33
+ // This independent extension page can still start when the worker/runtime
34
+ // cannot. Native decides whether a persisted migration needs recovery; the
35
+ // popup never guesses a transaction or sends an unbound rollback request.
36
+ document.addEventListener?.('DOMContentLoaded', () => {
37
+ setTimeout(() => {
38
+ if (!document.querySelector('[data-bootstrap-shell]') || !chrome.runtime?.sendNativeMessage) return;
39
+ chrome.runtime.sendNativeMessage('com.codex.overleaf', {
40
+ id: crypto.randomUUID(), method: 'update.status', params: { bootstrapRecovery: true }
41
+ }, response => {
42
+ if (chrome.runtime.lastError || recoveryReloaded || !document.querySelector('[data-bootstrap-shell]')) return;
43
+ const status = response?.ok ? response.result : null;
44
+ const transaction = status?.transaction;
45
+ const pair = status?.restoredPair;
46
+ if (!transaction?.id || transaction.state !== 'rolled_back' || !transaction.sourceVersion
47
+ || status.activeVersion !== transaction.sourceVersion || status.installedAligned !== true
48
+ || pair?.extensionVersion !== transaction.sourceVersion || pair?.nativeVersion !== transaction.sourceVersion
49
+ || !['extensionSha256', 'nativeSha256', 'bootstrapSha256'].every(key => /^[0-9a-f]{64}$/.test(pair[key] || ''))) return;
50
+ recoveryReloaded = true;
51
+ chrome.runtime.reload();
52
+ });
53
+ }, 250);
54
+ }, { once: true });
55
+ })();
@@ -88,6 +88,7 @@
88
88
  up_to_date: ['Everything is up to date', 'Extension and Native Host are on the latest stable release.', 'Up to date', 'success'],
89
89
  checking: ['Checking for updates', 'Reading the latest signed stable release.', 'Checking', 'active'],
90
90
  update_available: ['A stable update is ready', 'Review the target version, then update when convenient.', 'Available', 'success'],
91
+ manual_install_required: ['This update needs a one-time reinstall', 'Update now cannot apply this release. Run the command below once, then reload the extension and refresh Overleaf. Your sessions, settings, provider keys and project mirrors are kept.', 'Reinstall', 'warning'],
91
92
  downloading: ['Downloading the signed release', 'The package is being fetched and verified before any files change.', 'Downloading', 'active'],
92
93
  staged: ['Update verified', 'The signed package is ready and waiting for a safe installation point.', 'Verified', 'active'],
93
94
  waiting: ['Waiting for a safe point', 'Active Overleaf work will finish before the runtime changes.', 'Waiting', 'warning'],
@@ -164,6 +165,12 @@
164
165
  { id: 'install', label: 'Update now', kind: 'primary' }
165
166
  ];
166
167
  }
168
+ if (phase === 'manual_install_required') {
169
+ return [
170
+ { id: 'later', label: 'Later', kind: 'quiet' },
171
+ { id: 'copy-command', label: 'Copy command', kind: 'primary' }
172
+ ];
173
+ }
167
174
  if (['failed', 'rolled_back'].includes(phase)) {
168
175
  return [
169
176
  { id: 'close', label: 'Close', kind: 'quiet' },
@@ -229,8 +236,14 @@
229
236
  ? 'The extension may restart briefly. This window will reconnect and restore the saved progress.'
230
237
  : 'This window can stay open while work continues elsewhere. Progress is saved automatically.';
231
238
 
232
- const technical = technicalText(currentView);
233
- elements.details.hidden = !technical || !['failed', 'rolled_back'].includes(presentation.phase);
239
+ // The signed reason and the exact reinstall command replace the generic
240
+ // detail; the command stays visible and selectable in the details box.
241
+ const manual = presentation.phase === 'manual_install_required';
242
+ const reason = manual ? String(currentView.manualReason?.en || currentView.manualReason?.zh || '').trim() : '';
243
+ if (reason) elements.detail.textContent = reason + ' ' + presentation.detail;
244
+ const technical = manual ? manualCommand(target) : technicalText(currentView);
245
+ elements.details.hidden = !technical || !['failed', 'rolled_back', 'manual_install_required'].includes(presentation.phase);
246
+ elements.details.open = manual || elements.details.open;
234
247
  elements.technicalMessage.textContent = technical;
235
248
  renderActions(presentation.phase);
236
249
  schedulePolling(presentation.phase);
@@ -286,8 +299,18 @@
286
299
  }, 1100);
287
300
  }
288
301
 
302
+ function manualCommand(version) {
303
+ const pinned = /^\d+\.\d+\.\d+$/.test(String(version || '')) ? version : 'latest';
304
+ return `npm exec --yes codex-overleaf-link@${pinned} -- install-managed`;
305
+ }
306
+
289
307
  async function runAction(action) {
290
308
  if (actionPending) return;
309
+ if (action === 'copy-command') {
310
+ const target = versionOf(currentView, ['latestVersion', 'targetVersion', 'availableVersion'], '');
311
+ await navigator.clipboard.writeText(manualCommand(target)).catch(() => {});
312
+ return;
313
+ }
291
314
  if (action === 'close') {
292
315
  window.close();
293
316
  return;
@@ -17,6 +17,7 @@
17
17
  tab_not_idle: 'An Overleaf tab is still busy.',
18
18
  native_project_locked: 'The native host still holds a project lock.',
19
19
  native_run_active: 'The native host is still processing a Codex run.',
20
+ native_process_stop_unconfirmed: 'A previous Codex process has not yet confirmed its exit.',
20
21
  native_gate_unavailable: 'The native host could not report whether it is idle.',
21
22
  native_not_idle: 'The native host is still busy.',
22
23
  busy: 'An update safety check is still busy.'
@@ -4,7 +4,9 @@
4
4
  "https://www.overleaf.com/project",
5
5
  "https://overleaf.com/project",
6
6
  "https://www.overleaf.com/project/*",
7
- "https://overleaf.com/project/*"
7
+ "https://overleaf.com/project/*",
8
+ "https://cn.overleaf.com/project",
9
+ "https://cn.overleaf.com/project/*"
8
10
  ],
9
11
  "js": [
10
12
  "src/content/generated/content.bundle.js"