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
@@ -11,6 +11,8 @@
11
11
  let currentView = null;
12
12
  let mountedPanel = null;
13
13
  let actionInFlight = false;
14
+ let cancellationInFlight = false;
15
+ let actionSequence = 0;
14
16
  let listenerInstalled = false;
15
17
  let getLocale = () => '';
16
18
  let settingsRoot = null;
@@ -68,42 +70,62 @@
68
70
 
69
71
  async function handleClick(event) {
70
72
  const action = event.target?.closest?.('[data-update-notice-action]')?.dataset?.updateNoticeAction;
71
- if (!action || actionInFlight) return;
73
+ if (!action) return;
74
+ if (action === 'release-notes') {
75
+ const version = currentView?.state?.latestVersion || '';
76
+ window.open('https://github.com/Ghqqqq/codex-overleaf-link/releases/tag/v' + version, '_blank', 'noopener');
77
+ return;
78
+ }
72
79
  if (action === 'copy-manual') {
73
80
  try {
74
81
  await navigator.clipboard.writeText(manualUpdateCommand(currentView?.state));
75
82
  manualCommandCopied = true;
76
83
  render();
77
- setTimeout(() => {
78
- manualCommandCopied = false;
79
- render();
80
- }, 1800);
81
- } catch (_error) {
82
- manualCommandCopied = false;
83
- }
84
+ setTimeout(() => { manualCommandCopied = false; render(); }, 1800);
85
+ } catch (_) { manualCommandCopied = false; }
84
86
  return;
85
87
  }
88
+ return runUpdateAction(action);
89
+ }
90
+
91
+ async function runUpdateAction(action) {
92
+ const cancelling = action === 'cancel' || action === 'later';
93
+ if (cancellationInFlight || ((actionInFlight || settingsActionInFlight) && !cancelling)) return;
94
+ const sequence = ++actionSequence;
86
95
  actionInFlight = true;
96
+ settingsActionInFlight = true;
97
+ cancellationInFlight = cancelling;
87
98
  render();
88
99
  try {
89
- currentView = await request({
100
+ const view = await request({
101
+ check: 'codex-overleaf/consent-update-check',
90
102
  install: 'codex-overleaf/consent-update-install',
91
103
  retry: 'codex-overleaf/consent-update-check',
92
104
  later: 'codex-overleaf/consent-update-later',
105
+ cancel: 'codex-overleaf/consent-update-cancel',
106
+ recover: 'codex-overleaf/consent-update-recover',
93
107
  dismiss: 'codex-overleaf/consent-update-dismiss',
94
108
  reload: 'codex-overleaf/consent-update-reload'
95
109
  }[action]);
110
+ if (sequence === actionSequence) currentView = view;
96
111
  } catch (error) {
97
- currentView = await reconcileAfterActionError(error, {
98
- action,
99
- fallbackMessage: tx('Update failed.', '更新失败。')
100
- });
112
+ if (sequence === actionSequence) {
113
+ const view = await reconcileAfterActionError(error, {
114
+ action, fallbackMessage: tx('Update action failed.', '更新操作失败。')
115
+ });
116
+ if (sequence === actionSequence) currentView = view;
117
+ }
101
118
  } finally {
102
- actionInFlight = false;
103
- render();
119
+ if (sequence === actionSequence) {
120
+ actionInFlight = false;
121
+ settingsActionInFlight = false;
122
+ cancellationInFlight = false;
123
+ render();
124
+ }
104
125
  }
105
126
  }
106
127
 
128
+
107
129
  async function request(type) {
108
130
  if (!type) throw new Error('Unknown update action.');
109
131
  const response = await chrome.runtime.sendMessage({ type });
@@ -164,8 +186,9 @@
164
186
  restartWatchdog = setTimeout(async () => {
165
187
  try {
166
188
  const view = await request('codex-overleaf/consent-update-get-state');
167
- if (view?.state && !ACTIVE_UPDATE_STATES.has(view.state.state)) {
189
+ if (view?.state) {
168
190
  currentView = view;
191
+ if (ACTIVE_UPDATE_STATES.has(view.state.state)) scheduleRestartWatchdog();
169
192
  } else {
170
193
  currentView = buildFailedView('update_recovery_timeout', tx(
171
194
  'The update did not finish restarting. Retry or use the manual recovery command.',
@@ -206,41 +229,23 @@
206
229
  renderSettings();
207
230
  }
208
231
 
209
- async function handleSettingsAction() {
210
- if (settingsActionInFlight) return;
211
- settingsActionInFlight = true;
212
- renderSettings();
213
- const stateName = currentView?.state?.state || 'idle';
214
- let requestedAction = 'check';
215
- try {
216
- if (['reload_required', 'reload_tabs_required'].includes(stateName)) {
217
- requestedAction = 'reload';
218
- currentView = await request('codex-overleaf/consent-update-reload');
219
- } else if (stateName === 'update_available') {
220
- requestedAction = 'install';
221
- currentView = await request('codex-overleaf/consent-update-install');
222
- } else if (['failed', 'rolled_back'].includes(stateName)) {
223
- currentView = await request('codex-overleaf/consent-update-check');
224
- } else if (!ACTIVE_UPDATE_STATES.has(stateName)) {
225
- currentView = await request('codex-overleaf/consent-update-check');
226
- } else {
227
- return;
228
- }
229
- } catch (error) {
230
- currentView = await reconcileAfterActionError(error, {
231
- action: requestedAction,
232
- fallbackMessage: tx('Update check failed.', '更新检查失败。')
233
- });
234
- } finally {
235
- settingsActionInFlight = false;
236
- render();
232
+ function handleSettingsAction() {
233
+ const state = currentView?.state || {};
234
+ if (state.recoveryPending) return runUpdateAction('recover');
235
+ if (state.cancelRequested || ['checking', 'downloading', 'staged', 'waiting_for_idle'].includes(state.state)) {
236
+ return runUpdateAction('cancel');
237
237
  }
238
+ if (['reload_required', 'reload_tabs_required'].includes(state.state)) return runUpdateAction('reload');
239
+ if (state.state === 'update_available') return runUpdateAction('install');
240
+ if (!ACTIVE_UPDATE_STATES.has(state.state)) return runUpdateAction('check');
238
241
  }
239
242
 
243
+
240
244
  function render() {
241
245
  if (!currentView) return;
242
246
  renderSettings();
243
247
  if (!notice) return;
248
+ notice.setAttribute('aria-label', tx('Stable update', '稳定版更新'));
244
249
  if (!currentView.showPanel) {
245
250
  notice.hidden = true;
246
251
  notice.replaceChildren();
@@ -270,7 +275,24 @@
270
275
  detail.textContent = copy.detail;
271
276
  body.append(eyebrow, title, detail);
272
277
 
273
- if (state.state === 'failed') {
278
+ if (state.state === 'manual_install_required') {
279
+ const steps = document.createElement('ol');
280
+ steps.className = 'codex-update-notice-steps';
281
+ for (const text of [
282
+ tx('Run this once in a terminal:', '在终端运行一次:'),
283
+ tx('Reload the extension in chrome://extensions, then refresh Overleaf.', '在 chrome://extensions 里重新加载扩展,再刷新 Overleaf。')
284
+ ]) steps.append(Object.assign(document.createElement('li'), { textContent: text }));
285
+ const command = document.createElement('code');
286
+ command.className = 'codex-update-notice-command';
287
+ command.textContent = manualUpdateCommand(state);
288
+ steps.firstElementChild.append(command);
289
+ const keep = document.createElement('span');
290
+ keep.className = 'codex-update-notice-recovery';
291
+ keep.textContent = tx('Sessions, settings, provider keys and project mirrors are kept.', '会话、设置、模型服务的密钥和项目镜像都会保留。');
292
+ body.append(steps, keep);
293
+ }
294
+
295
+ if (state.state === 'failed' && !state.cancelRequested && !state.recoveryPending) {
274
296
  const recovery = document.createElement('span');
275
297
  recovery.className = 'codex-update-notice-recovery';
276
298
  recovery.textContent = tx('Manual recovery:', '手动恢复:');
@@ -280,7 +302,7 @@
280
302
  body.append(recovery, command);
281
303
  }
282
304
 
283
- if (!['update_available', 'failed', 'rolled_back', 'reload_required', 'reload_tabs_required'].includes(state.state)) {
305
+ if (!['update_available', 'manual_install_required', 'failed', 'rolled_back', 'reload_required', 'reload_tabs_required'].includes(state.state)) {
284
306
  const bar = document.createElement('div');
285
307
  bar.className = 'codex-update-notice-progress' + (progress.determinate ? '' : ' is-indeterminate');
286
308
  bar.setAttribute('role', 'progressbar');
@@ -302,7 +324,9 @@
302
324
  button.dataset.updateNoticeAction = action.id;
303
325
  button.className = action.primary ? 'is-primary' : '';
304
326
  button.textContent = action.label;
305
- button.disabled = actionInFlight;
327
+ button.disabled = action.id === 'cancel'
328
+ ? cancellationInFlight || (state.cancelRequested && !state.code)
329
+ : actionInFlight || settingsActionInFlight;
306
330
  actions.append(button);
307
331
  }
308
332
  notice.replaceChildren(body, actions);
@@ -332,7 +356,14 @@
332
356
  let statusText = '';
333
357
  let buttonText = tx('Check for updates', '检查更新');
334
358
 
335
- if (['reload_required', 'reload_tabs_required'].includes(stateName)) {
359
+ if (stateName === 'idle' && state.code === 'update_cooldown') {
360
+ const until = Number(state.cooldownUntil || 0);
361
+ const time = until > 0 && Number.isFinite(until) ? new Date(until).toLocaleString(getLocale() || undefined) : '';
362
+ statusText = tx(
363
+ `Update v${latestVersion} is paused after a failed installation. ${time ? `Check again after ${time}.` : 'Check again after its cooldown ends.'}`,
364
+ `v${latestVersion} 安装失败后已暂停更新。${time ? `请在 ${time} 后再次检查。` : '请在冷却期结束后再次检查。'}`
365
+ );
366
+ } else if (['reload_required', 'reload_tabs_required'].includes(stateName)) {
336
367
  summaryText = tx(`Installed v${latestVersion}; running extension v${currentVersion}.`, `已安装 v${latestVersion};扩展当前运行 v${currentVersion}。`);
337
368
  statusText = getCopy(state).detail;
338
369
  buttonText = stateName === 'reload_required' ? tx('Reload extension', '重新加载扩展') : tx('Refresh Overleaf tabs', '刷新 Overleaf 标签页');
@@ -343,11 +374,14 @@
343
374
  summaryText = tx(`Stable v${latestVersion} is available.`, `稳定版本 v${latestVersion} 已可用。`);
344
375
  statusText = tx('Ready to download and verify.', '已可下载并验证。');
345
376
  buttonText = tx('Update now', '立即更新');
377
+ } else if (stateName === 'manual_install_required') {
378
+ summaryText = tx(`v${latestVersion} is available but needs a one-time reinstall.`, `v${latestVersion} 已发布,但需要重新安装一次。`);
379
+ statusText = manualReasonText(state) || getCopy(state).detail;
346
380
  } else if (ACTIVE_UPDATE_STATES.has(stateName)) {
347
381
  statusText = getCopy(state).detail;
348
382
  buttonText = tx('Update in progress', '更新进行中');
349
383
  } else if (stateName === 'failed' || stateName === 'rolled_back') {
350
- statusText = state.message || getCopy(state).detail;
384
+ statusText = formatUpdateMessage(state) || getCopy(state).detail;
351
385
  buttonText = tx('Retry', '重试');
352
386
  } else if (stateName === 'committed') {
353
387
  summaryText = tx(`Current v${currentVersion}. Update completed successfully.`, `当前版本 v${currentVersion}。更新已成功完成。`);
@@ -358,11 +392,29 @@
358
392
  status.textContent = statusText;
359
393
  status.hidden = !statusText;
360
394
  button.textContent = buttonText;
361
- button.disabled = settingsActionInFlight || stateName === 'checking' || ACTIVE_UPDATE_STATES.has(stateName);
395
+ const cancellable = state.cancelRequested || ['checking', 'downloading', 'staged', 'waiting_for_idle'].includes(stateName);
396
+ if (state.recoveryPending) {
397
+ button.textContent = tx('Check recovery', '检查恢复状态');
398
+ button.disabled = actionInFlight || settingsActionInFlight;
399
+ } else if (cancellable) {
400
+ button.textContent = state.cancelRequested && !state.code
401
+ ? tx('Cancelling…', '正在取消…')
402
+ : state.cancelRequested ? tx('Retry cancellation', '重试取消') : tx('Cancel update', '取消更新');
403
+ button.disabled = cancellationInFlight || (state.cancelRequested && !state.code);
404
+ } else {
405
+ button.disabled = actionInFlight || settingsActionInFlight || ACTIVE_UPDATE_STATES.has(stateName);
406
+ }
362
407
  }
363
408
 
364
409
  function visibleActions(state) {
365
- if (actionInFlight) return [];
410
+ const value = currentView?.state || {};
411
+ if (value.recoveryPending) return [{ id: 'recover', label: tx('Check recovery', '检查恢复状态'), primary: true }];
412
+ if (value.cancelRequested || ['checking', 'downloading'].includes(state)) {
413
+ return [{ id: 'cancel', label: value.cancelRequested
414
+ ? value.code ? tx('Retry cancellation', '重试取消') : tx('Cancelling…', '正在取消…')
415
+ : tx('Cancel update', '取消更新'), primary: false }];
416
+ }
417
+ if (actionInFlight && !['staged', 'waiting_for_idle'].includes(state)) return [];
366
418
  if (['reload_required', 'reload_tabs_required'].includes(state)) {
367
419
  return [{ id: 'reload', label: state === 'reload_required'
368
420
  ? tx('Reload extension', '重新加载扩展') : tx('Refresh Overleaf tabs', '刷新 Overleaf 标签页'), primary: true }];
@@ -374,7 +426,14 @@
374
426
  ];
375
427
  }
376
428
  if (['staged', 'waiting_for_idle'].includes(state)) {
377
- return [{ id: 'later', label: tx('Later', '稍后'), primary: false }];
429
+ return [{ id: 'cancel', label: tx('Cancel update', '取消更新'), primary: false }];
430
+ }
431
+ if (state === 'manual_install_required') {
432
+ return [
433
+ { id: 'later', label: tx('Later', '稍后'), primary: false },
434
+ { id: 'release-notes', label: tx('Release notes', '发布说明'), primary: false },
435
+ { id: 'copy-manual', label: manualCommandCopied ? tx('Copied', '已复制') : tx('Copy command', '复制命令'), primary: true }
436
+ ];
378
437
  }
379
438
  if (['failed', 'rolled_back'].includes(state)) {
380
439
  return [
@@ -390,15 +449,30 @@
390
449
 
391
450
  function getCopy(state) {
392
451
  const target = state.latestVersion ? 'v' + state.latestVersion : '';
452
+ if (state.cancelRequested) return {
453
+ eyebrow: tx('Cancelling update', '正在取消更新'), title: target,
454
+ detail: formatUpdateMessage(state) || tx('Stopping this update and clearing its authorization.', '正在停止本次更新并清理更新授权。')
455
+ };
456
+ if (state.recoveryPending) return {
457
+ eyebrow: tx('Checking update recovery', '正在确认更新恢复状态'), title: target,
458
+ detail: formatUpdateMessage(state) || tx('Waiting for the installed version to be confirmed.', '正在确认实际安装的版本。')
459
+ };
393
460
  const blocker = blockersCopy(state.blockers?.length ? state.blockers : [state.blocker]);
394
461
  return {
462
+ checking: { eyebrow: tx('Checking for updates', '正在检查更新'), title: target,
463
+ detail: tx('Reading the latest signed release.', '正在读取最新签名版本。') },
395
464
  reload_required: {
396
465
  eyebrow: tx('Installed, awaiting reload', '已安装,等待加载'), title: target,
397
- detail: state.message || tx('The new files are installed. Reload the extension when Overleaf is saved and idle.', '新版文件已安装,请在 Overleaf 保存并空闲后重新加载扩展。')
466
+ detail: formatUpdateMessage(state) || tx('The new files are installed. Reload the extension when Overleaf is saved and idle.', '新版文件已安装,请在 Overleaf 保存并空闲后重新加载扩展。')
398
467
  },
399
468
  reload_tabs_required: {
400
469
  eyebrow: tx('Updated runtime is ready', '新版运行组件已就绪'), title: target,
401
- detail: state.message || tx('Refresh the saved, idle Overleaf tabs to load the updated panel.', '刷新已保存且空闲的 Overleaf 标签页以加载新版面板。')
470
+ detail: formatUpdateMessage(state) || tx('Refresh the saved, idle Overleaf tabs to load the updated panel.', '刷新已保存且空闲的 Overleaf 标签页以加载新版面板。')
471
+ },
472
+ manual_install_required: {
473
+ eyebrow: tx('Reinstall needed for this update', '这次更新需要重新安装'),
474
+ title: target,
475
+ detail: manualReasonText(state) || tx('This release changes what Chrome lets the extension do, so Update now cannot apply it.', '这一版改动了 Chrome 授予扩展的权限,无法通过“立即更新”完成。')
402
476
  },
403
477
  update_available: {
404
478
  eyebrow: tx('Update available', '发现新版本'),
@@ -443,7 +517,7 @@
443
517
  failed: {
444
518
  eyebrow: tx('Update could not continue', '更新无法继续'),
445
519
  title: target,
446
- detail: state.message || tx('Review the update details and retry.', '请查看更新详情后重试。')
520
+ detail: formatUpdateMessage(state) || tx('Review the update details and retry.', '请查看更新详情后重试。')
447
521
  }
448
522
  }[state.state] || { eyebrow: '', title: '', detail: '' };
449
523
  }
@@ -455,6 +529,45 @@
455
529
  return `npm exec --yes codex-overleaf-link@${version} -- install-managed`;
456
530
  }
457
531
 
532
+ function formatUpdateMessage(state = {}) {
533
+ const code = state.code || '';
534
+ const messages = {
535
+ update_phase_timeout: ['The update timed out and its download was stopped. Retry when the connection is available.', '更新超时,下载已停止。连接恢复后请重试。'],
536
+ update_not_applied: ['The update was stopped before installation. Retry when ready.', '更新已在安装前停止,可准备就绪后重试。'],
537
+ update_recovery_pending: ['The update result is being checked. Recovery has not been confirmed.', '正在确认更新结果,恢复状态尚未确认。'],
538
+ update_rolled_back: ['The previous version has been restored.', '已恢复上一版本。'],
539
+ update_not_managed: ['Run install-managed once to enable coordinated automatic updates.', '请先运行一次 install-managed,以启用扩展与本机服务的协调更新。'],
540
+ update_native_busy: ['Native Host is still processing a Codex task.', 'Native Host 仍在处理 Codex 任务。'],
541
+ update_revoke_too_late: ['The update is already being installed. Wait for its result.', '更新已进入安装,请等待结果。'],
542
+ update_cancel_unconfirmed: ['Update cancellation is unconfirmed. Check recovery before retrying.', '尚未确认更新已取消,请先检查恢复状态。'],
543
+ update_apply_unconfirmed: ['Update installation is unconfirmed. Check recovery before retrying.', '尚未确认更新安装结果,请先检查恢复状态。'],
544
+ update_rollback_unconfirmed: ['Restoring the previous version is unconfirmed. Check recovery before retrying.', '尚未确认旧版本已恢复,请先检查恢复状态。'],
545
+ update_reload_unavailable: ['No verified installed update is awaiting reload.', '当前没有已验证且等待重载的更新。'],
546
+ update_network_cancelled: ['The update download was cancelled.', '更新下载已取消。'],
547
+ update_apply_failed: ['The update could not be installed. Check recovery and retry.', '无法安装更新,请检查恢复状态后重试。']
548
+ };
549
+ if (messages[code]) return tx(...messages[code]);
550
+ if (['update_health_failed', 'update_request_failed', 'update_failed'].includes(code)) return tx('The updated components could not be confirmed. Check recovery before retrying.', '尚未确认更新后的组件正常,请先检查恢复状态。');
551
+ if (['update_bootstrap_health_timeout', 'update_bootstrap_reload_failed'].includes(code)) return tx('The updated startup components did not finish restarting and confirming. Check recovery before retrying.', '更新后的启动组件未能完成重启和确认,请先检查恢复状态。');
552
+ if (['update_bootstrap_source_mismatch', 'update_bootstrap_source_version_mismatch'].includes(code)) return tx('The installed startup files do not match a supported update source. Check recovery before retrying.', '已安装的启动文件与支持的升级来源不一致,请先检查恢复状态。');
553
+ if (['update_bootstrap_record_missing', 'update_bootstrap_record_invalid', 'update_bootstrap_backup_mismatch', 'update_bootstrap_already_restoring'].includes(code)) return tx('The startup recovery material could not be confirmed. The update result remains unconfirmed.', '尚未确认启动组件的恢复材料有效,更新结果仍待确认。');
554
+ if (['update_bootstrap_confirmation_pending', 'update_bootstrap_native_restart_required'].includes(code)) return tx('Waiting for the updated startup components and Native Host to finish restarting and confirming.', '正在等待更新后的启动组件和本机服务完成重启及确认。');
555
+ if (code === 'update_bootstrap_monitor_unavailable') return tx('The update recovery monitor could not start. Check recovery before retrying.', '更新恢复监护程序未能启动,请先检查恢复状态。');
556
+ if (['update_bootstrap_transaction_mismatch', 'update_bootstrap_transaction_invalid'].includes(code)) return tx('The startup update transaction could not be matched. Check recovery before retrying.', '未能匹配启动组件的更新事务,请先检查恢复状态。');
557
+ if (code.startsWith('update_bootstrap_')) return tx('The startup update package or installed files could not be verified. Check recovery before retrying.', '无法验证启动组件更新包或已安装文件,请先检查恢复状态。');
558
+ if (['update_reload_required', 'update_reload_busy'].includes(code)) {
559
+ const match = /^Reload is waiting for Overleaf to be saved and idle \(([^)]+)\)\.$/.exec(state.message || '');
560
+ if (match) return blockersCopy(match[1].split(', '));
561
+ }
562
+ if (['update_check_timeout', 'update_activation_timeout', 'update_status_timeout'].includes(code)) return tx('The update operation timed out. Check recovery or retry when the connection is available.', '更新操作超时,请检查恢复状态,或在连接恢复后重试。');
563
+ if (['update_candidate_missing', 'update_candidate_stale', 'update_not_staged', 'update_staged_archive_invalid', 'update_recovery_superseded'].includes(code)) return tx('No current verified update is ready. Check for updates again.', '当前没有已验证且可安装的更新,请重新检查更新。');
564
+ if (['update_authorization_in_progress', 'update_transaction_in_progress', 'update_transaction_locked'].includes(code)) return tx('Another update operation is in progress. Wait for it to finish.', '另一项更新操作正在进行,请等待其完成。');
565
+ if (['update_authorization_invalid', 'update_consent_required', 'update_consent_mismatch', 'update_transaction_mismatch', 'update_transaction_state_changed'].includes(code)) return tx('The update authorization or transaction changed. Check for updates and authorize the current candidate again.', '更新授权或事务已变化,请重新检查更新并确认当前候选版本。');
566
+ if (['update_archive_checksum_invalid', 'update_archive_compressed_limit', 'update_archive_duplicate_path', 'update_archive_file_count_limit', 'update_archive_file_limit', 'update_archive_invalid', 'update_archive_path_forbidden', 'update_archive_path_too_long', 'update_archive_required_file_missing', 'update_archive_total_limit', 'update_archive_truncated', 'update_archive_type_forbidden', 'update_staging_not_empty', 'update_operation_invalid', 'update_bundle_hash_invalid', 'update_bundle_name_invalid', 'update_bundle_size_invalid', 'update_manifest_artifacts_invalid', 'update_manifest_commit_invalid', 'update_manifest_invalid', 'update_manifest_manual_install_invalid', 'update_manifest_origin_mismatch', 'update_manifest_protocol_invalid', 'update_manifest_schema_unsupported', 'update_manifest_timestamp_invalid', 'update_manifest_too_large', 'update_manifest_version_invalid', 'update_signature_algorithm_unsupported', 'update_signature_invalid', 'update_signature_key_invalid', 'update_signature_key_unknown', 'update_signature_too_large', 'update_version_invalid'].includes(code)) return tx('The signed update or archive could not be verified. Check the release details and retry.', '无法验证更新签名或压缩包,请检查发布详情后重试。');
567
+ if (['update_github_http_error', 'update_github_response_invalid', 'update_asset_missing', 'update_asset_url_forbidden', 'update_release_asset_invalid', 'update_release_manifest_mismatch', 'update_bundle_size_mismatch', 'update_bundle_hash_mismatch', 'update_native_version_mismatch', 'update_extension_version_mismatch', 'update_runtime_manifest_invalid', 'update_runtime_asset_missing', 'update_bootstrap_manifest_invalid', 'update_managed_layout_invalid', 'update_marker_invalid', 'update_current_version_invalid', 'update_health_version_mismatch', 'update_confirmation_unexpected', 'update_rollback_unavailable'].includes(code)) return tx('The update or installed files could not be verified. Check the update details and repair or retry.', '无法验证更新或已安装文件,请检查更新详情后修复或重试。');
568
+ return state.message || '';
569
+ }
570
+
458
571
  function blockerCopy(value) {
459
572
  return {
460
573
  unsaved: tx('Overleaf has not confirmed that this document is saved.', 'Overleaf 尚未确认当前文档已保存。'),
@@ -475,6 +588,7 @@
475
588
  tab_unavailable: tx('An Overleaf tab is unavailable for the safety check.', '某个 Overleaf 标签页当前无法完成安全检查。'),
476
589
  idle_probe_failed: tx('The Overleaf safety check failed. Reload the affected tab and retry.', 'Overleaf 安全检查失败;请刷新受影响的标签页后重试。'),
477
590
  native_project_locked: tx('Native Host still holds a project lock.', 'Native Host 仍持有项目锁。'),
591
+ native_process_stop_unconfirmed: tx('A previous Codex process has not yet confirmed its exit.', '前一次 Codex 进程尚未确认退出。'),
478
592
  native_run_active: tx('Native Host is still processing a task.', 'Native Host 仍在处理任务。'),
479
593
  busy: tx('A component is still busy.', '某个组件仍处于忙碌状态。')
480
594
  }[value] || tx('Waiting until every Overleaf tab is saved and idle.', '正在等待所有 Overleaf 标签页完成保存并进入空闲状态。');
@@ -488,10 +602,19 @@
488
602
  );
489
603
  }
490
604
 
605
+ function manualReasonText(state = {}) {
606
+ if (state.code === 'prerelease_promotion_requires_manual_update') {
607
+ return tx('The installed release candidate has the same version number as the stable release. Reinstall to use the stable release.',
608
+ '已安装的候选版与稳定版使用相同版本号。请重新安装以使用稳定版。');
609
+ }
610
+ const reason = state.manualReason || {};
611
+ return tx(reason.en || reason.zh || '', reason.zh || reason.en || '');
612
+ }
613
+
491
614
  function tx(english, chinese) {
492
615
  const locale = String(getLocale() || document.documentElement?.lang || 'en');
493
616
  return /^zh\b/i.test(locale) ? chinese : english;
494
617
  }
495
618
 
496
- return Object.freeze({ mount });
619
+ return Object.freeze({ mount, refreshLocale: render });
497
620
  });
@@ -0,0 +1,58 @@
1
+ (function installUpdateSafetyReceiver(root) {
2
+ 'use strict';
3
+ if (root.__codexOverleafUpdateSafetyReceiverInstalled) return;
4
+ let binding, idle, inFlight = false;
5
+ const blocked = () => ({ idle: false, saved: false, blockers: ['tab_probe_unavailable'] });
6
+ function install(next, dependencies) {
7
+ if (!next?.transactionId || !next.token || next.url !== location.href) return { ok: false };
8
+ if (binding) {
9
+ if (binding.transactionId !== next.transactionId || binding.targetVersion !== next.targetVersion
10
+ || binding.documentId !== next.documentId || binding.url !== next.url || inFlight) return { ok: false };
11
+ binding = Object.freeze({ ...next });
12
+ return { ok: true, url: location.href };
13
+ }
14
+ binding = Object.freeze({ ...next });
15
+ const pageWrites = new Set();
16
+ const visible = node => !node.hidden && node.getAttribute('aria-hidden') !== 'true' && node.getClientRects().length > 0;
17
+ const { UpdateIdle, PageRpcContract } = dependencies;
18
+ idle = UpdateIdle.create({ document, includePanelActivity: true,
19
+ getBusyState: () => ({ reviewAction: pageWrites.size > 0
20
+ || [...document.querySelectorAll('#codex-overleaf-panel [data-run-accept-confirm], #codex-overleaf-panel button:disabled')]
21
+ .some(node => visible(node) && (node.hasAttribute('data-run-accept-confirm') || /Accepting|接受中/.test(node.textContent)
22
+ || (node.hasAttribute('data-run-undo') && !/Undone|已撤销/.test(node.textContent)
23
+ && !/Accepted|已接受/.test(node.closest('[data-run-id]')?.querySelector('[data-run-accept]')?.textContent || '')))),
24
+ run: document.querySelector('#codex-overleaf-panel')?.dataset.running === 'true',
25
+ cancelling: document.querySelector('#codex-overleaf-panel')?.dataset.cancelling === 'true',
26
+ dialog: [...document.querySelectorAll('[role="dialog"], dialog[open]')].some(visible) }),
27
+ checkSaved: async () => {
28
+ const response = await chrome.runtime.sendMessage({ type: 'codex-overleaf/migration-save-probe', ...binding,
29
+ nonce: activeNonce });
30
+ return response?.ok && response.nonce === activeNonce ? response.result : { ok: false, state: 'unavailable' };
31
+ } });
32
+ root.addEventListener('message', event => {
33
+ if (event.source !== root || event.origin !== location.origin || typeof event.data?.id !== 'string') return;
34
+ const data = event.data;
35
+ const mutation = PageRpcContract.getMethod(data.method)?.mutation;
36
+ if (data.source === 'codex-overleaf/content' && ['document', 'page_state', 'navigation'].includes(mutation)) {
37
+ pageWrites.add(data.id); idle.noteActivity();
38
+ } else if (data.source === 'codex-overleaf/page' && pageWrites.delete(data.id)) idle.noteActivity();
39
+ });
40
+ chrome.runtime.onMessage.addListener((message, sender, respond) => {
41
+ if (message?.type !== 'codex-overleaf/migration-idle-probe') return undefined;
42
+ if (sender?.id !== chrome.runtime.id || sender.tab || message.token !== binding.token
43
+ || message.transactionId !== binding.transactionId || typeof message.nonce !== 'string'
44
+ || !message.nonce || location.href !== binding.url || inFlight) { respond(blocked()); return false; }
45
+ inFlight = true;
46
+ activeNonce = message.nonce;
47
+ idle.buildIdleProbe().then(result => respond(location.href === binding.url ? {
48
+ ...result, transactionId: binding.transactionId, token: binding.token, nonce: message.nonce,
49
+ url: location.href, targetVersion: binding.targetVersion, safetyOnly: true
50
+ } : blocked())).catch(() => respond(blocked())).finally(() => { inFlight = false; activeNonce = ''; });
51
+ return true;
52
+ });
53
+ return { ok: true, url: location.href };
54
+ }
55
+ let activeNonce = '';
56
+ root.CodexOverleafUpdateSafetyReceiver = Object.freeze({ install });
57
+ root.__codexOverleafUpdateSafetyReceiverInstalled = true;
58
+ })(globalThis);