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,374 @@
1
+ (function (root, factory) {
2
+ if (typeof module === 'object' && module.exports) module.exports = factory();
3
+ else root.CodexOverleafModuleRegistry.define('SettingsWorkbench', [], factory);
4
+ })(typeof globalThis !== 'undefined' ? globalThis : this, function () {
5
+ 'use strict';
6
+
7
+ const CATEGORIES = [
8
+ ['general', 'settingsWorkbenchGeneral', 'appearance'],
9
+ ['providers', 'settingsWorkbenchModels', 'bolt'],
10
+ ['context', 'settingsWorkbenchContext', 'database'],
11
+ ['instructions', 'settingsWorkbenchInstructions', 'pen'],
12
+ ['protection', 'settingsWorkbenchProtection', 'shield'],
13
+ ['history', 'settingsWorkbenchHistory', 'history'],
14
+ ['updates', 'softwareUpdatesTitle', 'software']
15
+ ];
16
+ const GROUP_PAGES = {
17
+ appearance: 'general', 'writing-style': 'general', providers: 'providers', 'context-loading': 'context',
18
+ experimental: 'context', personalization: 'instructions', protection: 'protection',
19
+ privacy: 'protection', history: 'history', storage: 'history', updates: 'updates'
20
+ };
21
+ const PROJECT_GROUPS = new Set(['writing-style', 'personalization', 'protection', 'privacy', 'experimental', 'history']);
22
+
23
+ function mount(instance, options = {}) {
24
+ const container = instance.container, doc = container.ownerDocument;
25
+ const panel = container.closest('#codex-overleaf-panel');
26
+ const settings = container.querySelector('[data-project-settings-panel]');
27
+ const skills = container.querySelector('.codex-skills-panel');
28
+ if (!panel || !settings || !doc) return null;
29
+ const win = doc.defaultView;
30
+ const t = key => instance.i18n?.tr?.(key) || key;
31
+ const listeners = [];
32
+ const listen = (node, name, listener, eventOptions) => {
33
+ node?.addEventListener(name, listener, eventOptions);
34
+ listeners.push(() => node?.removeEventListener(name, listener, eventOptions));
35
+ };
36
+ const make = (tag, className, key) => {
37
+ const node = doc.createElement(tag);
38
+ if (className) node.className = className;
39
+ if (key) { node.dataset.i18n = key; node.textContent = t(key); }
40
+ return node;
41
+ };
42
+ const button = (className, key) => {
43
+ const node = make('button', className, key);
44
+ node.type = 'button';
45
+ return node;
46
+ };
47
+ const originalHead = settings.querySelector('.codex-custom-instructions-head');
48
+ const closeButton = originalHead?.querySelector('[data-settings-back]')
49
+ || button('', 'settingsWorkbenchClose');
50
+ const status = settings.querySelector('[data-project-settings-status]');
51
+ const dialog = make('dialog', 'codex-settings-workbench');
52
+ dialog.setAttribute('aria-labelledby', 'codex-settings-workbench-title');
53
+ const header = make('header', 'codex-wb-header');
54
+ const heading = make('div', 'codex-wb-heading');
55
+ const title = make('h2', '', 'settingsWorkbenchTitle');
56
+ title.id = 'codex-settings-workbench-title';
57
+ heading.append(title, make('p', '', 'settingsWorkbenchSubtitle'));
58
+ closeButton.classList.add('codex-wb-close');
59
+ closeButton.textContent = '\u00d7';
60
+ header.append(heading, closeButton);
61
+ originalHead?.remove();
62
+
63
+ const layout = make('div', 'codex-wb-layout');
64
+ const sidebar = make('aside', 'codex-wb-sidebar');
65
+ const filters = make('div', 'codex-wb-filters');
66
+ filters.setAttribute('role', 'group');
67
+ const allFilter = button('', 'settingsWorkbenchAll');
68
+ const projectFilter = button('', 'settingsScopeProjectTitle');
69
+ filters.append(allFilter, projectFilter);
70
+ const nav = make('nav', 'codex-wb-nav');
71
+ nav.setAttribute('role', 'tablist');
72
+ nav.setAttribute('aria-orientation', 'vertical');
73
+ const brand = make('div', 'codex-wb-brand');
74
+ brand.textContent = 'Codex Overleaf Link';
75
+ sidebar.append(filters, nav, brand);
76
+ const main = make('div', 'codex-wb-main');
77
+ const body = make('div', 'codex-wb-body');
78
+ const footer = make('footer', 'codex-wb-footer');
79
+ if (status) { status.setAttribute('aria-live', 'polite'); footer.append(status); }
80
+ main.append(body, footer);
81
+ layout.append(sidebar, main);
82
+ dialog.append(header, layout);
83
+ const pages = new Map(), navButtons = new Map(), groups = [];
84
+ let active = 'general', filter = 'all', returnFocus = null, destroyed = false;
85
+ let providerRequested = false, providerCloseGuard = null, closing = null;
86
+
87
+ for (const [id, key, icon] of CATEGORIES) {
88
+ const page = make('section', 'codex-wb-page');
89
+ page.id = 'codex-settings-page-' + id;
90
+ page.dataset.workbenchPage = id;
91
+ page.setAttribute('role', 'tabpanel');
92
+ page.setAttribute('aria-labelledby', 'codex-settings-nav-' + id);
93
+ page.hidden = true;
94
+ page.append(make('h3', 'codex-wb-page-title', key));
95
+ pages.set(id, page);
96
+ const tab = button('codex-wb-nav-button');
97
+ tab.id = 'codex-settings-nav-' + id;
98
+ tab.setAttribute('role', 'tab');
99
+ tab.setAttribute('aria-controls', page.id);
100
+ if (options.icon) {
101
+ const glyph = make('span', 'codex-wb-nav-icon');
102
+ glyph.innerHTML = options.icon(icon); // Static, repository-owned icon paths only.
103
+ tab.append(glyph);
104
+ }
105
+ tab.append(make('span', '', key));
106
+ listen(tab, 'click', () => select(id));
107
+ nav.append(tab);
108
+ navButtons.set(id, tab);
109
+ }
110
+ function addGroup(node, category, projectOnly) {
111
+ node.hidden = true;
112
+ node.dataset.workbenchScope = projectOnly ? 'project' : 'global';
113
+ const summary = node.querySelector('summary');
114
+ const badge = make('span', 'codex-wb-scope-label',
115
+ projectOnly ? 'settingsScopeProjectTitle' : 'settingsScopeGlobalTitle');
116
+ (summary || node).append(badge);
117
+ pages.get(category).append(node);
118
+ groups.push({ node, category, projectOnly, expanded: true });
119
+ }
120
+ // Move existing controls rather than copying them. Their listeners, unsaved
121
+ // values, identity, validation and persistence callbacks remain attached.
122
+ for (const group of Array.from(settings.querySelectorAll('[data-set-group]'))) {
123
+ const key = group.dataset.setGroup;
124
+ const originalScope = group.closest('.codex-project-settings-scope');
125
+ const projectOnly = PROJECT_GROUPS.has(key)
126
+ || (!GROUP_PAGES[key] && originalScope && !originalScope.classList.contains('codex-project-settings-scope--global'));
127
+ addGroup(group, GROUP_PAGES[key] || 'instructions', Boolean(projectOnly));
128
+ }
129
+ // Preserve non-card controls, including the legacy skill-loading entry.
130
+ // Scope headings are replaced by labels on the actual groups.
131
+ for (const scope of Array.from(settings.querySelectorAll('.codex-project-settings-scope'))) {
132
+ scope.querySelectorAll('.codex-project-settings-scope-title').forEach(node => node.remove());
133
+ if (scope.children.length) {
134
+ addGroup(scope, 'instructions', !scope.classList.contains('codex-project-settings-scope--global'));
135
+ } else scope.remove();
136
+ }
137
+ for (const node of Array.from(settings.children)) {
138
+ if (node === status) continue;
139
+ addGroup(node, 'instructions', false);
140
+ }
141
+ const providerHost = make('div', 'codex-wb-provider-host');
142
+ providerHost.dataset.providerSettingsHost = '';
143
+ pages.get('providers').append(providerHost);
144
+ settings.append(...pages.values());
145
+ body.append(settings);
146
+ if (skills) {
147
+ const back = skills.querySelector('[data-skills-back]');
148
+ if (back) back.innerHTML = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="m9.5 4-4 4 4 4"/></svg>';
149
+ const masterRow = skills.querySelector('[data-load-codex-overleaf-skills]')?.closest('label');
150
+ const masterTitle = masterRow?.querySelector('.codex-project-settings-row-label');
151
+ if (masterRow && masterTitle) {
152
+ if (masterRow.parentElement !== skills) {
153
+ masterRow.parentElement.classList.remove('codex-set-card');
154
+ masterRow.parentElement.classList.add('codex-wb-skills-master');
155
+ }
156
+ masterRow.classList.add('codex-wb-skills-master-row');
157
+ masterTitle.dataset.i18n = 'settingsWorkbenchEnableSkills';
158
+ masterTitle.classList.add('codex-wb-skills-caption');
159
+ const copy = make('div', 'codex-wb-skills-master-copy');
160
+ masterTitle.before(copy);
161
+ copy.append(masterTitle, make('p', 'codex-wb-skills-help codex-wb-skills-caption', 'settingsWorkbenchSkillsHelp'));
162
+ }
163
+ skills.querySelector('[data-local-skill-list]')?.before(
164
+ make('div', 'codex-wb-skills-list-title codex-wb-skills-caption', 'settingsWorkbenchSkillsList')
165
+ );
166
+ body.append(skills);
167
+ }
168
+ container.append(dialog);
169
+ panel.dataset.settingsWorkbench = 'true';
170
+
171
+ const themeSelect = settings.querySelector('[data-theme-select]');
172
+ let themeChoices = null;
173
+ if (themeSelect) {
174
+ const row = themeSelect.closest('label') || themeSelect;
175
+ themeSelect.hidden = true;
176
+ themeChoices = make('div', 'codex-wb-themes');
177
+ themeChoices.setAttribute('role', 'radiogroup');
178
+ for (const [value, key] of [['light', 'themeLight'], ['dark', 'themeDark'], ['auto', 'themeAuto']]) {
179
+ const choice = button('codex-wb-theme-choice');
180
+ choice.dataset.themeChoice = value;
181
+ choice.setAttribute('role', 'radio');
182
+ const preview = make('span', 'codex-wb-theme-preview');
183
+ preview.dataset.previewTheme = value;
184
+ preview.setAttribute('aria-hidden', 'true');
185
+ const lines = make('span', 'codex-wb-theme-lines');
186
+ lines.append(make('b'), make('b'), make('b'));
187
+ preview.append(lines);
188
+ choice.append(preview, make('span', 'codex-wb-theme-caption', key));
189
+ listen(choice, 'click', () => {
190
+ themeSelect.value = value;
191
+ themeSelect.dispatchEvent(new win.Event('input', { bubbles: true }));
192
+ themeSelect.dispatchEvent(new win.Event('change', { bubbles: true }));
193
+ updateThemes();
194
+ });
195
+ themeChoices.append(choice);
196
+ }
197
+ row.after(themeChoices);
198
+ listen(themeChoices, 'keydown', event => {
199
+ const choices = Array.from(themeChoices.querySelectorAll('button'));
200
+ const index = choices.indexOf(event.target);
201
+ if (index < 0 || !['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) return;
202
+ event.preventDefault(); event.stopPropagation();
203
+ const next = event.key === 'Home' ? 0 : event.key === 'End' ? choices.length - 1
204
+ : (index + (event.key === 'ArrowLeft' ? -1 : 1) + choices.length) % choices.length;
205
+ choices[next].click(); choices[next].focus();
206
+ });
207
+ }
208
+ function updateThemes() {
209
+ themeChoices?.setAttribute('aria-label', t('themeLabel'));
210
+ for (const choice of themeChoices?.querySelectorAll('button') || []) {
211
+ const selected = choice.dataset.themeChoice === themeSelect.value;
212
+ choice.setAttribute('aria-checked', String(selected));
213
+ choice.tabIndex = selected ? 0 : -1;
214
+ }
215
+ }
216
+ function hasProject() {
217
+ return panel.dataset.settingsScope !== 'account'
218
+ && /^\/project\/[^/]+/.test(win?.location?.pathname || '');
219
+ }
220
+ function available(item) {
221
+ return (!item.projectOnly || hasProject()) && (filter !== 'project' || item.projectOnly);
222
+ }
223
+ function refresh() {
224
+ if (destroyed) return;
225
+ if (!hasProject()) filter = 'all';
226
+ if (panel.dataset.view === 'skills') { active = 'instructions'; filter = 'all'; }
227
+ const availablePages = new Set(groups.filter(available).map(item => item.category));
228
+ if (!availablePages.has(active)) active = CATEGORIES.find(([id]) => availablePages.has(id))?.[0] || 'general';
229
+ for (const node of dialog.querySelectorAll('[data-i18n]')) {
230
+ // Existing controls use their established translation pass; update the
231
+ // newly owned chrome only, without replacing controls or skill rows.
232
+ if (node.closest('.codex-wb-header, .codex-wb-nav, .codex-wb-filters, .codex-wb-footer')
233
+ || node.classList.contains('codex-wb-page-title')
234
+ || node.classList.contains('codex-wb-scope-label')
235
+ || node.classList.contains('codex-wb-theme-caption')
236
+ || node.classList.contains('codex-wb-skills-caption')) node.textContent = t(node.dataset.i18n);
237
+ }
238
+ projectFilter.disabled = !hasProject();
239
+ projectFilter.title = hasProject() ? t('settingsWorkbenchProjectFilter') : t('settingsWorkbenchOpenProject');
240
+ filters.setAttribute('aria-label', t('settingsWorkbenchFilter'));
241
+ nav.setAttribute('aria-label', t('settingsWorkbenchCategories'));
242
+ allFilter.setAttribute('aria-pressed', String(filter === 'all'));
243
+ projectFilter.setAttribute('aria-pressed', String(filter === 'project'));
244
+ closeButton.title = t('settingsWorkbenchClose');
245
+ closeButton.setAttribute('aria-label', t('settingsWorkbenchClose'));
246
+ for (const [id, tab] of navButtons) {
247
+ tab.hidden = !availablePages.has(id);
248
+ tab.setAttribute('aria-selected', String(id === active));
249
+ tab.tabIndex = id === active ? 0 : -1;
250
+ pages.get(id).hidden = id !== active;
251
+ }
252
+ for (const item of groups) {
253
+ const visible = available(item) && item.category === active && panel.dataset.view !== 'skills';
254
+ if (item.node.tagName === 'DETAILS' && item.node.hidden !== !visible) {
255
+ if (!visible) item.expanded = item.node.open;
256
+ item.node.open = visible && item.expanded;
257
+ }
258
+ item.node.hidden = !visible;
259
+ }
260
+ updateThemes();
261
+ }
262
+ function requestProviders() {
263
+ if (active !== 'providers' || providerRequested || typeof instance.callbacks.onProvidersOpen !== 'function') return;
264
+ providerRequested = true;
265
+ const failed = error => {
266
+ providerRequested = false;
267
+ if (status && !destroyed) {
268
+ status.textContent = error?.message || t('settingsWorkbenchProviderOpenFailed');
269
+ status.dataset.status = 'failed';
270
+ }
271
+ };
272
+ try { Promise.resolve(instance.callbacks.onProvidersOpen()).catch(failed); }
273
+ catch (error) { failed(error); }
274
+ }
275
+ function revealProviders() {
276
+ active = 'providers';
277
+ filter = 'all';
278
+ providerRequested = true;
279
+ pages.get('providers').dataset.providerEmbedded = 'true';
280
+ panel.dataset.view = 'settings';
281
+ refresh();
282
+ return providerHost;
283
+ }
284
+ function requestClose() {
285
+ if (closing) return closing;
286
+ closing = (async () => {
287
+ if (providerCloseGuard && !await providerCloseGuard()) return;
288
+ if (!destroyed) instance.callbacks.onBack?.();
289
+ })().catch(error => {
290
+ if (status && !destroyed) {
291
+ status.textContent = error?.message || t('settingsWorkbenchProviderOpenFailed');
292
+ status.dataset.status = 'failed';
293
+ }
294
+ }).finally(() => { closing = null; });
295
+ return closing;
296
+ }
297
+ function select(id) {
298
+ active = id;
299
+ if (panel.dataset.view === 'skills') instance.callbacks.onSkillsBack?.();
300
+ refresh();
301
+ body.scrollTop = 0;
302
+ if (dialog.open) requestProviders();
303
+ }
304
+ function show() {
305
+ if (destroyed) return;
306
+ refresh();
307
+ if (!dialog.open) {
308
+ returnFocus = doc.activeElement;
309
+ dialog.showModal();
310
+ panel.dataset.settingsWorkbenchOpen = 'true';
311
+ navButtons.get(active)?.focus();
312
+ }
313
+ requestProviders();
314
+ }
315
+ function hide() {
316
+ providerRequested = false;
317
+ if (!dialog.open) return;
318
+ if (dialog.contains(doc.activeElement)) doc.activeElement?.blur?.();
319
+ dialog.close();
320
+ delete panel.dataset.settingsWorkbenchOpen;
321
+ if (returnFocus?.isConnected) returnFocus.focus?.();
322
+ }
323
+ const syncView = () => {
324
+ refresh();
325
+ if (['settings', 'skills'].includes(panel.dataset.view)) show();
326
+ else hide();
327
+ };
328
+ listen(allFilter, 'click', () => { filter = 'all'; refresh(); });
329
+ listen(projectFilter, 'click', () => {
330
+ filter = 'project';
331
+ if (panel.dataset.view === 'skills') instance.callbacks.onSkillsBack?.();
332
+ refresh();
333
+ body.scrollTop = 0;
334
+ });
335
+ listen(nav, 'keydown', event => {
336
+ if (!['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) return;
337
+ const tabs = Array.from(navButtons.values()).filter(tab => !tab.hidden);
338
+ const index = tabs.indexOf(event.target);
339
+ if (index < 0) return;
340
+ event.preventDefault(); event.stopPropagation();
341
+ const next = event.key === 'Home' ? 0 : event.key === 'End' ? tabs.length - 1
342
+ : (index + (event.key === 'ArrowUp' ? -1 : 1) + tabs.length) % tabs.length;
343
+ tabs[next].click(); tabs[next].focus();
344
+ });
345
+ listen(closeButton, 'click', event => {
346
+ if (!providerCloseGuard) return;
347
+ event.preventDefault(); event.stopImmediatePropagation();
348
+ void requestClose();
349
+ }, true);
350
+ listen(dialog, 'cancel', event => {
351
+ // File-input cancel events bubble; only this dialog's own cancel closes it.
352
+ if (event.target !== dialog) return;
353
+ event.preventDefault(); event.stopPropagation();
354
+ void requestClose();
355
+ });
356
+ listen(dialog, 'change', refresh);
357
+ const observer = new win.MutationObserver(syncView);
358
+ observer.observe(panel, { attributes: true, attributeFilter: ['data-view', 'data-settings-scope', 'data-theme'] });
359
+ refresh();
360
+ return {
361
+ show, hide, refresh, revealProviders,
362
+ setProviderCloseGuard(guard) { providerCloseGuard = guard; },
363
+ destroy() {
364
+ destroyed = true;
365
+ observer.disconnect();
366
+ listeners.splice(0).forEach(dispose => dispose());
367
+ hide();
368
+ dialog.remove();
369
+ delete panel.dataset.settingsWorkbench;
370
+ }
371
+ };
372
+ }
373
+ return { mount };
374
+ });
@@ -0,0 +1,72 @@
1
+ (function (root, factory) {
2
+ if (typeof module === 'object' && module.exports) module.exports = factory();
3
+ else root.CodexOverleafModuleRegistry.define('SharedSessionViewSync', [], factory);
4
+ })(typeof globalThis !== 'undefined' ? globalThis : this, function () {
5
+ 'use strict';
6
+
7
+ function install(options) {
8
+ const { Bridge, StorageDb, getScope, getState, isBusy, apply, notice } = options;
9
+ let saving = 0, version = 0, pending = false, timer = null, refreshing = false, stopped = false;
10
+ const sameScope = (a, b) => a.accountScopeId === b.accountScopeId
11
+ && a.projectId === b.projectId && a.generation === b.generation;
12
+ const signature = state => JSON.stringify([state.activeSessionId,
13
+ (state.sessions || []).map(session => [session.id, session.updatedAt, session.task])]);
14
+ function schedule(delay = 250) {
15
+ if (stopped || timer || !pending) return;
16
+ timer = setTimeout(() => { timer = null; void refresh(); }, delay);
17
+ }
18
+ async function refresh() {
19
+ if (refreshing || stopped || !pending) return;
20
+ const scope = getScope();
21
+ if (!scope.projectId || !scope.accountScopeId) { pending = false; return; }
22
+ if (saving || isBusy()) { schedule(1000); return; }
23
+ const local = getState();
24
+ // A draft or a not-yet-persisted edit always takes priority over passive
25
+ // history refresh. It remains on screen until the user saves/sends it.
26
+ if (local.task || (local.sessions || []).some(session => StorageDb.hasUnpersistedSharedSession(session))) {
27
+ schedule(1500); return;
28
+ }
29
+ const capturedVersion = version, capturedSignature = signature(local);
30
+ pending = false; refreshing = true;
31
+ try {
32
+ const records = await StorageDb.readSharedProjectSnapshot(scope.projectId);
33
+ if (!sameScope(scope, getScope())) return;
34
+ if (saving || isBusy() || version !== capturedVersion || signature(getState()) !== capturedSignature) {
35
+ pending = true; return;
36
+ }
37
+ const ids = new Set(records.map(record => record.id));
38
+ const newLocal = (local.sessions || []).filter(session =>
39
+ !ids.has(session.id) && !StorageDb.wasSharedSessionStored(session.id));
40
+ // The data has now been adopted by this view; future writes may use it
41
+ // as a merge baseline. Snapshot reads alone never advance the baseline.
42
+ StorageDb.adoptSharedSessionBaseline(records);
43
+ apply([...records, ...newLocal]);
44
+ } catch (error) {
45
+ notice?.(error);
46
+ } finally {
47
+ refreshing = false;
48
+ schedule(1000);
49
+ }
50
+ }
51
+ const unsubscribe = Bridge.subscribe(change => {
52
+ const scope = getScope();
53
+ if (!change.projectId || change.projectId === scope.projectId) {
54
+ pending = true; schedule();
55
+ }
56
+ });
57
+ return {
58
+ beginSave() {
59
+ saving += 1; version += 1;
60
+ let ended = false;
61
+ return () => {
62
+ if (ended) return;
63
+ ended = true; saving -= 1; version += 1; schedule();
64
+ };
65
+ },
66
+ dispose() {
67
+ stopped = true; clearTimeout(timer); unsubscribe();
68
+ }
69
+ };
70
+ }
71
+ return { install };
72
+ });
@@ -0,0 +1,195 @@
1
+ (function initSubagentActivityView(root, factory) {
2
+ root.CodexOverleafModuleRegistry.define('SubagentActivityView', ['SubagentActivityModel', 'RunActivityModel'], factory);
3
+ })(typeof globalThis !== 'undefined' ? globalThis : window, function subagentActivityViewFactory(Agents, Activity) {
4
+ 'use strict';
5
+ function create(deps) {
6
+ const { tx, getPanel, plain, make, icon, formatElapsed, renderBlocks } = deps;
7
+ let viewer = null;
8
+ function statusLabel(status) {
9
+ return ({ pending: tx('Starting', '启动中'), running: tx('Running', '运行中'),
10
+ completed: tx('Completed', '已完成'), failed: tx('Failed', '失败'),
11
+ cancelled: tx('Stopped', '已停止'), unknown: tx('Status unconfirmed', '状态未确认') })[status] || '';
12
+ }
13
+ function latest(agent) {
14
+ const blocks = Activity.project({ status: agent.status, events: agent.events || [] }).blocks;
15
+ const last = blocks.at(-1);
16
+ const item = last?.kind === 'exploreGroup' ? last.items.at(-1) : last;
17
+ return plain(item?.meta?.target || item?.meta?.command || item?.event?.title || agent.task).slice(0, 180);
18
+ }
19
+ function elapsed(agent, run) {
20
+ const duration = Agents.elapsedMs(agent, run, Date.now());
21
+ return duration === null ? '' : formatElapsed(duration);
22
+ }
23
+ function close() {
24
+ if (!viewer) return;
25
+ const previous = viewer; viewer = null;
26
+ previous.shell.remove();
27
+ for (const [node, inert] of previous.inert) if (node.isConnected) node.inert = inert;
28
+ if (previous.log?.isConnected) previous.log.scrollTop = previous.parentScroll;
29
+ if (previous.trigger?.isConnected) previous.trigger.focus({ preventScroll: true });
30
+ }
31
+ function open(card, key, trigger) {
32
+ const agent = card.run.subagents?.find(item => item.key === key);
33
+ const panel = getPanel();
34
+ if (!agent || !panel) return;
35
+ if (viewer?.card.id === card.id) {
36
+ viewer.scrolls.set(viewer.key, viewer.body.scrollTop);
37
+ viewer.key = key; viewer.rows.clear(); viewer.events.replaceChildren(); renderViewer(card); return;
38
+ }
39
+ close();
40
+ const shell = make('section', 'codex-subagent-view');
41
+ shell.setAttribute('role', 'region');
42
+ shell.setAttribute('aria-label', tx('Subagent conversation', '子代理对话'));
43
+ const header = make('header', 'codex-subagent-view-head');
44
+ const back = make('button', 'codex-subagent-back');
45
+ back.type = 'button'; back.textContent = tx('Back to main task', '返回主任务');
46
+ back.addEventListener('click', close);
47
+ const readonly = make('span', 'codex-subagent-readonly'); readonly.textContent = tx('Read only', '只读');
48
+ header.append(back, readonly);
49
+ const parent = make('div', 'codex-subagent-parent');
50
+ const parentLabel = make('span', 'codex-subagent-parent-label');
51
+ const parentCount = make('span', 'codex-subagent-parent-count');
52
+ parent.append(parentLabel, parentCount);
53
+ const siblings = make('nav', 'codex-subagent-siblings'); siblings.setAttribute('aria-label', tx('Subagents', '子代理'));
54
+ const body = make('div', 'codex-subagent-body');
55
+ const title = make('h3', 'codex-subagent-title');
56
+ const meta = make('div', 'codex-subagent-meta');
57
+ const assignment = make('details', 'codex-subagent-assignment');
58
+ const assignmentLabel = make('summary', ''); assignmentLabel.textContent = tx('Assigned task', '派遣任务');
59
+ const prompt = make('p', ''); assignment.append(assignmentLabel, prompt);
60
+ const events = make('div', 'run-workflow-list');
61
+ events.dataset.expanded = 'true';
62
+ const empty = make('p', 'codex-subagent-empty');
63
+ const limit = make('p', 'codex-subagent-history-note');
64
+ const bottom = make('button', 'codex-subagent-latest'); bottom.type = 'button';
65
+ bottom.textContent = tx('Latest activity', '最新活动'); bottom.hidden = true;
66
+ bottom.addEventListener('click', () => { body.scrollTop = body.scrollHeight; });
67
+ body.append(title, meta, assignment, events, empty, limit);
68
+ const footer = make('footer', 'codex-subagent-footer');
69
+ footer.textContent = tx('Continue the conversation in the main task.', '后续对话在主任务中继续。');
70
+ shell.append(header, parent, siblings, body, bottom, footer);
71
+ const log = panel.querySelector('[data-log]');
72
+ const inert = Array.from(panel.children).map(node => [node, node.inert]);
73
+ for (const [node] of inert) node.inert = true;
74
+ panel.append(shell);
75
+ viewer = { shell, card, key, trigger, log, parentScroll: log?.scrollTop || 0, inert,
76
+ title, meta, assignment, prompt, parentLabel, parentCount, siblings, body, events, empty, limit, bottom,
77
+ rows: new Map(), siblingRows: new Map(), scrolls: new Map(), renderedKey: '' };
78
+ body.addEventListener('scroll', () => {
79
+ if (viewer?.shell === shell) bottom.hidden = body.scrollHeight - body.scrollTop - body.clientHeight < 70;
80
+ }, { passive: true });
81
+ shell.addEventListener('keydown', event => { if (event.key === 'Escape') { event.stopPropagation(); close(); } });
82
+ renderViewer(card); back.focus({ preventScroll: true });
83
+ }
84
+ function mount(card) {
85
+ const el = make('section', 'run-subagents');
86
+ const heading = make('div', 'run-subagents-heading');
87
+ const label = make('span', ''); label.textContent = tx('Subagents', '子代理');
88
+ const count = make('span', 'run-subagents-count'); count.setAttribute('aria-live', 'polite');
89
+ heading.append(icon('agent'), label, count);
90
+ const rows = make('div', 'run-subagents-rows'); el.append(heading, rows);
91
+ card.events.before(el);
92
+ card.subagentGroup = { el, count, rows, cache: new Map() };
93
+ }
94
+ function update(card) {
95
+ if (!card.subagentGroup) mount(card);
96
+ const agents = card.run.subagents || [], group = card.subagentGroup;
97
+ group.el.hidden = agents.length === 0;
98
+ const running = agents.filter(agent => ['pending', 'running'].includes(Agents.effectiveStatus(agent, card.run))).length;
99
+ const completed = agents.filter(agent => Agents.effectiveStatus(agent, card.run) === 'completed').length;
100
+ const failed = agents.filter(agent => Agents.effectiveStatus(agent, card.run) === 'failed').length;
101
+ group.count.textContent = [
102
+ running ? tx(running + ' active', running + ' 进行中') : '',
103
+ completed ? tx(completed + ' completed', completed + ' 已完成') : '',
104
+ failed ? tx(failed + ' failed', failed + ' 失败') : ''
105
+ ].filter(Boolean).join(' · ') || tx(agents.length + ' recorded', agents.length + ' 项记录');
106
+ const keep = new Set();
107
+ for (const agent of agents) {
108
+ keep.add(agent.key);
109
+ let row = group.cache.get(agent.key);
110
+ if (!row) {
111
+ const el = make('button', 'run-subagent-row'); el.type = 'button';
112
+ const mark = icon('agent'), copy = make('span', 'run-subagent-copy');
113
+ const name = make('span', 'run-subagent-name'), activity = make('span', 'run-subagent-activity');
114
+ copy.append(name, activity);
115
+ const tail = make('span', 'run-subagent-tail'), status = make('span', ''), time = make('span', 'run-subagent-time');
116
+ tail.append(status, time);
117
+ el.append(mark, copy, tail);
118
+ el.addEventListener('click', () => open(card, agent.key, el));
119
+ row = { el, name, activity, status, time }; group.cache.set(agent.key, row); group.rows.append(el);
120
+ }
121
+ const status = Agents.effectiveStatus(agent, card.run);
122
+ row.el.dataset.state = status;
123
+ row.name.textContent = plain(agent.title || agent.jobId || agent.threadId);
124
+ row.activity.textContent = latest(agent) || statusLabel(status);
125
+ row.activity.title = row.activity.textContent;
126
+ row.status.textContent = statusLabel(status); row.time.textContent = elapsed(agent, card.run);
127
+ row.el.setAttribute('aria-label', row.name.textContent + ', ' + statusLabel(status) + ', ' + tx('Open conversation', '查看子对话'));
128
+ }
129
+ for (const [key, row] of group.cache) if (!keep.has(key)) { row.el.remove(); group.cache.delete(key); }
130
+ if (viewer?.card.id === card.id) renderViewer(card);
131
+ }
132
+ function renderViewer(card) {
133
+ try {
134
+ renderViewerContent(card);
135
+ if (viewer) viewer.renderError = false;
136
+ } catch (error) {
137
+ // A read-only child view must not interrupt the parent event or settlement path.
138
+ if (!viewer) return;
139
+ if (!viewer.renderError) console.warn('[codex-overleaf] Child conversation render failed:', plain(error?.message));
140
+ viewer.renderError = true;
141
+ viewer.rows.clear(); viewer.events.replaceChildren();
142
+ viewer.empty.hidden = false;
143
+ viewer.empty.textContent = tx('Unable to display this subagent conversation. Return to the main task and reopen it.',
144
+ '暂时无法显示子代理对话,请返回主任务后重新打开。');
145
+ }
146
+ }
147
+ function renderViewerContent(card) {
148
+ if (!viewer || !viewer.shell.isConnected) { if (viewer) close(); return; }
149
+ const agent = card.run.subagents?.find(item => item.key === viewer.key);
150
+ if (!agent) { close(); return; }
151
+ viewer.card = card;
152
+ const switched = viewer.renderedKey !== agent.key;
153
+ const follow = !switched && viewer.body.scrollHeight - viewer.body.scrollTop - viewer.body.clientHeight < 70;
154
+ const childStatus = Agents.effectiveStatus(agent, card.run);
155
+ viewer.title.textContent = plain(agent.title || agent.jobId || agent.threadId);
156
+ viewer.meta.textContent = [statusLabel(childStatus), elapsed(agent, card.run), agent.model, agent.reasoningEffort].filter(Boolean).join(' · ');
157
+ viewer.prompt.textContent = plain(agent.task);
158
+ viewer.assignment.hidden = !viewer.prompt.textContent;
159
+ const parent = Activity.project(card.run), last = parent.blocks.at(-1);
160
+ const lastItem = last?.kind === 'exploreGroup' ? last.items.at(-1) : last;
161
+ const parentWork = plain(lastItem?.meta?.target || lastItem?.meta?.command || lastItem?.event?.title).slice(0, 150);
162
+ viewer.parentLabel.textContent = tx('Main agent · ', '主 agent · ') + (card.run.status === 'running'
163
+ ? parentWork || tx('Working', '处理中') : tx('Run ended', '本轮已结束'));
164
+ const running = (card.run.subagents || []).filter(item => ['pending', 'running'].includes(Agents.effectiveStatus(item, card.run))).length;
165
+ viewer.parentCount.textContent = tx(running + ' subagents active', running + ' 个子任务进行中');
166
+ for (const sibling of card.run.subagents || []) {
167
+ let button = viewer.siblingRows.get(sibling.key);
168
+ if (!button) {
169
+ button = make('button', 'codex-subagent-sibling'); button.type = 'button';
170
+ button.addEventListener('click', () => open(viewer.card, sibling.key, viewer.trigger));
171
+ viewer.siblingRows.set(sibling.key, button); viewer.siblings.append(button);
172
+ }
173
+ button.textContent = plain(sibling.title || sibling.jobId || sibling.threadId);
174
+ button.setAttribute('aria-pressed', String(sibling.key === agent.key));
175
+ button.title = statusLabel(Agents.effectiveStatus(sibling, card.run));
176
+ }
177
+ const childRun = { id: card.id + ':' + agent.key, status: ['pending', 'running'].includes(childStatus) ? 'running' : childStatus,
178
+ events: agent.events || [], mode: 'ask' };
179
+ const result = Activity.project(childRun);
180
+ const childCard = { id: childRun.id, projection: result };
181
+ renderBlocks(viewer.events, result.blocks, viewer.rows, childCard, childRun);
182
+ viewer.empty.hidden = result.blocks.length > 0;
183
+ viewer.empty.textContent = agent.historyUnavailable
184
+ ? tx('This runtime could not read the child history. Recorded updates remain available.', '当前运行端无法读取子会话历史,已记录的活动仍会保留。')
185
+ : tx('Waiting for recorded activity from this subagent.', '等待该子代理的活动记录。');
186
+ viewer.limit.hidden = !agent.clipped;
187
+ viewer.limit.textContent = tx('Older details were trimmed to keep history bounded.', '较早的详细记录已按历史容量上限裁剪。');
188
+ if (switched) viewer.body.scrollTop = viewer.scrolls.get(agent.key) || 0;
189
+ else if (follow) viewer.body.scrollTop = viewer.body.scrollHeight;
190
+ viewer.renderedKey = agent.key;
191
+ }
192
+ return { update, close, isOpen: () => Boolean(viewer?.shell.isConnected) };
193
+ }
194
+ return { create };
195
+ });