codex-overleaf-link 2.4.1 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/README.md +272 -314
  2. package/README.zh-CN.md +287 -329
  3. package/extension/bootstrap/background.js +47 -10
  4. package/extension/bootstrap/manifest.template.json +9 -4
  5. package/extension/bootstrap/popup.html +10 -16
  6. package/extension/bootstrap/update.js +25 -2
  7. package/extension/runtime-manifest.json +3 -1
  8. package/extension/src/background.js +28 -3
  9. package/extension/src/backgroundSharedSessions.js +380 -0
  10. package/extension/src/backgroundUpdateCoordinator.js +442 -379
  11. package/extension/src/content/activeTurnControl.js +8 -0
  12. package/extension/src/content/assetTransferBroker.js +186 -12
  13. package/extension/src/content/changeHistoryView.js +175 -0
  14. package/extension/src/content/composerAttachments.js +24 -22
  15. package/extension/src/content/composerPanel.js +23 -8
  16. package/extension/src/content/contentRuntime.js +507 -507
  17. package/extension/src/content/diagnosticsController.js +1 -2
  18. package/extension/src/content/diagnosticsExport.js +222 -0
  19. package/extension/src/content/diagnosticsPanel.js +48 -19
  20. package/extension/src/content/diffReviewPanel.js +8 -5
  21. package/extension/src/content/generated/content.bundle.js +8330 -1349
  22. package/extension/src/content/generated/content.bundle.meta.json +22 -3
  23. package/extension/src/content/legacyGlobalRegistry.js +19 -1
  24. package/extension/src/content/localSkillsPanel.js +42 -7
  25. package/extension/src/content/markdownDomRenderer.js +9 -4
  26. package/extension/src/content/modelPicker.js +1 -1
  27. package/extension/src/content/pageBridgeClient.js +18 -3
  28. package/extension/src/content/panelMaintenance.js +48 -121
  29. package/extension/src/content/panelRenderer.js +4 -0
  30. package/extension/src/content/pendingInputView.js +109 -76
  31. package/extension/src/content/providerSettingsCoordinator.js +17 -6
  32. package/extension/src/content/providerSettingsDialog.js +661 -108
  33. package/extension/src/content/recentProjects.js +10 -1
  34. package/extension/src/content/runActivitySummary.js +631 -0
  35. package/extension/src/content/runController.js +3 -1
  36. package/extension/src/content/runFailureNotice.js +14 -1
  37. package/extension/src/content/runGuidanceController.js +4 -3
  38. package/extension/src/content/runPresence.js +306 -0
  39. package/extension/src/content/runQueueScheduler.js +2 -1
  40. package/extension/src/content/runResultActions.js +123 -3
  41. package/extension/src/content/runTimelineView.js +186 -154
  42. package/extension/src/content/selectionContextView.js +300 -0
  43. package/extension/src/content/sessionPersistence.js +6 -1
  44. package/extension/src/content/settingsPanel.js +77 -52
  45. package/extension/src/content/settingsWorkbench.js +374 -0
  46. package/extension/src/content/sharedSessionViewSync.js +72 -0
  47. package/extension/src/content/subagentActivityView.js +195 -0
  48. package/extension/src/content/trackedChangeCaptureController.js +7 -3
  49. package/extension/src/content/updateNotice.js +121 -50
  50. package/extension/src/content/writebackController.js +257 -0
  51. package/extension/src/content/writebackOrchestrator.js +146 -141
  52. package/extension/src/content/writebackPlan.js +231 -0
  53. package/extension/src/content/writebackRecovery.js +122 -0
  54. package/extension/src/content/writingStyleSettings.js +576 -0
  55. package/extension/src/content/writtenChangesView.js +152 -0
  56. package/extension/src/page/binaryAssetUploader.js +97 -19
  57. package/extension/src/page/overleafProjectSnapshot.js +1 -0
  58. package/extension/src/page/referenceProjects.js +148 -0
  59. package/extension/src/page/saveState.js +14 -2
  60. package/extension/src/page/snapshotRouter.js +44 -13
  61. package/extension/src/page/textCoordinates.js +102 -0
  62. package/extension/src/page/textFileCreator.js +350 -59
  63. package/extension/src/page/trackedChangeCapture.js +42 -56
  64. package/extension/src/page/trackedChangeOwnership.js +198 -0
  65. package/extension/src/page/trackedChangeReplay.js +164 -0
  66. package/extension/src/page/trackedChangesLifecycle.js +135 -149
  67. package/extension/src/page/treeOperations.js +26 -2
  68. package/extension/src/page/writebackReceiptJournal.js +112 -0
  69. package/extension/src/page/writebackRouter.js +175 -135
  70. package/extension/src/pageBridge.js +56 -101
  71. package/extension/src/popup.js +203 -59
  72. package/extension/src/shared/agentTranscript.js +18 -4
  73. package/extension/src/shared/auditRecords.js +71 -0
  74. package/extension/src/shared/changeHistoryModel.js +94 -0
  75. package/extension/src/shared/compatibility.js +1 -1
  76. package/extension/src/shared/compileAdapter.js +42 -0
  77. package/extension/src/shared/failureReasons.js +20 -0
  78. package/extension/src/shared/globalPreferences.js +1 -1
  79. package/extension/src/shared/i18n.js +93 -25
  80. package/extension/src/shared/managedUpdateProjection.js +6 -3
  81. package/extension/src/shared/pageRpcContract.js +7 -1
  82. package/extension/src/shared/providerProfiles.js +109 -0
  83. package/extension/src/shared/runActivityModel.js +361 -0
  84. package/extension/src/shared/runExecutionSnapshot.js +8 -2
  85. package/extension/src/shared/runExecutionSnapshotCodec.js +16 -4
  86. package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
  87. package/extension/src/shared/selectionContext.js +28 -0
  88. package/extension/src/shared/sessionState.js +97 -6
  89. package/extension/src/shared/sharedSessionBridge.js +288 -0
  90. package/extension/src/shared/storageDb.js +22 -55
  91. package/extension/src/shared/storageMigration.js +3 -0
  92. package/extension/src/shared/storageRunActions.js +10 -4
  93. package/extension/src/shared/storageValuePruning.js +40 -0
  94. package/extension/src/shared/subagentActivityModel.js +174 -0
  95. package/extension/src/shared/undoOperations.js +87 -0
  96. package/extension/src/shared/updateConsent.js +37 -8
  97. package/extension/src/shared/writebackIntent.js +62 -0
  98. package/extension/src/shared/writebackSettlement.js +29 -10
  99. package/extension/src/shared/writingStyle.js +33 -0
  100. package/extension/styles/panel.css +1972 -384
  101. package/extension/styles/popup.css +110 -0
  102. package/native-host/src/anthropicBridgeRequest.js +2 -1
  103. package/native-host/src/codexModelRecovery.js +107 -0
  104. package/native-host/src/codexPromptAssembly.js +2 -0
  105. package/native-host/src/codexProviderLaunch.js +3 -3
  106. package/native-host/src/codexRuntimeIdentity.js +1 -0
  107. package/native-host/src/codexSessionRunner.js +106 -140
  108. package/native-host/src/codexSessionTiming.js +3 -0
  109. package/native-host/src/managedInstall.js +5 -4
  110. package/native-host/src/nativeEnvironment.js +70 -0
  111. package/native-host/src/nativeQuotas.js +15 -8
  112. package/native-host/src/overleafWorkspaceRules.js +16 -0
  113. package/native-host/src/processStopBarrier.js +80 -0
  114. package/native-host/src/providerModelCatalog.js +4 -3
  115. package/native-host/src/providerProfile.js +13 -1
  116. package/native-host/src/providerReasoning.js +9 -5
  117. package/native-host/src/providerStore.js +4 -0
  118. package/native-host/src/releaseTransport.js +14 -5
  119. package/native-host/src/selectionScope.js +58 -0
  120. package/native-host/src/skills/parallel-subagents/SKILL.md +31 -3
  121. package/native-host/src/skills/writing-style-builder/SKILL.md +146 -0
  122. package/native-host/src/subagentBroker.js +102 -98
  123. package/native-host/src/subagentTelemetry.js +316 -0
  124. package/native-host/src/subagentWorkspace.js +103 -0
  125. package/native-host/src/subagentWorkspacePath.js +31 -0
  126. package/native-host/src/taskRunnerRuntime.js +55 -5
  127. package/native-host/src/turnAttachments.js +113 -0
  128. package/native-host/src/updateManager.js +122 -12
  129. package/native-host/src/updateNetworkControl.js +75 -0
  130. package/native-host/src/updateTrust.js +21 -2
  131. package/native-host/src/vendor/pdfjs/LICENSE +177 -0
  132. package/native-host/src/vendor/pdfjs/SOURCE.txt +3 -0
  133. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  134. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  135. package/native-host/src/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
  136. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  137. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  138. package/native-host/src/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
  139. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  140. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  141. package/native-host/src/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  142. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  143. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  144. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  145. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  146. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  147. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  148. package/native-host/src/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
  149. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  150. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  151. package/native-host/src/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
  152. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  153. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  154. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  155. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  156. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  157. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  158. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  159. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  160. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  161. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  162. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  163. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  164. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  165. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  166. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  167. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  168. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  169. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  170. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  171. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  172. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  173. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  174. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  175. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  176. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  177. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  178. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  179. package/native-host/src/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
  180. package/native-host/src/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
  181. package/native-host/src/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  182. package/native-host/src/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  183. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  184. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  185. package/native-host/src/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  186. package/native-host/src/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  187. package/native-host/src/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  188. package/native-host/src/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  189. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  190. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  191. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  192. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  193. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  194. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  195. package/native-host/src/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
  196. package/native-host/src/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
  197. package/native-host/src/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
  198. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  199. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  200. package/native-host/src/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
  201. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  202. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  203. package/native-host/src/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
  204. package/native-host/src/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
  205. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  206. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  207. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  208. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  209. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  210. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  211. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  212. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  213. package/native-host/src/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
  214. package/native-host/src/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
  215. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  216. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  217. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  218. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  219. package/native-host/src/vendor/pdfjs/cmaps/H.bcmap +0 -0
  220. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  221. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  222. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  223. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  224. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  225. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  226. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  227. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  228. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  229. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  230. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  231. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  232. package/native-host/src/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
  233. package/native-host/src/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
  234. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  235. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  236. package/native-host/src/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
  237. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  238. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  239. package/native-host/src/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
  240. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  241. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  242. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  243. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  244. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  245. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  246. package/native-host/src/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
  247. package/native-host/src/vendor/pdfjs/cmaps/LICENSE +36 -0
  248. package/native-host/src/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
  249. package/native-host/src/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
  250. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  251. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  252. package/native-host/src/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
  253. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  254. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  255. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  256. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  257. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  258. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  259. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  260. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  261. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  262. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  263. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  264. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  265. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  266. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  267. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  268. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  269. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  270. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  271. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  272. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  273. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  274. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  275. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  276. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  277. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  278. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  279. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  280. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  281. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  282. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  283. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  284. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  285. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  286. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  287. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  288. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  289. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  290. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  291. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  292. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  293. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  294. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  295. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  296. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  297. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  298. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  299. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  300. package/native-host/src/vendor/pdfjs/cmaps/V.bcmap +0 -0
  301. package/native-host/src/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  302. package/native-host/src/vendor/pdfjs/pdf.mjs +26740 -0
  303. package/native-host/src/vendor/pdfjs/pdf.worker.mjs +62201 -0
  304. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  305. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  306. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  307. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  308. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  309. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  310. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  311. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  312. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  313. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  314. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  315. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
  316. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  317. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  318. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  319. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  320. package/native-host/src/writingStyleEvidence.js +102 -0
  321. package/native-host/src/writingStylePdfWorker.js +35 -0
  322. package/native-host/src/writingStyleProfile.js +165 -0
  323. package/native-host/src/writingStyleRuntime.js +447 -0
  324. package/package.json +1 -1
@@ -0,0 +1,300 @@
1
+ (function (root, factory) {
2
+ if (typeof module === 'object' && module.exports) module.exports = factory(require('../shared/selectionContext'));
3
+ else root.CodexOverleafModuleRegistry.define('SelectionContextView', ['SelectionContext'], factory);
4
+ })(typeof globalThis !== 'undefined' ? globalThis : window, function (SelectionContext) {
5
+ 'use strict';
6
+
7
+ // The chip shared by the composer and sent messages: file:lines, the edit-only
8
+ // scope label, and the selected text behind a disclosure.
9
+ function buildChip(selection, { document: doc = globalThis.document, tx = en => en, expanded = false } = {}) {
10
+ const lines = selection.lineStart === selection.lineEnd
11
+ ? String(selection.lineStart) : selection.lineStart + '-' + selection.lineEnd;
12
+ const location = selection.path + ':' + lines;
13
+ const details = doc.createElement('details');
14
+ details.open = expanded;
15
+ const summary = doc.createElement('summary');
16
+ summary.title = location;
17
+ summary.setAttribute('aria-label', tx('Preview selection from ' + location, '预览选区:' + location));
18
+ const file = doc.createElement('span');
19
+ file.className = 'codex-selection-file';
20
+ file.textContent = selection.path.split('/').pop();
21
+ const range = doc.createElement('span');
22
+ range.className = 'codex-selection-range';
23
+ range.textContent = ':' + lines;
24
+ summary.append(file, range);
25
+ if (selection.mode === 'edit') {
26
+ const scope = doc.createElement('span');
27
+ scope.className = 'codex-selection-scope';
28
+ scope.textContent = tx('Selection only', '仅此处');
29
+ summary.append(scope);
30
+ }
31
+ const source = doc.createElement('pre');
32
+ source.textContent = selection.text;
33
+ details.append(summary, source);
34
+ return details;
35
+ }
36
+
37
+ // Read-only chip for a sent message: the selection travels with the run's
38
+ // execution snapshot, so the bubble keeps showing what was attached.
39
+ function renderSent(host, value, options = {}) {
40
+ if (!host) return;
41
+ const selection = SelectionContext.normalize(value);
42
+ host.replaceChildren();
43
+ host.hidden = !selection;
44
+ if (selection) host.append(buildChip(selection, options));
45
+ }
46
+
47
+ function create(deps = {}) {
48
+ let generation = 0;
49
+ let probeGeneration = 0;
50
+ let timer = null;
51
+ let controller = null;
52
+ let toolbar = null;
53
+ let candidate = null;
54
+ let pointerSelecting = false;
55
+ let pointerEditor = null;
56
+ const resetEvent = 'codex-overleaf-selection-ui-reset';
57
+ const tx = (en, zh) => deps.tx ? deps.tx(en, zh) : en;
58
+
59
+ function capture() {
60
+ const selection = SelectionContext.normalize(deps.getState()?.selectionContext);
61
+ return selection?.projectId === deps.getProjectId() ? selection : null;
62
+ }
63
+
64
+ function clear() {
65
+ generation += 1;
66
+ hideFloating();
67
+ deps.setSelection(null);
68
+ render();
69
+ }
70
+
71
+ function render() {
72
+ const panel = deps.getPanel();
73
+ if (toolbar && !toolbar.hidden) syncFloatingAppearance();
74
+ const host = panel?.querySelector('[data-composer-selection]');
75
+ if (!host) return;
76
+ const selection = capture();
77
+ const id = selection ? [selection.projectId, selection.path, selection.from, selection.to,
78
+ selection.documentHash, selection.capturedAt, selection.mode].join(':') : '';
79
+ const expanded = Boolean(id && host.dataset.selectionId === id && host.querySelector('details')?.open);
80
+ host.replaceChildren();
81
+ host.dataset.selectionId = id;
82
+ host.hidden = !selection;
83
+ if (!selection) return;
84
+
85
+ host.append(buildChip(selection, { document, tx, expanded }));
86
+ const remove = document.createElement('button');
87
+ remove.type = 'button';
88
+ remove.textContent = '\u00d7';
89
+ remove.title = tx('Remove selection', '移除选区');
90
+ remove.setAttribute('aria-label', remove.title);
91
+ remove.addEventListener('click', clear);
92
+ host.append(remove);
93
+ }
94
+
95
+ async function attach(mode = 'reference', selected = null) {
96
+ const request = ++generation;
97
+ const projectId = deps.getProjectId();
98
+ const sessionId = deps.getState()?.activeSessionId;
99
+ if (selected && (selected.projectId !== projectId || selected.sessionId !== sessionId)) return null;
100
+ hideFloating();
101
+ try {
102
+ const response = selected
103
+ ? { ok: true, selection: selected.selection }
104
+ : await deps.callPageBridge('getSelectionContext', { runProjectId: projectId });
105
+ if (request !== generation || projectId !== deps.getProjectId()
106
+ || sessionId !== deps.getState()?.activeSessionId) return null;
107
+ const selection = SelectionContext.normalize({
108
+ ...(response?.selection || response), mode: mode === 'edit' ? 'edit' : 'reference'
109
+ });
110
+ if (response?.ok !== true || !selection || selection.projectId !== projectId) {
111
+ deps.toast?.(response?.code === 'selection_too_large'
112
+ ? tx('Select a shorter passage (up to 20,000 characters).', '请选择较短的片段,最多 20,000 个字符。')
113
+ : tx('Select text in the source editor first.', '请先在源码编辑器中选中文字。'));
114
+ return null;
115
+ }
116
+ await deps.openComposer?.();
117
+ if (request !== generation || projectId !== deps.getProjectId()
118
+ || sessionId !== deps.getState()?.activeSessionId) return null;
119
+ deps.setSelection(selection, { edit: selection.mode === 'edit' });
120
+ render();
121
+ const panel = deps.getPanel();
122
+ const tray = panel?.querySelector('[data-context-tray]');
123
+ if (tray) tray.hidden = true;
124
+ panel?.querySelector('[data-add-context]')?.setAttribute('aria-expanded', 'false');
125
+ panel?.querySelector('[data-task]')?.focus();
126
+ return selection;
127
+ } catch (_) {
128
+ if (request === generation && projectId === deps.getProjectId()
129
+ && sessionId === deps.getState()?.activeSessionId) {
130
+ deps.toast?.(tx('Could not attach the selection. Select it again and retry.', '未能添加选区,请重新选取后再试。'));
131
+ }
132
+ return null;
133
+ }
134
+ }
135
+
136
+ function editorFor(node) {
137
+ const element = node?.nodeType === 1 ? node : node?.parentElement;
138
+ const editor = element?.closest?.('.cm-editor');
139
+ return editor && !editor.closest('#codex-overleaf-panel') ? editor : null;
140
+ }
141
+
142
+ function hideFloating() {
143
+ probeGeneration += 1;
144
+ clearTimeout(timer);
145
+ timer = null;
146
+ candidate = null;
147
+ if (!toolbar) return;
148
+ if (typeof toolbar.hidePopover === 'function' && toolbar.matches(':popover-open')) toolbar.hidePopover();
149
+ toolbar.hidden = true;
150
+ }
151
+
152
+ function syncFloatingAppearance() {
153
+ if (!toolbar) return;
154
+ const panel = deps.getPanel();
155
+ const computed = panel ? window.getComputedStyle(panel) : null;
156
+ const theme = deps.getState()?.theme;
157
+ const dark = theme === 'dark' || (theme !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches);
158
+ const colors = dark
159
+ ? ['#26282b', '#f1f2f4', '#adb4be', '#454b53', '#353a41', '#91b7e1']
160
+ : ['#ffffff', '#24292f', '#67717e', '#d8dde3', '#f0f3f6', '#2f73b8'];
161
+ ['--tl-surface-0', '--tl-fg-1', '--tl-fg-3', '--tl-border-strong', '--tl-hover', '--tl-accent']
162
+ .forEach((name, index) => toolbar.style.setProperty(name, computed?.getPropertyValue(name).trim() || colors[index]));
163
+ if (computed?.fontFamily) toolbar.style.fontFamily = computed.fontFamily;
164
+ toolbar.setAttribute('aria-label', tx('Selected text actions', '选区操作'));
165
+ toolbar.querySelector('[data-selection-action="reference"]').textContent = tx('Add to Chat', '加入对话');
166
+ toolbar.querySelector('[data-selection-action="edit"]').textContent = tx('Edit Selection', '仅编辑此处');
167
+ }
168
+
169
+ function ensureToolbar() {
170
+ if (toolbar) return;
171
+ toolbar = document.createElement('div');
172
+ toolbar.className = 'codex-selection-actions';
173
+ toolbar.setAttribute('data-codex-selection-actions', '');
174
+ toolbar.setAttribute('role', 'toolbar');
175
+ toolbar.hidden = true;
176
+ if (typeof toolbar.showPopover === 'function') toolbar.setAttribute('popover', 'manual');
177
+ for (const mode of ['reference', 'edit']) {
178
+ if (mode === 'edit') {
179
+ const divider = document.createElement('span');
180
+ divider.className = 'codex-selection-action-divider';
181
+ divider.setAttribute('aria-hidden', 'true');
182
+ toolbar.append(divider);
183
+ }
184
+ const button = document.createElement('button');
185
+ button.type = 'button';
186
+ button.dataset.selectionAction = mode;
187
+ button.addEventListener('click', () => {
188
+ const selected = candidate;
189
+ if (selected) void attach(mode, selected);
190
+ });
191
+ toolbar.append(button);
192
+ }
193
+ document.body.append(toolbar);
194
+ syncFloatingAppearance();
195
+ }
196
+
197
+ function showFloating(anchor) {
198
+ ensureToolbar();
199
+ syncFloatingAppearance();
200
+ toolbar.hidden = false;
201
+ if (typeof toolbar.showPopover === 'function' && !toolbar.matches(':popover-open')) toolbar.showPopover();
202
+ const rect = toolbar.getBoundingClientRect();
203
+ const width = window.innerWidth, height = window.innerHeight;
204
+ const left = Math.max(8, Math.min(width - rect.width - 8,
205
+ (anchor.left + anchor.right) / 2 - rect.width / 2));
206
+ const preferredTop = anchor.top - rect.height - 8;
207
+ const top = Math.max(8, Math.min(height - rect.height - 8,
208
+ preferredTop >= 8 ? preferredTop : anchor.bottom + 8));
209
+ toolbar.style.left = left + 'px';
210
+ toolbar.style.top = top + 'px';
211
+ }
212
+
213
+ function schedule(editor) {
214
+ hideFloating();
215
+ if (!controller || pointerSelecting || !editor) return;
216
+ const request = ++probeGeneration;
217
+ timer = setTimeout(() => { timer = null; void probe(editor, request); }, 90);
218
+ }
219
+
220
+ async function probe(editor, request) {
221
+ if (!controller || request !== probeGeneration || document.hidden
222
+ || !editor.isConnected || !editor.contains(document.activeElement)) return;
223
+ const projectId = deps.getProjectId();
224
+ const sessionId = deps.getState()?.activeSessionId;
225
+ try {
226
+ const response = await deps.callPageBridge('getSelectionContext', { runProjectId: projectId });
227
+ if (request !== probeGeneration || projectId !== deps.getProjectId()
228
+ || sessionId !== deps.getState()?.activeSessionId || !editor.isConnected
229
+ || !editor.contains(document.activeElement)) return;
230
+ const selection = SelectionContext.normalize(response?.selection || response);
231
+ const anchor = response?.anchor;
232
+ if (!response?.ok || !selection || selection.projectId !== projectId || !anchor
233
+ || !['left', 'right', 'top', 'bottom'].every(key => Number.isFinite(anchor[key]))
234
+ || anchor.bottom < 0 || anchor.top > window.innerHeight) return;
235
+ candidate = { selection, anchor, projectId, sessionId };
236
+ showFloating(anchor);
237
+ } catch (_) { /* Transient editor states do not interrupt ordinary selection. */ }
238
+ }
239
+
240
+ function start() {
241
+ if (controller) return;
242
+ // Replacing a content runtime retires the old selection listener set.
243
+ document.dispatchEvent(new Event(resetEvent));
244
+ controller = new AbortController();
245
+ const options = { capture: true, signal: controller.signal };
246
+ document.addEventListener(resetEvent, destroy, options);
247
+ document.addEventListener('pointerdown', event => {
248
+ if (toolbar?.contains(event.target)) {
249
+ if (event.button === 0) event.preventDefault();
250
+ return;
251
+ }
252
+ hideFloating();
253
+ pointerEditor = editorFor(event.target);
254
+ pointerSelecting = Boolean(pointerEditor && event.button === 0);
255
+ }, options);
256
+ document.addEventListener('pointerup', () => {
257
+ if (!pointerSelecting) return;
258
+ pointerSelecting = false;
259
+ const editor = pointerEditor;
260
+ pointerEditor = null;
261
+ schedule(editor);
262
+ }, options);
263
+ document.addEventListener('pointercancel', () => {
264
+ pointerSelecting = false;
265
+ pointerEditor = null;
266
+ hideFloating();
267
+ }, options);
268
+ document.addEventListener('selectionchange', () => {
269
+ if (pointerSelecting || toolbar?.contains(document.activeElement)) return;
270
+ schedule(editorFor(document.activeElement));
271
+ }, options);
272
+ document.addEventListener('keyup', event => {
273
+ if (event.key !== 'Escape' && editorFor(event.target)) schedule(editorFor(event.target));
274
+ }, options);
275
+ document.addEventListener('keydown', event => {
276
+ if (event.key === 'Escape') hideFloating();
277
+ }, options);
278
+ document.addEventListener('scroll', hideFloating, { ...options, passive: true });
279
+ document.addEventListener('visibilitychange', () => { if (document.hidden) hideFloating(); }, options);
280
+ window.addEventListener('resize', hideFloating, { ...options, passive: true });
281
+ window.addEventListener('blur', hideFloating, options);
282
+ window.addEventListener('pagehide', event => { if (event.persisted) hideFloating(); else destroy(); }, options);
283
+ }
284
+
285
+ function destroy() {
286
+ generation += 1;
287
+ hideFloating();
288
+ controller?.abort();
289
+ controller = null;
290
+ pointerSelecting = false;
291
+ pointerEditor = null;
292
+ toolbar?.remove();
293
+ toolbar = null;
294
+ }
295
+
296
+ return { attach, capture, clear, render, start, destroy };
297
+ }
298
+
299
+ return { create, buildChip, renderSent };
300
+ });
@@ -85,7 +85,12 @@
85
85
  record !== rawExistingSessions[index] && !writable.some(item => item.id === record.id)
86
86
  );
87
87
  if (cleanedExisting.length || writable.length) {
88
- await StorageDb.putRecords('sessions', [...cleanedExisting, ...writable]);
88
+ const written = await StorageDb.putRecords('sessions', [...cleanedExisting, ...writable], {
89
+ reviewRunIds: options.reviewRunIds
90
+ });
91
+ // Check the actual durable result, including a decision already saved
92
+ // from another origin, instead of acknowledging only the proposed view.
93
+ return written.filter(record => writable.some(candidate => candidate.id === record.id));
89
94
  }
90
95
  return writable;
91
96
  }
@@ -1,4 +1,10 @@
1
- (function initCodexOverleafSettingsPanel() {
1
+ (function (root, factory) {
2
+ if (typeof module === 'object' && module.exports) {
3
+ module.exports = factory(require('./settingsWorkbench'));
4
+ } else {
5
+ root.CodexOverleafModuleRegistry.define('SettingsPanel', ['SettingsWorkbench'], factory);
6
+ }
7
+ })(typeof globalThis !== 'undefined' ? globalThis : this, function settingsPanelFactory(SettingsWorkbench) {
2
8
  'use strict';
3
9
 
4
10
  function codexIcon(name) {
@@ -45,10 +51,16 @@
45
51
  <div class="codex-project-settings-status" data-project-settings-status></div>
46
52
  <div class="codex-project-settings-scope">
47
53
  <div class="codex-project-settings-scope-title codex-set-eyebrow" data-i18n="settingsScopeProjectTitle">This project</div>
54
+ <details class="codex-set-group" data-set-group="writing-style" open>
55
+ <summary class="codex-set-group-head">
56
+ <span class="codex-set-group-title">${codexSetIcon('pen')}<span data-writing-style-heading>Writing style</span></span>
57
+ </summary>
58
+ <div class="codex-set-card" data-writing-style-settings></div>
59
+ </details>
48
60
  <details class="codex-set-group" data-set-group="personalization" open>
49
61
  <summary class="codex-set-group-head">
50
62
  <span class="codex-set-group-title">${codexSetIcon('pen')}<span data-i18n="personalizationConfig">Personalization</span></span>
51
- <span class="codex-set-saved" data-set-saved hidden>✓ <span data-i18n="settingsSaved">Saved</span></span>
63
+ <span class="codex-set-saved" data-set-saved hidden><svg class="codex-glyph" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="m3.5 8 3 3 6-6"/></svg><span data-i18n="settingsSaved">Saved</span></span>
52
64
  </summary>
53
65
  <div class="codex-set-card">
54
66
  <p class="codex-set-row-help" data-i18n="personalizationHelp">Style, terminology, and LaTeX conventions Codex should follow in this project.</p>
@@ -58,7 +70,7 @@
58
70
  <details class="codex-set-group" data-set-group="protection" open>
59
71
  <summary class="codex-set-group-head">
60
72
  <span class="codex-set-group-title">${codexSetIcon('shield')}<span data-i18n="fileProtectionTitle">File protection</span></span>
61
- <span class="codex-set-saved" data-set-saved hidden>✓ <span data-i18n="settingsSaved">Saved</span></span>
73
+ <span class="codex-set-saved" data-set-saved hidden><svg class="codex-glyph" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="m3.5 8 3 3 6-6"/></svg><span data-i18n="settingsSaved">Saved</span></span>
62
74
  </summary>
63
75
  <div class="codex-set-card">
64
76
  <div class="codex-set-row">
@@ -78,7 +90,7 @@
78
90
  <details class="codex-set-group" data-set-group="privacy" open>
79
91
  <summary class="codex-set-group-head">
80
92
  <span class="codex-set-group-title">${codexSetIcon('lock')}<span data-i18n="privacyTitle">Privacy</span></span>
81
- <span class="codex-set-saved" data-set-saved hidden>✓ <span data-i18n="settingsSaved">Saved</span></span>
93
+ <span class="codex-set-saved" data-set-saved hidden><svg class="codex-glyph" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="m3.5 8 3 3 6-6"/></svg><span data-i18n="settingsSaved">Saved</span></span>
82
94
  </summary>
83
95
  <div class="codex-set-card">
84
96
  <label class="codex-project-settings-row codex-project-settings-row--switch">
@@ -96,7 +108,7 @@
96
108
  <details class="codex-set-group" data-set-group="experimental">
97
109
  <summary class="codex-set-group-head">
98
110
  <span class="codex-set-group-title">${codexSetIcon('database')}<span data-i18n="otSettingsTitle">Project cache</span></span>
99
- <span class="codex-set-saved" data-set-saved hidden>✓ <span data-i18n="settingsSaved">Saved</span></span>
111
+ <span class="codex-set-saved" data-set-saved hidden><svg class="codex-glyph" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="m3.5 8 3 3 6-6"/></svg><span data-i18n="settingsSaved">Saved</span></span>
100
112
  </summary>
101
113
  <div class="codex-set-card">
102
114
  <label class="codex-project-settings-row codex-project-settings-row--switch">
@@ -113,19 +125,37 @@
113
125
  <div class="codex-project-settings-scope codex-project-settings-scope--global">
114
126
  <details class="codex-set-group" data-set-group="history" data-history-card>
115
127
  <summary class="codex-set-group-head">
116
- <span class="codex-set-group-title">${codexSetIcon('history')}<span data-i18n="historyTitle">Change history</span></span>
128
+ <span class="codex-set-group-title">${codexSetIcon('history')}<span data-i18n="historyTitle">File changes</span><span class="codex-history-count" data-history-count aria-live="polite"></span></span>
117
129
  </summary>
118
130
  <div class="codex-set-card">
119
- <p class="codex-set-row-help" data-i18n="historyHelp">What Codex wrote to this project, per run. Filter by file name or task text.</p>
120
- <input type="text" class="codex-set-select codex-history-filter" data-history-filter>
131
+ <p class="codex-set-row-help" data-i18n="historyHelp">Review recent file changes and open the matching conversation.</p>
132
+ <div class="codex-history-toolbar">
133
+ <label class="codex-history-search">
134
+ <span class="codex-history-search-mark" aria-hidden="true"></span>
135
+ <input type="search" class="codex-set-select codex-history-filter" data-history-filter autocomplete="off">
136
+ </label>
137
+ <select class="codex-set-select codex-history-status-filter" data-history-status data-i18n-aria-label="historyStatusLabel">
138
+ <option value="all" data-i18n="historyStatusAll">All statuses</option>
139
+ <option value="pending" data-i18n="historyStatusPending">Pending review</option>
140
+ <option value="accepted" data-i18n="historyStatusAccepted">Accepted</option>
141
+ <option value="undone" data-i18n="historyStatusUndone">Undone</option>
142
+ <option value="attention" data-i18n="historyStatusAttention">Needs attention</option>
143
+ <option value="written" data-i18n="historyStatusWritten">Written</option>
144
+ </select>
145
+ </div>
121
146
  <div class="codex-history-list" data-history-list></div>
147
+ <button type="button" class="codex-history-jump codex-history-more" data-history-more hidden></button>
148
+ <label class="codex-history-include" hidden>
149
+ <input type="checkbox" data-history-include-empty>
150
+ <span data-history-include-label></span>
151
+ </label>
122
152
  </div>
123
153
  </details>
124
154
  <div class="codex-project-settings-scope-title codex-set-eyebrow" data-i18n="settingsScopeGlobalTitle">All projects</div>
125
155
  <details class="codex-set-group" data-set-group="appearance" open>
126
156
  <summary class="codex-set-group-head">
127
157
  <span class="codex-set-group-title">${codexSetIcon('appearance')}<span data-i18n="appearanceTitle">Appearance</span></span>
128
- <span class="codex-set-saved" data-set-saved hidden>✓ <span data-i18n="settingsSaved">Saved</span></span>
158
+ <span class="codex-set-saved" data-set-saved hidden><svg class="codex-glyph" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="m3.5 8 3 3 6-6"/></svg><span data-i18n="settingsSaved">Saved</span></span>
129
159
  </summary>
130
160
  <div class="codex-set-card">
131
161
  <label class="codex-project-settings-row codex-project-settings-row--select">
@@ -153,7 +183,7 @@
153
183
  </summary>
154
184
  <div class="codex-set-card codex-provider-settings-entry">
155
185
  <div class="codex-provider-settings-entry-copy">
156
- <p class="codex-set-row-help" data-i18n="providerSettingsHelp">Configure experimental third-party model APIs. Compatibility varies by provider and gateway.</p>
186
+ <p class="codex-set-row-help" data-i18n="providerSettingsHelp">Manage model API connections.</p>
157
187
  <p class="codex-provider-settings-summary" data-provider-settings-summary data-tone="loading">${t(instance, 'providerSettingsLoading')}</p>
158
188
  </div>
159
189
  <button type="button" class="codex-set-btn" data-provider-settings-open data-i18n="providerSettingsConfigure">Configure</button>
@@ -162,7 +192,7 @@
162
192
  <details class="codex-set-group" data-set-group="context-loading" open>
163
193
  <summary class="codex-set-group-head">
164
194
  <span class="codex-set-group-title">${codexSetIcon('database')}<span data-i18n="contextLoadingTitle">Context loading</span></span>
165
- <span class="codex-set-saved" data-set-saved hidden>✓ <span data-i18n="settingsSaved">Saved</span></span>
195
+ <span class="codex-set-saved" data-set-saved hidden><svg class="codex-glyph" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="m3.5 8 3 3 6-6"/></svg><span data-i18n="settingsSaved">Saved</span></span>
166
196
  </summary>
167
197
  <div class="codex-set-card">
168
198
  <label class="codex-project-settings-row codex-project-settings-row--switch">
@@ -186,18 +216,24 @@
186
216
  </details>
187
217
  <details class="codex-set-group" data-set-group="storage" data-storage-card>
188
218
  <summary class="codex-set-group-head">
189
- <span class="codex-set-group-title">${codexSetIcon('database')}<span data-i18n="storageTitle">History &amp; storage</span></span>
219
+ <span class="codex-set-group-title">${codexSetIcon('database')}<span data-i18n="storageTitle">Local data</span></span>
190
220
  </summary>
191
221
  <div class="codex-set-card">
192
- <p class="codex-set-row-help" data-storage-usage data-i18n="storageUsageLoading">Calculating usage…</p>
193
- <button type="button" class="codex-set-btn codex-set-btn--danger" data-clear-all-history data-i18n="storageClearAll">Clear all history…</button>
194
- <p class="codex-set-row-help" data-i18n="storageClearAllHelp">Removes every stored session, run and audit record for all projects. Project settings and rules are kept.</p>
222
+ <div class="codex-storage-data-row">
223
+ <div class="codex-storage-data-copy">
224
+ <div class="codex-storage-data-label" data-i18n="storageSavedData">Saved conversations &amp; records</div>
225
+ <p class="codex-set-row-help" data-storage-usage data-i18n="storageUsageLoading">Loading saved history…</p>
226
+ </div>
227
+ <button type="button" class="codex-set-btn codex-set-btn--danger" data-clear-all-history data-i18n="storageClearAll">Clear local history…</button>
228
+ </div>
229
+ <p class="codex-set-row-help codex-storage-clear-help" data-i18n="storageClearAllHelp">Clearing removes local history and undo information. Overleaf project files stay unchanged.</p>
230
+ <p class="codex-storage-estimate" data-storage-estimate aria-live="polite"></p>
195
231
  </div>
196
232
  </details>
197
233
  <details class="codex-set-group" data-set-group="skills" open>
198
234
  <summary class="codex-set-group-head">
199
235
  <span class="codex-set-group-title">${codexSetIcon('bolt')}<span data-i18n="localSkillsTitle">Skills</span></span>
200
- <span class="codex-set-saved" data-set-saved hidden>✓ <span data-i18n="settingsSaved">Saved</span></span>
236
+ <span class="codex-set-saved" data-set-saved hidden><svg class="codex-glyph" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="m3.5 8 3 3 6-6"/></svg><span data-i18n="settingsSaved">Saved</span></span>
201
237
  </summary>
202
238
  <div class="codex-set-card">
203
239
  <label class="codex-project-settings-row codex-project-settings-row--switch">
@@ -220,7 +256,7 @@
220
256
  <div>
221
257
  <div class="codex-custom-instructions-title" data-i18n="codexOverleafSkillsTitle">Codex Overleaf skills</div>
222
258
  </div>
223
- <span class="codex-set-saved" data-set-saved hidden>✓ <span data-i18n="settingsSaved">Saved</span></span>
259
+ <span class="codex-set-saved" data-set-saved hidden><svg class="codex-glyph" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="m3.5 8 3 3 6-6"/></svg><span data-i18n="settingsSaved">Saved</span></span>
224
260
  </div>
225
261
  <div class="codex-set-card">
226
262
  <label class="codex-project-settings-row codex-project-settings-row--switch">
@@ -247,6 +283,8 @@
247
283
  if (event.target.open) instance.callbacks.onStorageOpen?.();
248
284
  });
249
285
  container.querySelector('[data-history-filter]')?.addEventListener('input', () => instance.callbacks.onHistoryFilter?.());
286
+ container.querySelector('[data-history-status]')?.addEventListener('change', () => instance.callbacks.onHistoryFilter?.());
287
+ container.querySelector('[data-history-include-empty]')?.addEventListener('change', () => instance.callbacks.onHistoryFilter?.());
250
288
  // OT mirror: a single visible switch; legacy storage/DOM keys are retained. The click is
251
289
  // intercepted (the runtime's handler preventDefaults, runs the enable
252
290
  // confirmation, then sets checked + drives the change flow itself) so the
@@ -265,8 +303,9 @@
265
303
  Promise.resolve(instance.callbacks.onInputChange?.(event))
266
304
  .then(() => {
267
305
  flashSaved(instance, event);
268
- if (selector === '[data-language-select]' && container.querySelector('[data-storage-card]')?.open) {
269
- instance.callbacks.onStorageOpen?.();
306
+ if (selector === '[data-language-select]') {
307
+ if (container.querySelector('[data-storage-card]')?.open) instance.callbacks.onStorageOpen?.();
308
+ instance.callbacks.onHistoryFilter?.();
270
309
  }
271
310
  }).catch(() => {});
272
311
  });
@@ -280,12 +319,18 @@
280
319
  element?.addEventListener?.('input', () => updateGovernanceNotes(instance));
281
320
  element?.addEventListener?.('change', () => updateGovernanceNotes(instance));
282
321
  }
283
- setupGroupPersistence(instance);
322
+ instance.workbench = SettingsWorkbench.mount(instance, { icon: codexIcon });
284
323
 
285
324
  return {
286
325
  get container() { return instance.container; },
287
326
  show: () => show(instance),
288
327
  hide: () => hide(instance),
328
+ openProviderPage: () => {
329
+ const host = instance.workbench?.revealProviders();
330
+ if (host) show(instance);
331
+ return host || null;
332
+ },
333
+ setProviderCloseGuard: guard => instance.workbench?.setProviderCloseGuard(guard),
289
334
  loadState: state => loadState(instance, state),
290
335
  readState: () => readState(instance),
291
336
  setStatus: (text, status) => setStatus(instance, text, status),
@@ -310,10 +355,12 @@
310
355
  button.dataset.active = 'true';
311
356
  button.setAttribute('aria-expanded', 'true');
312
357
  }
313
- root.querySelector('[data-custom-instructions-input]')?.focus?.();
358
+ if (instance.workbench) instance.workbench.show();
359
+ else root.querySelector('[data-custom-instructions-input]')?.focus?.();
314
360
  }
315
361
 
316
362
  function refreshSettingsScope(instance, root) {
363
+ if (instance.workbench) { instance.workbench.refresh(); return; }
317
364
  const accountScope = instance.container?.closest?.('[data-settings-scope]')?.dataset?.settingsScope === 'account';
318
365
  const prefix = accountScope ? 'recentProjects_settings' : 'projectSettings';
319
366
  for (const [selector, suffix] of [['[data-settings-title]', 'Title'], ['[data-settings-subtitle]', 'Subtitle']]) {
@@ -337,6 +384,7 @@
337
384
  button.setAttribute('aria-expanded', 'false');
338
385
  }
339
386
  clearStatus(instance);
387
+ instance.workbench?.hide();
340
388
  }
341
389
 
342
390
  function isVisible(target) {
@@ -386,6 +434,7 @@
386
434
  setValue(scope, '[data-theme-select]', state.theme || 'dark');
387
435
  setValue(scope, '[data-language-select]', state.language || 'en');
388
436
  }
437
+ instance.workbench?.refresh();
389
438
  }
390
439
 
391
440
  function readState(target) {
@@ -413,7 +462,7 @@
413
462
 
414
463
  function setStatus(target, text, status = 'info') {
415
464
  const instance = target?._instance || target;
416
- const element = getRoot(instance)?.querySelector('[data-project-settings-status]');
465
+ const element = instance?.container?.querySelector('[data-project-settings-status]');
417
466
  if (!element) {
418
467
  return;
419
468
  }
@@ -423,7 +472,7 @@
423
472
 
424
473
  function clearStatus(target) {
425
474
  const instance = target?._instance || target;
426
- const element = getRoot(instance)?.querySelector('[data-project-settings-status]');
475
+ const element = instance?.container?.querySelector('[data-project-settings-status]');
427
476
  if (!element) {
428
477
  return;
429
478
  }
@@ -440,11 +489,11 @@
440
489
  element.textContent = text || '';
441
490
  }
442
491
 
443
- // Flash the "✓ Saved" indicator after a field auto-saves, then fade it out.
492
+ // Flash the check-mark "Saved" indicator after a field auto-saves, then fade it out.
444
493
  // The fields persist immediately on change, so this is purely a confirmation
445
494
  // cue — it never gates the save itself.
446
495
  function flashSaved(instance, event) {
447
- // Card-level feedback: the ✓ appears on the card that was actually
496
+ // Card-level feedback: the check appears on the card that was actually
448
497
  // changed (falls back to the screen's first badge, e.g. the skills page).
449
498
  const origin = event?.target?.closest?.('details.codex-set-group, section');
450
499
  const badge = origin?.querySelector?.('[data-set-saved]')
@@ -530,31 +579,6 @@
530
579
  element.dataset.tone = typeof value === 'object' && value.tone ? value.tone : 'ok';
531
580
  }
532
581
 
533
- // Collapse memory: card open/closed state persists per browser profile.
534
- const GROUP_STORE_KEY = 'codexOverleafSettingsGroups';
535
-
536
- function setupGroupPersistence(instance) {
537
- let stored = {};
538
- try {
539
- stored = JSON.parse(globalThis.localStorage?.getItem(GROUP_STORE_KEY) || '{}') || {};
540
- } catch (_error) {
541
- stored = {};
542
- }
543
- for (const details of instance.container.querySelectorAll('details[data-set-group]')) {
544
- const key = details.dataset.setGroup;
545
- if (key in stored) {
546
- details.open = stored[key] !== false;
547
- }
548
- details.addEventListener('toggle', () => {
549
- try {
550
- const current = JSON.parse(globalThis.localStorage?.getItem(GROUP_STORE_KEY) || '{}') || {};
551
- current[key] = details.open;
552
- globalThis.localStorage?.setItem(GROUP_STORE_KEY, JSON.stringify(current));
553
- } catch (_error) { /* private mode — collapse state just doesn't persist */ }
554
- });
555
- }
556
- }
557
-
558
582
  function getRoot(instance) {
559
583
  return instance?.container?.querySelector('[data-project-settings-panel]') || null;
560
584
  }
@@ -582,6 +606,7 @@
582
606
  }
583
607
 
584
608
  function destroy(instance) {
609
+ instance.workbench?.destroy();
585
610
  if (instance._savedFlashTimer) {
586
611
  clearTimeout(instance._savedFlashTimer);
587
612
  instance._savedFlashTimer = null;
@@ -589,7 +614,7 @@
589
614
  instance.container.textContent = '';
590
615
  }
591
616
 
592
- window.CodexOverleafSettingsPanel = {
617
+ return {
593
618
  create,
594
619
  loadState,
595
620
  readState,
@@ -601,4 +626,4 @@
601
626
  setSkillsSummary,
602
627
  setProviderSummary
603
628
  };
604
- })();
629
+ });