codex-overleaf-link 2.4.0 → 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 (327) hide show
  1. package/README.md +272 -311
  2. package/README.zh-CN.md +287 -326
  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 +572 -571
  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 +8974 -1781
  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 +51 -120
  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 +364 -356
  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 +194 -164
  42. package/extension/src/content/scopedPersistenceCoordinator.js +2 -1
  43. package/extension/src/content/scopedPersistencePanelState.js +45 -2
  44. package/extension/src/content/selectionContextView.js +300 -0
  45. package/extension/src/content/sessionPersistence.js +10 -2
  46. package/extension/src/content/settingsPanel.js +93 -54
  47. package/extension/src/content/settingsWorkbench.js +374 -0
  48. package/extension/src/content/sharedSessionViewSync.js +72 -0
  49. package/extension/src/content/subagentActivityView.js +195 -0
  50. package/extension/src/content/trackedChangeCaptureController.js +7 -3
  51. package/extension/src/content/updateNotice.js +121 -50
  52. package/extension/src/content/writebackController.js +257 -0
  53. package/extension/src/content/writebackOrchestrator.js +146 -141
  54. package/extension/src/content/writebackPlan.js +231 -0
  55. package/extension/src/content/writebackRecovery.js +122 -0
  56. package/extension/src/content/writingStyleSettings.js +576 -0
  57. package/extension/src/content/writtenChangesView.js +152 -0
  58. package/extension/src/page/binaryAssetUploader.js +97 -19
  59. package/extension/src/page/overleafProjectSnapshot.js +1 -0
  60. package/extension/src/page/referenceProjects.js +148 -0
  61. package/extension/src/page/saveState.js +58 -3
  62. package/extension/src/page/snapshotRouter.js +44 -13
  63. package/extension/src/page/textCoordinates.js +102 -0
  64. package/extension/src/page/textFileCreator.js +350 -59
  65. package/extension/src/page/trackedChangeCapture.js +42 -56
  66. package/extension/src/page/trackedChangeOwnership.js +198 -0
  67. package/extension/src/page/trackedChangeReplay.js +164 -0
  68. package/extension/src/page/trackedChangesLifecycle.js +139 -150
  69. package/extension/src/page/treeOperations.js +36 -29
  70. package/extension/src/page/writebackReceiptJournal.js +112 -0
  71. package/extension/src/page/writebackRouter.js +176 -136
  72. package/extension/src/pageBridge.js +59 -101
  73. package/extension/src/popup.js +203 -59
  74. package/extension/src/shared/agentTranscript.js +18 -4
  75. package/extension/src/shared/auditRecords.js +71 -0
  76. package/extension/src/shared/changeHistoryModel.js +94 -0
  77. package/extension/src/shared/compatibility.js +1 -1
  78. package/extension/src/shared/compileAdapter.js +42 -0
  79. package/extension/src/shared/failureReasons.js +20 -0
  80. package/extension/src/shared/globalPreferences.js +1 -1
  81. package/extension/src/shared/i18n.js +187 -65
  82. package/extension/src/shared/managedUpdateProjection.js +6 -3
  83. package/extension/src/shared/pageRpcContract.js +7 -1
  84. package/extension/src/shared/providerProfiles.js +109 -0
  85. package/extension/src/shared/runActivityModel.js +361 -0
  86. package/extension/src/shared/runExecutionSnapshot.js +8 -2
  87. package/extension/src/shared/runExecutionSnapshotCodec.js +16 -4
  88. package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
  89. package/extension/src/shared/selectionContext.js +28 -0
  90. package/extension/src/shared/sessionState.js +97 -6
  91. package/extension/src/shared/sharedSessionBridge.js +288 -0
  92. package/extension/src/shared/storageDb.js +23 -55
  93. package/extension/src/shared/storageMigration.js +3 -0
  94. package/extension/src/shared/storageRunActions.js +54 -4
  95. package/extension/src/shared/storageValuePruning.js +40 -0
  96. package/extension/src/shared/subagentActivityModel.js +174 -0
  97. package/extension/src/shared/undoOperations.js +87 -0
  98. package/extension/src/shared/updateConsent.js +37 -8
  99. package/extension/src/shared/writebackIntent.js +62 -0
  100. package/extension/src/shared/writebackSettlement.js +29 -10
  101. package/extension/src/shared/writingStyle.js +33 -0
  102. package/extension/styles/panel.css +2136 -744
  103. package/extension/styles/popup.css +110 -0
  104. package/native-host/src/anthropicBridgeRequest.js +2 -1
  105. package/native-host/src/codexModelRecovery.js +107 -0
  106. package/native-host/src/codexPromptAssembly.js +2 -0
  107. package/native-host/src/codexProviderLaunch.js +3 -3
  108. package/native-host/src/codexRuntimeIdentity.js +1 -0
  109. package/native-host/src/codexSessionRunner.js +146 -177
  110. package/native-host/src/codexSessionTiming.js +71 -0
  111. package/native-host/src/managedInstall.js +5 -4
  112. package/native-host/src/nativeEnvironment.js +70 -0
  113. package/native-host/src/nativeQuotas.js +15 -8
  114. package/native-host/src/overleafWorkspaceRules.js +16 -0
  115. package/native-host/src/processStopBarrier.js +80 -0
  116. package/native-host/src/providerModelCatalog.js +4 -3
  117. package/native-host/src/providerProfile.js +13 -1
  118. package/native-host/src/providerReasoning.js +9 -5
  119. package/native-host/src/providerStore.js +4 -0
  120. package/native-host/src/readProgressGuard.js +84 -17
  121. package/native-host/src/releaseTransport.js +14 -5
  122. package/native-host/src/selectionScope.js +58 -0
  123. package/native-host/src/skills/parallel-subagents/SKILL.md +31 -3
  124. package/native-host/src/skills/writing-style-builder/SKILL.md +146 -0
  125. package/native-host/src/subagentBroker.js +102 -98
  126. package/native-host/src/subagentTelemetry.js +316 -0
  127. package/native-host/src/subagentWorkspace.js +103 -0
  128. package/native-host/src/subagentWorkspacePath.js +31 -0
  129. package/native-host/src/taskRunnerRuntime.js +55 -5
  130. package/native-host/src/turnAttachments.js +113 -0
  131. package/native-host/src/updateManager.js +122 -12
  132. package/native-host/src/updateNetworkControl.js +75 -0
  133. package/native-host/src/updateTrust.js +21 -2
  134. package/native-host/src/vendor/pdfjs/LICENSE +177 -0
  135. package/native-host/src/vendor/pdfjs/SOURCE.txt +3 -0
  136. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  137. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  138. package/native-host/src/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
  139. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  140. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  141. package/native-host/src/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
  142. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  143. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  144. package/native-host/src/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  145. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  146. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  147. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  148. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  149. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  150. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  151. package/native-host/src/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
  152. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  153. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  154. package/native-host/src/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
  155. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  156. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  157. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  158. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  159. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  160. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  161. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  162. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  163. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  164. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  165. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  166. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  167. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  168. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  169. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  170. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  171. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  172. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  173. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  174. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  175. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  176. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  177. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  178. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  179. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  180. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  181. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  182. package/native-host/src/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
  183. package/native-host/src/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
  184. package/native-host/src/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  185. package/native-host/src/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  186. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  187. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  188. package/native-host/src/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  189. package/native-host/src/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  190. package/native-host/src/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  191. package/native-host/src/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  192. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  193. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  194. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  195. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  196. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  197. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  198. package/native-host/src/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
  199. package/native-host/src/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
  200. package/native-host/src/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
  201. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  202. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  203. package/native-host/src/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
  204. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  205. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  206. package/native-host/src/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
  207. package/native-host/src/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
  208. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  209. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  210. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  211. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  212. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  213. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  214. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  215. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  216. package/native-host/src/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
  217. package/native-host/src/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
  218. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  219. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  220. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  221. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  222. package/native-host/src/vendor/pdfjs/cmaps/H.bcmap +0 -0
  223. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  224. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  225. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  226. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  227. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  228. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  229. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  230. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  231. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  232. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  233. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  234. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  235. package/native-host/src/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
  236. package/native-host/src/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
  237. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  238. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  239. package/native-host/src/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
  240. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  241. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  242. package/native-host/src/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
  243. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  244. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  245. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  246. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  247. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  248. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  249. package/native-host/src/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
  250. package/native-host/src/vendor/pdfjs/cmaps/LICENSE +36 -0
  251. package/native-host/src/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
  252. package/native-host/src/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
  253. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  254. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  255. package/native-host/src/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
  256. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  257. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  258. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  259. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  260. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  261. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  262. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  263. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  264. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  265. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  266. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  267. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  268. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  269. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  270. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  271. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  272. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  273. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  274. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  275. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  276. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  277. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  278. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  279. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  280. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  281. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  282. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  283. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  284. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  285. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  286. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  287. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  288. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  289. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  290. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  291. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  292. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  293. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  294. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  295. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  296. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  297. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  298. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  299. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  300. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  301. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  302. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  303. package/native-host/src/vendor/pdfjs/cmaps/V.bcmap +0 -0
  304. package/native-host/src/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  305. package/native-host/src/vendor/pdfjs/pdf.mjs +26740 -0
  306. package/native-host/src/vendor/pdfjs/pdf.worker.mjs +62201 -0
  307. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  308. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  309. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  310. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  311. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  312. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  313. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  314. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  315. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  316. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  317. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  318. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
  319. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  320. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  321. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  322. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  323. package/native-host/src/writingStyleEvidence.js +102 -0
  324. package/native-host/src/writingStylePdfWorker.js +35 -0
  325. package/native-host/src/writingStyleProfile.js +165 -0
  326. package/native-host/src/writingStyleRuntime.js +447 -0
  327. package/package.json +1 -1
@@ -1,8 +1,9 @@
1
1
  (function (root, factory) {
2
- const api = factory();
2
+ const api = factory(typeof module === 'object' && module.exports
3
+ ? require('./trackedChangeOwnership') : root.CodexOverleafTrackedChangeOwnership);
3
4
  if (typeof module === 'object' && module.exports) module.exports = api;
4
5
  if (root) root.CodexOverleafTrackedChangeCapture = api;
5
- })(typeof window !== 'undefined' ? window : globalThis, function () {
6
+ })(typeof window !== 'undefined' ? window : globalThis, function (Ownership) {
6
7
  'use strict';
7
8
 
8
9
  function create(deps = {}) {
@@ -125,11 +126,22 @@
125
126
  reason: snapshot.ready ? (snapshot.refs.length ? 'native_untracked_undo_pending_changes' : '')
126
127
  : snapshot.reason || 'native_review_unavailable' };
127
128
  }
129
+ const mergedPrefix = 'native-merge:';
130
+ const nativeKey = tuple => 'native:' + JSON.stringify(tuple);
131
+ const ledgerKeys = refs => refs.map(ref => ref.key).sort();
132
+ const { mergedInsertionScope, prepareMergedInsertionReview, nativeOwned, rangesFor, shiftedBaseline, scopeCovered } = Ownership.create({
133
+ fingerprint, readActiveEditorText, mergedPrefix, nativeKey, ledgerKeys
134
+ });
135
+
136
+
137
+
128
138
  function prepareTrackedChangeReview(path, refs = []) {
129
139
  const snapshot = readNativeSnapshot(path);
130
140
  const blocked = reason => ({ ...snapshot, ok: false, reason });
131
141
  if (!snapshot.ready) return blocked(snapshot.reason || 'native_review_unavailable');
132
142
  const targets = refs.filter(ref => ref.path === path), ids = new Set(targets.map(ref => ref.id));
143
+ if (targets.some(ref => ref.key?.startsWith(mergedPrefix)))
144
+ return prepareMergedInsertionReview(path, targets, snapshot);
133
145
  let expected;
134
146
  try {
135
147
  expected = targets.map(ref => {
@@ -150,19 +162,6 @@
150
162
  return { ...snapshot, ok: true, targets, ids: [...ids],
151
163
  unrelated: snapshot.refs.filter(ref => !ids.has(ref.id)) };
152
164
  }
153
- function nativeOwned(ref, capture) {
154
- if (ref.source !== 'native' || !Number.isSafeInteger(ref.from) || !Number.isSafeInteger(ref.to)) return false;
155
- if (ref.kind === 'delete') return capture.ranges.some(range => ref.from >= range.start && ref.from <= range.end
156
- && ref.textLength === range.removedLength && ref.textHash === range.removedHash && range.removedLength > 0);
157
- let covered = ref.from;
158
- for (const range of capture.ranges) {
159
- if (range.end < covered) continue;
160
- if (range.start > covered) break;
161
- covered = Math.max(covered, range.end);
162
- if (covered >= ref.to) return ref.to > ref.from;
163
- }
164
- return false;
165
- }
166
165
  const identity = ref => (ref.path || '') + '\0' + ref.key;
167
166
  function diff(before, after) {
168
167
  const seen = new Set(before.map(identity));
@@ -173,34 +172,6 @@
173
172
  return true;
174
173
  });
175
174
  }
176
- function rangesFor(operation, beforeContent, postContent) {
177
- const patches = Array.isArray(operation.patches) && operation.patches.length
178
- ? operation.patches
179
- : [{ from: 0, to: beforeContent.length, insert: postContent }];
180
- let delta = 0;
181
- return patches.map(patch => {
182
- const range = { from: patch.from, to: patch.to,
183
- start: patch.from + delta, end: patch.from + delta + String(patch.insert ?? '').length,
184
- removedLength: patch.to - patch.from, removedHash: fingerprint(beforeContent.slice(patch.from, patch.to)) };
185
- delta += String(patch.insert ?? '').length - (patch.to - patch.from);
186
- return range;
187
- });
188
- }
189
- function shiftedBaseline(before, ranges) {
190
- let overlap = false;
191
- const refs = before.map(ref => {
192
- const match = /^pos:(\d+):/.exec(ref.key);
193
- if (!match) return ref;
194
- const pos = Number(match[1]);
195
- let delta = 0;
196
- for (const range of ranges) {
197
- if (pos >= range.from && pos < range.to) overlap = true;
198
- if (pos >= range.to) delta += (range.end - range.start) - (range.to - range.from);
199
- }
200
- return { ...ref, key: ref.key.replace(/^pos:\d+:/, 'pos:' + (pos + delta) + ':') };
201
- });
202
- return { refs, overlap };
203
- }
204
175
  function allowedRef(ref, capture) {
205
176
  if (ref.path !== capture.path) return false;
206
177
  if (capture.source === 'native') return nativeOwned(ref, capture);
@@ -212,16 +183,6 @@
212
183
  // insufficient to assign a new task ownership after a delayed capture.
213
184
  return Boolean(ref.id);
214
185
  }
215
- function scopeCovered(refs, capture) {
216
- if (capture.source === 'native') return capture.ranges.every(range => refs.some(ref =>
217
- ref.from <= range.end && ref.to >= range.start));
218
- const positioned = refs.filter(ref => /^pos:\d+:/.test(ref.key));
219
- if (refs.some(ref => ref.id)) return true;
220
- return capture.ranges.every(range => positioned.some(ref => {
221
- const pos = Number(/^pos:(\d+):/.exec(ref.key)[1]);
222
- return pos >= range.start && pos <= range.end;
223
- }));
224
- }
225
186
  async function waitForTrackedChangeDiff(before, paths, options = {}) {
226
187
  const waitMs = Math.max(0, Number(options.waitMs ?? 5000));
227
188
  const intervalMs = Math.max(1, Number(options.intervalMs ?? 180));
@@ -244,9 +205,15 @@
244
205
  if (options.capture && !allowedRef(ref, options.capture)) { filtered++; continue; }
245
206
  found.set(identity(ref), ref);
246
207
  }
208
+ const merged = native && lastSnapshotReady
209
+ ? mergedInsertionScope(options.capture, after, readActiveEditorText()) : null;
210
+ if (merged) { found.clear(); found.set(identity(merged.ref), merged.ref); }
247
211
  const nextSignature = after.map(ref => native ? ref.key : identity(ref)).sort().join('\n');
248
212
  if (nextSignature !== signature) { signature = nextSignature; lastChange = now(); }
249
213
  if (options.stopOnFirst && found.size) { reason = 'observed'; break; }
214
+ if (options.capture && now() - start >= 5000 && lastSnapshotReady && found.size
215
+ && now() - lastChange >= stableMs && scopeCovered(Array.from(found.values()), options.capture)
216
+ && afterCount < limit) { reason = 'observed'; break; }
250
217
  if (now() >= deadline) break;
251
218
  await delay(Math.min(intervalMs, deadline - now()));
252
219
  }
@@ -263,7 +230,7 @@
263
230
  source: options.capture?.source || 'dom', sourceReason }
264
231
  };
265
232
  }
266
- async function captureTrackedWrite({ trackedBefore, captureBaseline, operation, beforeContent, postContent, runProjectId }) {
233
+ async function captureTrackedWrite({ trackedBefore, captureBaseline, operation, beforeContent, postContent, runProjectId, waitMs = 5000 }) {
267
234
  if (beforeContent === postContent) return { trackedChanges: [], capture: null };
268
235
  const ranges = rangesFor(operation, beforeContent, postContent);
269
236
  const baseline = shiftedBaseline(trackedBefore, ranges);
@@ -284,7 +251,7 @@
284
251
  capture.reason = baseline.overlap ? 'preexisting_change_overlap' : 'capture_baseline_limit';
285
252
  return { trackedChanges: [], capture };
286
253
  }
287
- return observe(capture, postContent, 5000);
254
+ return observe(capture, postContent, Math.min(35000, Math.max(5000, Number(waitMs) || 5000)));
288
255
  }
289
256
  function validCapture(capture) {
290
257
  return capture?.version === 1 && typeof capture.path === 'string'
@@ -333,7 +300,26 @@
333
300
  if (params.capture?.runProjectId !== params.runProjectId) {
334
301
  return { ok: false, code: 'capture_project_mismatch', trackedChanges: [] };
335
302
  }
336
- return observe(params.capture, params.expectedContent, 1200);
303
+ const capture = params.capture;
304
+ // An expired polling window does not erase a provable, unchanged scope.
305
+ // Recovery is read-only and must reconstruct the complete old/new ledger.
306
+ if (validCapture(capture) && capture.source === 'native'
307
+ && (now() >= capture.expiresAt || capture.state === 'needs_review')) {
308
+ const active = getActiveFilePath() === capture.path
309
+ && readActiveEditorText() === params.expectedContent
310
+ && (!deps.getProjectId || deps.getProjectId() === params.runProjectId);
311
+ const snapshot = active ? readNativeSnapshot(capture.path, capture.nativeDocId) : null;
312
+ const merged = snapshot?.ready && snapshot.acceptByIdSupported
313
+ ? mergedInsertionScope(capture, snapshot.refs, params.expectedContent) : null;
314
+ if (merged) return { ok: true, trackedChanges: [merged.ref], capture: {
315
+ ...capture, refs: [merged.ref], state: 'observed', reason: 'observed',
316
+ diagnostics: { ...capture.diagnostics, capturedCount: 1,
317
+ sourceReason: 'native_merged_insertion_recovered' }
318
+ } };
319
+ return { ok: false, trackedChanges: [], capture: { ...capture,
320
+ state: 'needs_review', reason: 'capture_merged_scope_unavailable' } };
321
+ }
322
+ return observe(capture, params.expectedContent, 1200);
337
323
  }
338
324
  return { collectTrackedChangeNodes, trackedChangeRefFromNode, collectTrackedChangeRefsForPaths,
339
325
  waitForTrackedChangeDiff, prepareTrackedChangeCapture, prepareTrackedChangeReview, prepareUntrackedUndo, getTrackedChangeCaptureStatus, captureTrackedWrite, reconcileTrackedChangeCapture };
@@ -0,0 +1,198 @@
1
+ (function (root, factory) {
2
+ const api = factory();
3
+ if (typeof module === 'object' && module.exports) module.exports = api;
4
+ if (root) root.CodexOverleafTrackedChangeOwnership = api;
5
+ })(typeof window !== 'undefined' ? window : globalThis, function () {
6
+ 'use strict';
7
+
8
+ function create({ fingerprint, readActiveEditorText, mergedPrefix, nativeKey, ledgerKeys }) {
9
+ function parseNativeRef(ref) {
10
+ try {
11
+ if (!ref?.key?.startsWith('native:') || ref.key.length > 1024) return null;
12
+ const tuple = JSON.parse(ref.key.slice(7));
13
+ if (!Array.isArray(tuple) || tuple.length !== 5 || tuple[0] !== ref.id
14
+ || typeof tuple[0] !== 'string' || !tuple[0] || tuple[0].length > 256
15
+ || !['insert', 'delete'].includes(tuple[1])
16
+ || !Number.isSafeInteger(tuple[2]) || !Number.isSafeInteger(tuple[3])
17
+ || tuple[2] < 0 || tuple[3] < tuple[2]
18
+ || (tuple[1] === 'delete' && tuple[2] !== tuple[3])
19
+ || (tuple[1] === 'insert' && tuple[2] === tuple[3])
20
+ || typeof tuple[4] !== 'string' || !/^\d+:[0-9a-f]+:[0-9a-f]+$/.test(tuple[4])) return null;
21
+ return tuple;
22
+ } catch (_error) { return null; }
23
+ }
24
+
25
+ // An existing ID can grow when a later insertion touches an older change.
26
+ // Prove the entire ledger as old fragments + this run's inserted slices.
27
+ // Never assign ownership of the whole merged ID.
28
+ function mergedInsertionScope(capture, after, postContent) {
29
+ if (capture?.source !== 'native' || !capture.nativeDocId || !capture.runProjectId
30
+ || typeof postContent !== 'string' || fingerprint(postContent) !== capture.expected
31
+ || !Array.isArray(capture.before) || !capture.before.length || capture.before.length > 128
32
+ || !Array.isArray(after) || !after.length || after.length > 128
33
+ || !Array.isArray(capture.ranges) || !capture.ranges.length || capture.ranges.length > 64) return null;
34
+ const ranges = capture.ranges;
35
+ let delta = 0, previousFrom = -1;
36
+ for (const range of ranges) {
37
+ if (!Number.isSafeInteger(range.from) || range.from <= previousFrom || range.to !== range.from
38
+ || range.removedLength !== 0 || !Number.isSafeInteger(range.start) || !Number.isSafeInteger(range.end)
39
+ || range.start !== range.from + delta || range.end <= range.start || range.end > postContent.length) return null;
40
+ delta += range.end - range.start;
41
+ previousFrom = range.from;
42
+ }
43
+ let preContent = postContent;
44
+ for (const range of ranges.slice().reverse()) {
45
+ preContent = preContent.slice(0, range.start) + preContent.slice(range.end);
46
+ }
47
+ const before = capture.before.map(parseNativeRef);
48
+ if (before.some(tuple => !tuple)) return null;
49
+ const beforeKeys = before.map(nativeKey).sort();
50
+ if (new Set(beforeKeys).size !== beforeKeys.length) return null;
51
+ const preservedKeys = [];
52
+ for (const tuple of before) {
53
+ const [id, kind, from, to, hash] = tuple;
54
+ if (to > preContent.length
55
+ || (kind === 'insert' && fingerprint(preContent.slice(from, to)) !== hash)) return null;
56
+ // Interior edits and deletion-boundary ambiguity need a different proof.
57
+ if (ranges.some(range => kind === 'insert'
58
+ ? range.from > from && range.from < to : range.from === from)) return null;
59
+ const startShift = ranges.filter(range => range.from <= from)
60
+ .reduce((sum, range) => sum + range.end - range.start, 0);
61
+ const endShift = kind === 'delete' ? startShift : ranges.filter(range => range.from < to)
62
+ .reduce((sum, range) => sum + range.end - range.start, 0);
63
+ preservedKeys.push(nativeKey([id, kind, from + startShift, to + endShift, hash]));
64
+ }
65
+ preservedKeys.sort();
66
+ const oldIds = new Set(before.map(tuple => tuple[0]));
67
+ const mergedIds = new Set(), residue = [], claims = ranges.map(() => []);
68
+ for (const ref of after) {
69
+ const tuple = parseNativeRef(ref);
70
+ if (!tuple || ref.path !== capture.path) return null;
71
+ const [id, kind, from, to, hash] = tuple;
72
+ if (kind === 'delete') { residue.push(nativeKey(tuple)); continue; }
73
+ if (to > postContent.length || fingerprint(postContent.slice(from, to)) !== hash) return null;
74
+ let pieces = [[from, to]];
75
+ ranges.forEach((range, index) => {
76
+ const start = Math.max(from, range.start), end = Math.min(to, range.end);
77
+ if (start >= end) return;
78
+ claims[index].push([start, end]);
79
+ if (oldIds.has(id)) mergedIds.add(id);
80
+ pieces = pieces.flatMap(([left, right]) => {
81
+ if (range.end <= left || range.start >= right) return [[left, right]];
82
+ const remaining = [];
83
+ if (left < range.start) remaining.push([left, range.start]);
84
+ if (range.end < right) remaining.push([range.end, right]);
85
+ return remaining;
86
+ });
87
+ });
88
+ for (const [left, right] of pieces) {
89
+ residue.push(nativeKey([id, kind, left, right, fingerprint(postContent.slice(left, right))]));
90
+ }
91
+ }
92
+ if (!mergedIds.size || JSON.stringify(residue.sort()) !== JSON.stringify(preservedKeys)) return null;
93
+ for (let index = 0; index < ranges.length; index++) {
94
+ let cursor = ranges[index].start;
95
+ for (const [start, end] of claims[index].sort((a, b) => a[0] - b[0])) {
96
+ if (start !== cursor) return null;
97
+ cursor = end;
98
+ }
99
+ if (cursor !== ranges[index].end) return null;
100
+ }
101
+ const proof = [1, capture.runProjectId, capture.nativeDocId, fingerprint(preContent),
102
+ capture.expected, beforeKeys, ranges.map(range => [range.from, range.start, range.end]),
103
+ fingerprint(JSON.stringify(ledgerKeys(after)))];
104
+ const key = mergedPrefix + JSON.stringify(proof);
105
+ if (key.length > 32768) return null;
106
+ return {
107
+ ref: { key, id: [...mergedIds].sort()[0], path: capture.path,
108
+ label: 'This run: insertion merged with an earlier tracked change' },
109
+ runProjectId: capture.runProjectId, beforeKeys, preservedKeys, ranges, preContent, postContent
110
+ };
111
+ }
112
+
113
+ function prepareMergedInsertionReview(path, targets, snapshot) {
114
+ const blocked = reason => ({ ...snapshot, ok: false, reason });
115
+ if (targets.length !== 1 || !snapshot.acceptByIdSupported) return blocked('native_merged_review_unsupported');
116
+ const target = targets[0];
117
+ try {
118
+ if (target.key.length > 32768) return blocked('native_merged_review_invalid');
119
+ const proof = JSON.parse(target.key.slice(mergedPrefix.length));
120
+ if (!Array.isArray(proof) || proof.length !== 8 || proof[0] !== 1
121
+ || proof[2] !== snapshot.nativeDocId || !Array.isArray(proof[5]) || proof[5].length > 128
122
+ || !Array.isArray(proof[6]) || proof[6].length > 64) return blocked('native_merged_review_invalid');
123
+ const before = proof[5].map(key => {
124
+ const tuple = JSON.parse(key.slice(7));
125
+ return { key, id: tuple[0], path };
126
+ });
127
+ const ranges = proof[6].map(([from, start, end]) => ({
128
+ from, to: from, start, end, removedLength: 0
129
+ }));
130
+ const merged = mergedInsertionScope({ source: 'native', path, runProjectId: proof[1],
131
+ nativeDocId: proof[2], expected: proof[4], before, ranges }, snapshot.refs, readActiveEditorText());
132
+ if (!merged || merged.ref.key !== target.key || merged.ref.id !== target.id)
133
+ return blocked('native_merged_review_scope_changed');
134
+ return { ...snapshot, ok: true, targets, ids: [], unrelated: snapshot.refs, merged };
135
+ } catch (_error) { return blocked('native_merged_review_invalid'); }
136
+ }
137
+
138
+ function nativeOwned(ref, capture) {
139
+ if (ref.source !== 'native' || !Number.isSafeInteger(ref.from) || !Number.isSafeInteger(ref.to)) return false;
140
+ if (ref.kind === 'delete') return capture.ranges.some(range => ref.from >= range.start && ref.from <= range.end
141
+ && ref.textLength === range.removedLength && ref.textHash === range.removedHash && range.removedLength > 0);
142
+ let covered = ref.from;
143
+ for (const range of capture.ranges) {
144
+ if (range.end < covered) continue;
145
+ if (range.start > covered) break;
146
+ covered = Math.max(covered, range.end);
147
+ if (covered >= ref.to) return ref.to > ref.from;
148
+ }
149
+ return false;
150
+ }
151
+
152
+ function rangesFor(operation, beforeContent, postContent) {
153
+ const patches = Array.isArray(operation.patches) && operation.patches.length
154
+ ? operation.patches
155
+ : [{ from: 0, to: beforeContent.length, insert: postContent }];
156
+ let delta = 0;
157
+ return patches.map(patch => {
158
+ const range = { from: patch.from, to: patch.to,
159
+ start: patch.from + delta, end: patch.from + delta + String(patch.insert ?? '').length,
160
+ removedLength: patch.to - patch.from, removedHash: fingerprint(beforeContent.slice(patch.from, patch.to)) };
161
+ delta += String(patch.insert ?? '').length - (patch.to - patch.from);
162
+ return range;
163
+ });
164
+ }
165
+
166
+ function shiftedBaseline(before, ranges) {
167
+ let overlap = false;
168
+ const refs = before.map(ref => {
169
+ const match = /^pos:(\d+):/.exec(ref.key);
170
+ if (!match) return ref;
171
+ const pos = Number(match[1]);
172
+ let delta = 0;
173
+ for (const range of ranges) {
174
+ if (pos >= range.from && pos < range.to) overlap = true;
175
+ if (pos >= range.to) delta += (range.end - range.start) - (range.to - range.from);
176
+ }
177
+ return { ...ref, key: ref.key.replace(/^pos:\d+:/, 'pos:' + (pos + delta) + ':') };
178
+ });
179
+ return { refs, overlap };
180
+ }
181
+
182
+ function scopeCovered(refs, capture) {
183
+ if (refs.length === 1 && refs[0].key?.startsWith(mergedPrefix)) return true;
184
+ if (capture.source === 'native') return capture.ranges.every(range => refs.some(ref =>
185
+ ref.from <= range.end && ref.to >= range.start));
186
+ const positioned = refs.filter(ref => /^pos:\d+:/.test(ref.key));
187
+ if (refs.some(ref => ref.id)) return true;
188
+ return capture.ranges.every(range => positioned.some(ref => {
189
+ const pos = Number(/^pos:(\d+):/.exec(ref.key)[1]);
190
+ return pos >= range.start && pos <= range.end;
191
+ }));
192
+ }
193
+
194
+ return { mergedInsertionScope, prepareMergedInsertionReview, nativeOwned, rangesFor, shiftedBaseline, scopeCovered };
195
+ }
196
+
197
+ return { create };
198
+ });
@@ -0,0 +1,164 @@
1
+ (function (root, factory) {
2
+ const api = factory();
3
+ if (typeof module === 'object' && module.exports) module.exports = api;
4
+ if (root) root.CodexOverleafTrackedChangeReplay = api;
5
+ })(typeof window !== 'undefined' ? window : globalThis, function () {
6
+ 'use strict';
7
+
8
+ function create({ normalizeSafeProjectPath, applyTextPatches }) {
9
+ // Builds the minimal replay operations for Accept All. The replay must write
10
+ // only the changed fragments, never a whole-file replaceAll.
11
+ //
12
+ // Preferred source: the run's own original forward writeback operations
13
+ // (carrying their `patches`). After the editor-undo the document is back at
14
+ // the pre-write content, so those patches' `expected` slices match and
15
+ // re-apply cleanly.
16
+ //
17
+ // Fallback: when a path has no usable original patch operation, compute a
18
+ // minimal pre->post diff (trim the common prefix/suffix to a single targeted
19
+ // {from,to,insert} patch).
20
+ function buildAcceptReplayOperations(paths, expectedByPath, postByPath, appliedOperations) {
21
+ const patchesByPath = collectAppliedEditPatchesByPath(appliedOperations);
22
+ const operations = [];
23
+ for (const path of paths) {
24
+ const preContent = expectedByPath.get(path);
25
+ const postContent = postByPath.get(path);
26
+ if (typeof preContent !== 'string' || typeof postContent !== 'string') {
27
+ return {
28
+ ok: false,
29
+ code: 'accept_missing_run_content',
30
+ reason: `${path} 缺少写入前/写入后内容;Codex 没有重放本轮改动。`
31
+ };
32
+ }
33
+
34
+ // Preferred: re-apply the run's original forward patches verbatim.
35
+ const originalPatches = patchesByPath.get(path);
36
+ if (originalPatches && originalPatches.length && patchesApplyCleanly(preContent, originalPatches)) {
37
+ operations.push({
38
+ type: 'edit',
39
+ path,
40
+ patches: originalPatches,
41
+ reason: 'Accept tracked edit (replay untracked)'
42
+ });
43
+ continue;
44
+ }
45
+
46
+ // Fallback: minimal pre->post diff trimmed to a single targeted patch.
47
+ const diffPatch = buildMinimalDiffPatch(preContent, postContent);
48
+ if (!diffPatch) {
49
+ // pre === post: nothing to replay for this file.
50
+ continue;
51
+ }
52
+ operations.push({
53
+ type: 'edit',
54
+ path,
55
+ patches: [diffPatch],
56
+ reason: 'Accept tracked edit (replay untracked)'
57
+ });
58
+ }
59
+ return { ok: true, operations };
60
+ }
61
+
62
+ // Collects the per-path `patches` arrays from the run's applied edit
63
+ // operations. Only edit operations that actually carried `patches` are
64
+ // usable; whole-file replaceAll / verifiedContent operations are skipped so
65
+ // the replay never falls back to a whole-file write.
66
+ function collectAppliedEditPatchesByPath(appliedOperations) {
67
+ const patchesByPath = new Map();
68
+ for (const rawOperation of Array.isArray(appliedOperations) ? appliedOperations : []) {
69
+ if (!rawOperation || rawOperation.type !== 'edit') {
70
+ continue;
71
+ }
72
+ const path = typeof rawOperation.path === 'string'
73
+ ? normalizeSafeProjectPath(rawOperation.path)
74
+ : '';
75
+ if (!path || !Array.isArray(rawOperation.patches) || !rawOperation.patches.length) {
76
+ continue;
77
+ }
78
+ const normalized = rawOperation.patches.map(patch => ({
79
+ from: Number(patch?.from),
80
+ to: Number(patch?.to),
81
+ expected: String(patch?.expected ?? ''),
82
+ insert: String(patch?.insert ?? '')
83
+ }));
84
+ const existing = patchesByPath.get(path) || [];
85
+ patchesByPath.set(path, existing.concat(normalized));
86
+ }
87
+ return patchesByPath;
88
+ }
89
+
90
+ // Confirms a patch set re-applies cleanly against the given (pre-write) text:
91
+ // every patch range is valid and its `expected` slice matches.
92
+ function patchesApplyCleanly(text, patches) {
93
+ const applied = applyTextPatches(text, patches);
94
+ return applied.ok === true;
95
+ }
96
+
97
+ // Computes a single targeted {from,to,insert} patch describing the pre->post
98
+ // change by trimming the common prefix and suffix. Returns null when the two
99
+ // strings are identical.
100
+ function buildMinimalDiffPatch(preContent, postContent) {
101
+ if (preContent === postContent) {
102
+ return null;
103
+ }
104
+ const preLen = preContent.length;
105
+ const postLen = postContent.length;
106
+ let prefix = 0;
107
+ const maxPrefix = Math.min(preLen, postLen);
108
+ while (prefix < maxPrefix && preContent[prefix] === postContent[prefix]) {
109
+ prefix += 1;
110
+ }
111
+ let suffix = 0;
112
+ const maxSuffix = Math.min(preLen, postLen) - prefix;
113
+ while (
114
+ suffix < maxSuffix
115
+ && preContent[preLen - 1 - suffix] === postContent[postLen - 1 - suffix]
116
+ ) {
117
+ suffix += 1;
118
+ }
119
+ const from = prefix;
120
+ const to = preLen - suffix;
121
+ return {
122
+ from,
123
+ to,
124
+ expected: preContent.slice(from, to),
125
+ insert: postContent.slice(from, postLen - suffix)
126
+ };
127
+ }
128
+
129
+ function rebaseCheckpointPair(actualContent, expectedContent, postContent) {
130
+ const actual = String(actualContent ?? '');
131
+ const expected = String(expectedContent ?? '');
132
+ const post = String(postContent ?? '');
133
+ if (actual === post) {
134
+ return {
135
+ ok: true,
136
+ expectedContent: expected,
137
+ postContent: post,
138
+ prefixLength: 0,
139
+ suffixLength: 0
140
+ };
141
+ }
142
+ if (!post) {
143
+ return { ok: false };
144
+ }
145
+ const matchIndex = actual.indexOf(post);
146
+ if (matchIndex < 0 || actual.indexOf(post, matchIndex + 1) >= 0) {
147
+ return { ok: false };
148
+ }
149
+ const prefix = actual.slice(0, matchIndex);
150
+ const suffix = actual.slice(matchIndex + post.length);
151
+ return {
152
+ ok: true,
153
+ expectedContent: prefix + expected + suffix,
154
+ postContent: actual,
155
+ prefixLength: prefix.length,
156
+ suffixLength: suffix.length
157
+ };
158
+ }
159
+
160
+ return { buildAcceptReplayOperations, rebaseCheckpointPair };
161
+ }
162
+
163
+ return { create };
164
+ });