codex-overleaf-link 2.4.1 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. package/README.md +275 -305
  2. package/README.zh-CN.md +290 -320
  3. package/extension/bootstrap/background.js +99 -19
  4. package/extension/bootstrap/manifest.template.json +9 -4
  5. package/extension/bootstrap/popup.html +11 -16
  6. package/extension/bootstrap/popupFallback.js +55 -0
  7. package/extension/bootstrap/update.js +25 -2
  8. package/extension/bootstrap/updateStatus.js +1 -0
  9. package/extension/runtime-manifest.json +3 -1
  10. package/extension/src/background.js +234 -56
  11. package/extension/src/backgroundBootstrapMigration.js +181 -0
  12. package/extension/src/backgroundSharedSessions.js +440 -0
  13. package/extension/src/backgroundUpdateCoordinator.js +541 -381
  14. package/extension/src/backgroundUpdateSafety.js +173 -0
  15. package/extension/src/content/activeTurnControl.js +16 -2
  16. package/extension/src/content/applyResultFormatters.js +46 -73
  17. package/extension/src/content/assetTransferBroker.js +244 -12
  18. package/extension/src/content/changeHistoryView.js +175 -0
  19. package/extension/src/content/composerAttachments.js +117 -67
  20. package/extension/src/content/composerPanel.js +41 -8
  21. package/extension/src/content/contentRuntime.js +1084 -1099
  22. package/extension/src/content/diagnosticsController.js +122 -97
  23. package/extension/src/content/diagnosticsExport.js +236 -0
  24. package/extension/src/content/diagnosticsPanel.js +78 -19
  25. package/extension/src/content/diffReviewPanel.js +8 -5
  26. package/extension/src/content/directoryCleanupRecovery.js +54 -0
  27. package/extension/src/content/generated/content.bundle.js +14680 -3606
  28. package/extension/src/content/generated/content.bundle.meta.json +30 -3
  29. package/extension/src/content/globalPreferencesController.js +1 -1
  30. package/extension/src/content/legacyGlobalRegistry.js +25 -1
  31. package/extension/src/content/localSkillsPanel.js +141 -16
  32. package/extension/src/content/markdownDomRenderer.js +9 -4
  33. package/extension/src/content/markdownText.js +5 -6
  34. package/extension/src/content/modelPicker.js +8 -5
  35. package/extension/src/content/nativeCompatibilityController.js +45 -20
  36. package/extension/src/content/otWarmMirror.js +4 -5
  37. package/extension/src/content/otWarmMirrorController.js +17 -20
  38. package/extension/src/content/pageBridgeClient.js +33 -5
  39. package/extension/src/content/panelMaintenance.js +87 -132
  40. package/extension/src/content/panelRenderer.js +10 -0
  41. package/extension/src/content/pendingInputView.js +109 -76
  42. package/extension/src/content/projectProviderSelection.js +13 -4
  43. package/extension/src/content/projectSessionCleanup.js +109 -62
  44. package/extension/src/content/projectSettingsCoordinator.js +39 -2
  45. package/extension/src/content/providerSettingsCoordinator.js +63 -14
  46. package/extension/src/content/providerSettingsDialog.js +724 -113
  47. package/extension/src/content/recentProjects.js +21 -6
  48. package/extension/src/content/runActivitySummary.js +665 -0
  49. package/extension/src/content/runCompletionMeta.js +344 -0
  50. package/extension/src/content/runController.js +40 -15
  51. package/extension/src/content/runFailureNotice.js +34 -12
  52. package/extension/src/content/runGuidanceController.js +76 -30
  53. package/extension/src/content/runGuidanceView.js +59 -10
  54. package/extension/src/content/runPresence.js +306 -0
  55. package/extension/src/content/runQueueScheduler.js +150 -43
  56. package/extension/src/content/runRecoveryActions.js +146 -0
  57. package/extension/src/content/runResultActions.js +11 -8
  58. package/extension/src/content/runReviewController.js +574 -0
  59. package/extension/src/content/runScrollLayout.js +21 -2
  60. package/extension/src/content/runTimelineView.js +315 -290
  61. package/extension/src/content/scopedPersistencePanelState.js +51 -6
  62. package/extension/src/content/selectionContextView.js +300 -0
  63. package/extension/src/content/sensitivePreflight.js +140 -0
  64. package/extension/src/content/sessionForkController.js +80 -17
  65. package/extension/src/content/sessionManager.js +1 -1
  66. package/extension/src/content/sessionPersistence.js +6 -1
  67. package/extension/src/content/settingsPanel.js +84 -55
  68. package/extension/src/content/settingsWorkbench.js +379 -0
  69. package/extension/src/content/sharedSessionViewSync.js +109 -0
  70. package/extension/src/content/subagentActivityView.js +195 -0
  71. package/extension/src/content/trackedChangeCaptureController.js +7 -3
  72. package/extension/src/content/updateIdle.js +4 -1
  73. package/extension/src/content/updateNotice.js +179 -56
  74. package/extension/src/content/updateSafetyReceiver.js +58 -0
  75. package/extension/src/content/writebackController.js +308 -2
  76. package/extension/src/content/writebackOrchestrator.js +213 -199
  77. package/extension/src/content/writebackPlan.js +231 -0
  78. package/extension/src/content/writebackRecovery.js +122 -0
  79. package/extension/src/content/writingStyleSettings.js +600 -0
  80. package/extension/src/content/writtenChangesView.js +152 -0
  81. package/extension/src/page/binaryAssetUploader.js +223 -23
  82. package/extension/src/page/fileMover.js +256 -0
  83. package/extension/src/page/overleafProjectSnapshot.js +1 -0
  84. package/extension/src/page/ownedDirectoryCleanup.js +94 -0
  85. package/extension/src/page/referenceProjects.js +149 -0
  86. package/extension/src/page/reviewContext.js +113 -0
  87. package/extension/src/page/saveState.js +20 -6
  88. package/extension/src/page/snapshotRouter.js +124 -48
  89. package/extension/src/page/textCoordinates.js +102 -0
  90. package/extension/src/page/textFileCreator.js +442 -71
  91. package/extension/src/page/trackedChangeCapture.js +53 -57
  92. package/extension/src/page/trackedChangeOwnership.js +216 -0
  93. package/extension/src/page/trackedChangeReplay.js +184 -0
  94. package/extension/src/page/trackedChangesLifecycle.js +343 -339
  95. package/extension/src/page/treeOperations.js +33 -12
  96. package/extension/src/page/updateSafetyProbe.js +41 -0
  97. package/extension/src/page/writebackReceiptJournal.js +114 -0
  98. package/extension/src/page/writebackRouter.js +242 -201
  99. package/extension/src/pageBridge.js +73 -102
  100. package/extension/src/popup.js +261 -65
  101. package/extension/src/shared/agentTranscript.js +41 -4
  102. package/extension/src/shared/auditRecords.js +73 -0
  103. package/extension/src/shared/changeHistoryModel.js +94 -0
  104. package/extension/src/shared/compatibility.js +22 -6
  105. package/extension/src/shared/compileAdapter.js +101 -37
  106. package/extension/src/shared/composerAttachmentDraft.js +151 -0
  107. package/extension/src/shared/directoryCleanupProof.js +43 -0
  108. package/extension/src/shared/failureReasons.js +329 -3
  109. package/extension/src/shared/globalPreferences.js +31 -14
  110. package/extension/src/shared/governanceRules.js +4 -37
  111. package/extension/src/shared/i18n.js +389 -25
  112. package/extension/src/shared/managedUpdateProjection.js +8 -5
  113. package/extension/src/shared/nativeRequestIdentity.js +1 -0
  114. package/extension/src/shared/pageRpcContract.js +9 -2
  115. package/extension/src/shared/projectFiles.js +21 -44
  116. package/extension/src/shared/providerProfiles.js +114 -3
  117. package/extension/src/shared/runActivityModel.js +361 -0
  118. package/extension/src/shared/runExecutionSnapshot.js +8 -2
  119. package/extension/src/shared/runExecutionSnapshotCodec.js +16 -4
  120. package/extension/src/shared/runInputQueue.js +48 -5
  121. package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
  122. package/extension/src/shared/selectionContext.js +37 -0
  123. package/extension/src/shared/sessionState.js +166 -30
  124. package/extension/src/shared/settlementFacts.js +10 -2
  125. package/extension/src/shared/sharedSessionBridge.js +311 -0
  126. package/extension/src/shared/sharedSessionTransfer.js +140 -0
  127. package/extension/src/shared/staleGuard.js +118 -13
  128. package/extension/src/shared/storageDb.js +77 -78
  129. package/extension/src/shared/storageMigration.js +74 -111
  130. package/extension/src/shared/storageRunActions.js +211 -22
  131. package/extension/src/shared/storageValuePruning.js +40 -0
  132. package/extension/src/shared/subagentActivityModel.js +174 -0
  133. package/extension/src/shared/undoOperations.js +216 -6
  134. package/extension/src/shared/updateConsent.js +42 -11
  135. package/extension/src/shared/updateRuntimeIdentity.js +1 -1
  136. package/extension/src/shared/writebackIntent.js +78 -0
  137. package/extension/src/shared/writebackOperationEvidence.js +4 -15
  138. package/extension/src/shared/writebackSettlement.js +67 -48
  139. package/extension/src/shared/writingStyle.js +33 -0
  140. package/extension/styles/panel.css +1987 -385
  141. package/extension/styles/popup.css +110 -0
  142. package/native-host/src/anthropicBridgeRequest.js +6 -3
  143. package/native-host/src/anthropicBridgeResponse.js +6 -2
  144. package/native-host/src/anthropicMessagesBridge.js +24 -16
  145. package/native-host/src/bootstrapMigration.js +296 -0
  146. package/native-host/src/bootstrapMigrationContract.js +101 -0
  147. package/native-host/src/bootstrapUpdate.js +233 -0
  148. package/native-host/src/bootstrapUpdateWatchdog.js +44 -0
  149. package/native-host/src/chatBridgeResponse.js +10 -0
  150. package/native-host/src/chatCompletionsBridge.js +21 -15
  151. package/native-host/src/codexConfigPaths.js +106 -0
  152. package/native-host/src/codexHome.js +66 -73
  153. package/native-host/src/codexHomeScope.js +124 -0
  154. package/native-host/src/codexInheritedAuth.js +90 -0
  155. package/native-host/src/codexLocalSkills.js +301 -0
  156. package/native-host/src/codexModelRecovery.js +107 -0
  157. package/native-host/src/codexPromptAssembly.js +33 -12
  158. package/native-host/src/codexProviderLaunch.js +3 -3
  159. package/native-host/src/codexProviderTest.js +24 -26
  160. package/native-host/src/codexRuntimeIdentity.js +1 -0
  161. package/native-host/src/codexSessionRunner.js +211 -318
  162. package/native-host/src/codexSessionTiming.js +21 -8
  163. package/native-host/src/codexSkillIsolation.js +170 -0
  164. package/native-host/src/codexThreadFork.js +19 -3
  165. package/native-host/src/index.js +19 -7
  166. package/native-host/src/managedInstall.js +115 -39
  167. package/native-host/src/managedInstallRecovery.js +140 -0
  168. package/native-host/src/managedRuntimeEvidence.js +57 -0
  169. package/native-host/src/mirrorWorkspace.js +92 -22
  170. package/native-host/src/nativeDoctor.js +15 -0
  171. package/native-host/src/nativeEnvironment.js +70 -0
  172. package/native-host/src/nativeHelperLifecycle.js +21 -0
  173. package/native-host/src/nativeHostRegistration.js +33 -0
  174. package/native-host/src/nativeQuotas.js +15 -8
  175. package/native-host/src/nativeRunLifecycle.js +71 -0
  176. package/native-host/src/overleafWorkspaceRules.js +16 -0
  177. package/native-host/src/processStopBarrier.js +115 -0
  178. package/native-host/src/projectPathPlatform.js +30 -0
  179. package/native-host/src/providerHttp.js +80 -0
  180. package/native-host/src/providerModelCatalog.js +4 -3
  181. package/native-host/src/providerProfile.js +17 -3
  182. package/native-host/src/providerReasoning.js +10 -11
  183. package/native-host/src/providerRuntime.js +1 -0
  184. package/native-host/src/providerStore.js +76 -14
  185. package/native-host/src/releaseTransport.js +14 -5
  186. package/native-host/src/responsesPassthroughBridge.js +266 -52
  187. package/native-host/src/runtimeInstaller.js +21 -1
  188. package/native-host/src/selectionScope.js +86 -0
  189. package/native-host/src/skills/parallel-subagents/SKILL.md +31 -3
  190. package/native-host/src/skills/writing-style-builder/SKILL.md +146 -0
  191. package/native-host/src/subagentAdmission.js +26 -0
  192. package/native-host/src/subagentBroker.js +176 -159
  193. package/native-host/src/subagentTelemetry.js +325 -0
  194. package/native-host/src/subagentWorkspace.js +103 -0
  195. package/native-host/src/subagentWorkspacePath.js +34 -0
  196. package/native-host/src/taskRunnerRuntime.js +130 -57
  197. package/native-host/src/tomlStatements.js +140 -0
  198. package/native-host/src/turnAttachments.js +113 -0
  199. package/native-host/src/updateManager.js +406 -38
  200. package/native-host/src/updateNetworkControl.js +75 -0
  201. package/native-host/src/updateTrust.js +21 -2
  202. package/native-host/src/vendor/pdfjs/LICENSE +177 -0
  203. package/native-host/src/vendor/pdfjs/SOURCE.txt +3 -0
  204. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  205. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  206. package/native-host/src/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
  207. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  208. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  209. package/native-host/src/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
  210. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  211. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  212. package/native-host/src/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  213. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  214. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  215. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  216. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  217. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  218. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  219. package/native-host/src/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
  220. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  221. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  222. package/native-host/src/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
  223. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  224. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  225. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  226. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  227. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  228. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  229. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  230. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  231. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  232. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  233. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  234. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  235. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  236. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  237. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  238. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  239. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  240. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  241. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  242. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  243. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  244. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  245. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  246. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  247. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  248. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  249. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  250. package/native-host/src/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
  251. package/native-host/src/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
  252. package/native-host/src/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  253. package/native-host/src/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  254. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  255. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  256. package/native-host/src/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  257. package/native-host/src/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  258. package/native-host/src/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  259. package/native-host/src/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  260. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  261. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  262. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  263. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  264. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  265. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  266. package/native-host/src/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
  267. package/native-host/src/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
  268. package/native-host/src/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
  269. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  270. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  271. package/native-host/src/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
  272. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  273. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  274. package/native-host/src/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
  275. package/native-host/src/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
  276. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  277. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  278. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  279. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  280. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  281. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  282. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  283. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  284. package/native-host/src/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
  285. package/native-host/src/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
  286. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  287. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  288. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  289. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  290. package/native-host/src/vendor/pdfjs/cmaps/H.bcmap +0 -0
  291. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  292. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  293. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  294. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  295. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  296. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  297. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  298. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  299. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  300. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  301. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  302. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  303. package/native-host/src/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
  304. package/native-host/src/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
  305. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  306. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  307. package/native-host/src/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
  308. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  309. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  310. package/native-host/src/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
  311. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  312. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  313. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  314. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  315. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  316. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  317. package/native-host/src/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
  318. package/native-host/src/vendor/pdfjs/cmaps/LICENSE +36 -0
  319. package/native-host/src/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
  320. package/native-host/src/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
  321. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  322. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  323. package/native-host/src/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
  324. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  325. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  326. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  327. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  328. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  329. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  330. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  331. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  332. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  333. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  334. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  335. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  336. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  337. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  338. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  339. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  340. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  341. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  342. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  343. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  344. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  345. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  346. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  347. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  348. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  349. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  350. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  351. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  352. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  353. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  354. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  355. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  356. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  357. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  358. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  359. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  360. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  361. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  362. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  363. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  364. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  365. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  366. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  367. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  368. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  369. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  370. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  371. package/native-host/src/vendor/pdfjs/cmaps/V.bcmap +0 -0
  372. package/native-host/src/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  373. package/native-host/src/vendor/pdfjs/pdf.mjs +26740 -0
  374. package/native-host/src/vendor/pdfjs/pdf.worker.mjs +62201 -0
  375. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  376. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  377. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  378. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  379. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  380. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  381. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  382. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  383. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  384. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  385. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  386. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
  387. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  388. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  389. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  390. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  391. package/native-host/src/writingStyleEvidence.js +102 -0
  392. package/native-host/src/writingStylePdfWorker.js +35 -0
  393. package/native-host/src/writingStyleProfile.js +165 -0
  394. package/native-host/src/writingStyleRuntime.js +475 -0
  395. package/native-host/src/writingStyleStore.js +73 -0
  396. package/package.json +1 -1
  397. package/scripts/install-managed.mjs +1 -0
@@ -1,14 +1,16 @@
1
1
  (function initStorageRunActions(root, factory) {
2
2
  if (typeof module === 'object' && module.exports) {
3
- module.exports = factory();
3
+ module.exports = factory(require('./selectionContext'), require('./writebackIntent'), require('./writingStyle'), require('./directoryCleanupProof'));
4
4
  } else {
5
- root.CodexOverleafStorageRunActions = factory();
5
+ root.CodexOverleafModuleRegistry.define('StorageRunActions', ['SelectionContext', 'WritebackIntent', 'WritingStyle', 'DirectoryCleanupProof'], factory);
6
6
  }
7
- })(typeof globalThis !== 'undefined' ? globalThis : window, function storageRunActionsFactory() {
7
+ })(typeof globalThis !== 'undefined' ? globalThis : window, function storageRunActionsFactory(SelectionContext, WritebackIntent, WritingStyle, DirectoryCleanupProof) {
8
8
  'use strict';
9
9
 
10
- var MAX_PERSISTED_ACTION_RUNS_PER_SESSION = 2;
11
- var MAX_PERSISTED_ACTION_BYTES_PER_RUN = 320 * 1024;
10
+ // Share a bounded budget across the retained history, rather than expiring
11
+ // otherwise valid recovery data after two edits. The session builder also
12
+ // reserves room for display metadata within the shared transport limit.
13
+ var MAX_PERSISTED_ACTION_BYTES_PER_SESSION = 16 * 1024 * 1024;
12
14
 
13
15
  function compactRunsForStorage(runs, options, maxRuns, compactRun) {
14
16
  if (typeof compactRun !== 'function') {
@@ -17,22 +19,100 @@
17
19
  var selectedRuns = (Array.isArray(runs) ? runs : [])
18
20
  .filter(function (run) { return run && typeof run.id === 'string'; })
19
21
  .slice(-Math.max(0, Number(maxRuns) || 0));
20
- var actionRunIds = new Set();
22
+ var payloads = new Map();
23
+ var remaining = Math.min(MAX_PERSISTED_ACTION_BYTES_PER_SESSION,
24
+ Number.isFinite(options?.maxActionPayloadBytes) ? Math.max(0, options.maxActionPayloadBytes) : Infinity);
25
+ var usedBytes = 0, usedChars = 0;
26
+ var fits = (bytes, chars) => bytes <= remaining && (typeof options?.canRetainActionPayload !== 'function'
27
+ || options.canRetainActionPayload(usedBytes + bytes, usedChars + chars));
21
28
  if (options && options.preserveRunActionPayload === true) {
22
- for (var index = selectedRuns.length - 1;
23
- index >= 0 && actionRunIds.size < MAX_PERSISTED_ACTION_RUNS_PER_SESSION;
24
- index -= 1) {
25
- if (hasReloadableRunActionPayload(selectedRuns[index])) {
26
- actionRunIds.add(selectedRuns[index].id);
29
+ for (var index = selectedRuns.length - 1; index >= 0; index -= 1) {
30
+ var run = selectedRuns[index];
31
+ if (!hasReloadableRunActionPayload(withoutDirectoryFacts(run))) continue;
32
+ var payload = compactRunActionPayload(run, true, { includeCaptures: false, includeDirectoryCleanup: false });
33
+ if (payload.recoveryRetention?.state === 'omitted') { payloads.set(run.id, payload); continue; }
34
+ var serialized = JSON.stringify(payload);
35
+ var bytes = getUtf8ByteLength(serialized);
36
+ if (!fits(bytes, serialized.length)) {
37
+ payloads.set(run.id, { ...emptyActionPayload(), recoveryRetention: omitted('session-budget', bytes) });
38
+ continue;
39
+ }
40
+ remaining -= bytes;
41
+ usedBytes += bytes; usedChars += serialized.length;
42
+ payloads.set(run.id, payload);
43
+ }
44
+ // Captures are optional. They must not crowd out any retained core data.
45
+ for (var run of selectedRuns.slice().reverse()) {
46
+ var payload = payloads.get(run.id);
47
+ if (!payload || payload.recoveryRetention?.state === 'omitted'
48
+ || run.undoStatus === 'applied' || ['accepted', 'rejected'].includes(run.trackedChangeStatus)) continue;
49
+ var captures = cloneSerializableArray(run.trackedChangeCaptures);
50
+ var extraText = captures.length ? JSON.stringify({ trackedChangeCaptures: captures }) : '';
51
+ var extraBytes = getUtf8ByteLength(extraText);
52
+ if (extraBytes && fits(extraBytes, extraText.length)) {
53
+ payload.trackedChangeCaptures = captures;
54
+ remaining -= extraBytes;
55
+ usedBytes += extraBytes; usedChars += extraText.length;
27
56
  }
28
57
  }
29
58
  }
59
+ // Passive directory history uses only the space left after all original
60
+ // recovery payloads and optional captures have been selected.
61
+ var directoryRemaining = Number.isFinite(options?.maxOptionalDirectoryBytes)
62
+ ? Math.max(0, options.maxOptionalDirectoryBytes) : Infinity;
30
63
  return selectedRuns.map(function (run) {
31
- return compactRun(run, actionRunIds.has(run.id));
64
+ var payload = payloads.get(run.id) || compactRunActionPayload(run, false, { includeDirectoryCleanup: false });
65
+ if (options?.deferDirectoryCleanup !== true) payload = appendDirectoryFacts(payload, run,
66
+ options?.preserveRunActionPayload === true, function (bytes, chars) {
67
+ if (bytes > directoryRemaining || !fits(bytes, chars)) return false;
68
+ directoryRemaining -= bytes; remaining -= bytes;
69
+ usedBytes += bytes; usedChars += chars;
70
+ return true;
71
+ }, 'session-budget');
72
+ return compactRun(run, payloads.has(run.id) && !coreWasOmitted(payload), payload);
32
73
  });
33
74
  }
34
75
 
76
+ // Keep the complete display history while allocating finite recovery space
77
+ // across the current project. A record plus its previous merge baseline is
78
+ // transported together; a readable batch must also fit the response bound.
79
+ function compactSessionBatchActions(records, options = {}, buildSessionRecord, SharedSessionTransfer) {
80
+ var budget = SharedSessionTransfer.MAX_RESPONSE_BYTES - 64 * 1024;
81
+ if (SharedSessionTransfer.byteLength(JSON.stringify(records)) <= budget) return records;
82
+ var summaries = records.map(record => buildSessionRecord(record, { preserveRunActionPayload: false, deferDirectoryCleanup: true }));
83
+ var remaining = Math.max(0, budget - SharedSessionTransfer.byteLength(JSON.stringify(summaries)));
84
+ var allocated = new Map();
85
+ var ordered = records.slice().sort((a, b) => Number(b.id === options.activeSessionId) - Number(a.id === options.activeSessionId)
86
+ || (Date.parse(b.updatedAt) || 0) - (Date.parse(a.updatedAt) || 0));
87
+ for (var record of ordered) {
88
+ var summary = summaries.find(item => item.id === record.id);
89
+ var next = buildSessionRecord(record, { preserveRunActionPayload: true, maxActionPayloadBytes: remaining, deferDirectoryCleanup: true });
90
+ remaining -= Math.max(0, SharedSessionTransfer.byteLength(JSON.stringify(next)) - SharedSessionTransfer.byteLength(JSON.stringify(summary)));
91
+ allocated.set(record.id, next);
92
+ }
93
+ // Do not let an active session's optional directory facts evict another
94
+ // session's existing Undo core under the shared response bound.
95
+ for (var record of ordered) {
96
+ var core = allocated.get(record.id);
97
+ var sourceRuns = new Map((record.runs || []).map(run => [run.id, run]));
98
+ var withFacts = { ...core, runs: core.runs.map(run => {
99
+ var source = sourceRuns.get(run.id), next = { ...run };
100
+ if (source?.pendingDirectoryCleanup) next.pendingDirectoryCleanup = source.pendingDirectoryCleanup;
101
+ if (source?.recoveryRetention?.directoryCleanup === true) next.recoveryRetention = {
102
+ ...(next.recoveryRetention || { ...source.recoveryRetention, coreRetained: true }), directoryCleanup: true };
103
+ return next;
104
+ }) };
105
+ var enriched = buildSessionRecord(withFacts, { preserveRunActionPayload: true, maxOptionalDirectoryBytes: remaining });
106
+ remaining -= Math.max(0, SharedSessionTransfer.byteLength(JSON.stringify(enriched)) - SharedSessionTransfer.byteLength(JSON.stringify(core)));
107
+ allocated.set(record.id, enriched);
108
+ }
109
+ return records.map(record => allocated.get(record.id));
110
+ }
111
+
35
112
  function hasReloadableRunActionPayload(run) {
113
+ if (!run || run.forkSnapshot === true) return false;
114
+ if (runDirectoryCleanup(run)) return true;
115
+ if (run.undoStatus === 'applied' || ['accepted', 'rejected'].includes(run.trackedChangeStatus)) return false;
36
116
  var trackedStatus = run && run.trackedChangeStatus;
37
117
  var trackedLifecycle = (trackedStatus === 'pending' || trackedStatus === 'needs_review')
38
118
  && Array.isArray(run.undoTrackedChanges) && run.undoTrackedChanges.length > 0
@@ -52,29 +132,96 @@
52
132
  return trackedLifecycle || reviewingEditorUndo || legacyUndo;
53
133
  }
54
134
 
55
- function compactRunActionPayload(run, keepActionPayload) {
135
+ function runDirectoryCleanup(run) {
136
+ var proof = DirectoryCleanupProof.normalize(run?.pendingDirectoryCleanup);
137
+ return proof && proof.runId === run.id && proof.projectId === run.runProjectId ? proof : null;
138
+ }
139
+
140
+ function omitted(reason, bytes = 0) {
141
+ return { state: 'omitted', reason, bytes };
142
+ }
143
+
144
+ function withoutDirectoryFacts(run) {
145
+ var core = { ...run };
146
+ delete core.pendingDirectoryCleanup;
147
+ if (core.recoveryRetention?.directoryCleanup === true) {
148
+ if (core.recoveryRetention.coreRetained === true) delete core.recoveryRetention;
149
+ else {
150
+ core.recoveryRetention = { ...core.recoveryRetention };
151
+ delete core.recoveryRetention.directoryCleanup;
152
+ delete core.recoveryRetention.coreRetained;
153
+ }
154
+ }
155
+ return core;
156
+ }
157
+
158
+ function coreWasOmitted(payload) {
159
+ return payload.recoveryRetention?.state === 'omitted' && payload.recoveryRetention.coreRetained !== true;
160
+ }
161
+
162
+ function appendDirectoryFacts(payload, run, keep, fits, reason) {
163
+ if (run?.forkSnapshot === true) return payload;
164
+ var directory = runDirectoryCleanup(run), previous = run?.recoveryRetention;
165
+ if (!directory && previous?.directoryCleanup !== true) return payload;
166
+ if (directory && keep) {
167
+ var extended = { ...payload, pendingDirectoryCleanup: directory };
168
+ var before = JSON.stringify(payload), after = JSON.stringify(extended);
169
+ if (fits(getUtf8ByteLength(after) - getUtf8ByteLength(before), after.length - before.length)) return extended;
170
+ }
171
+ // The existing omission marker distinguishes optional history from lost
172
+ // recovery authority. Never imply that a retained Undo core was discarded.
173
+ var retention = coreWasOmitted(payload) ? payload.recoveryRetention
174
+ : omitted(!keep ? 'fallback' : directory ? reason : previous.reason,
175
+ directory ? getUtf8ByteLength(JSON.stringify(directory)) : previous.bytes);
176
+ return { ...payload, recoveryRetention: { ...retention, directoryCleanup: true,
177
+ ...(!coreWasOmitted(payload) ? { coreRetained: true } : {}) } };
178
+ }
179
+
180
+ function compactRunActionPayload(run, keepActionPayload, options = {}) {
181
+ var payload = compactCoreActionPayload(withoutDirectoryFacts(run), keepActionPayload, options);
182
+ if (options.includeDirectoryCleanup === false) return payload;
183
+ var serialized = JSON.stringify(payload);
184
+ return appendDirectoryFacts(payload, run, keepActionPayload,
185
+ bytes => getUtf8ByteLength(serialized) + bytes <= MAX_PERSISTED_ACTION_BYTES_PER_SESSION, 'run-budget');
186
+ }
187
+
188
+ function compactCoreActionPayload(run, keepActionPayload, options = {}) {
56
189
  var empty = emptyActionPayload();
57
190
  if (!keepActionPayload || !hasReloadableRunActionPayload(run)) {
191
+ if (hasReloadableRunActionPayload(run)) empty.recoveryRetention = omitted('fallback');
192
+ else if (run?.recoveryRetention?.state === 'omitted' && !run.forkSnapshot
193
+ && run.undoStatus !== 'applied' && !['accepted', 'rejected'].includes(run.trackedChangeStatus)) {
194
+ empty.recoveryRetention = omitted(
195
+ ['run-budget', 'session-budget', 'fallback', 'invalid'].includes(run.recoveryRetention.reason)
196
+ ? run.recoveryRetention.reason : 'invalid', Math.max(0, Number(run.recoveryRetention.bytes) || 0));
197
+ }
58
198
  return empty;
59
199
  }
60
- var payload = {
200
+ var terminal = run.undoStatus === 'applied' || ['accepted', 'rejected'].includes(run.trackedChangeStatus);
201
+ var payload = terminal ? emptyActionPayload() : {
61
202
  appliedOperations: cloneSerializableArray(run.appliedOperations),
62
203
  undoOperations: cloneSerializableArray(run.undoOperations),
63
204
  undoBaseFiles: cloneSerializableArray(run.undoBaseFiles),
64
205
  undoTrackedChanges: cloneSerializableArray(run.undoTrackedChanges),
65
206
  undoExpectedFiles: cloneSerializableArray(run.undoExpectedFiles)
66
207
  };
208
+ if (!terminal && Object.keys(payload).some(key => run[key]?.length && !payload[key].length)) {
209
+ return { ...empty, recoveryRetention: omitted('invalid') };
210
+ }
67
211
  var serialized;
68
212
  try {
69
213
  serialized = JSON.stringify(payload);
70
214
  } catch (_error) {
71
- return empty;
215
+ return { ...empty, recoveryRetention: omitted('invalid') };
72
216
  }
73
- if (getUtf8ByteLength(serialized) > MAX_PERSISTED_ACTION_BYTES_PER_RUN) return empty;
217
+ var bytes = getUtf8ByteLength(serialized);
218
+ if (bytes > MAX_PERSISTED_ACTION_BYTES_PER_SESSION) return { ...empty,
219
+ recoveryRetention: omitted('run-budget', bytes) };
220
+ if (options.includeCaptures === false || terminal) return payload;
74
221
  const captures = cloneSerializableArray(run.trackedChangeCaptures);
75
222
  if (captures.length) {
76
223
  const extended = { ...payload, trackedChangeCaptures: captures };
77
- if (getUtf8ByteLength(JSON.stringify(extended)) <= MAX_PERSISTED_ACTION_BYTES_PER_RUN) return extended;
224
+ if (getUtf8ByteLength(JSON.stringify(extended)) <= MAX_PERSISTED_ACTION_BYTES_PER_SESSION) return extended;
78
225
  }
79
226
  return payload; // Optional capture evidence must never evict a mature Undo payload.
80
227
  }
@@ -126,6 +273,8 @@
126
273
  compact.focusFiles = snapshot.focusFiles.slice(0, 100)
127
274
  .filter(function (value) { return typeof value === 'string'; }).map(normalize);
128
275
  }
276
+ compact.selectionContext = SelectionContext.normalize(snapshot.selectionContext);
277
+ compact.writingStyle = WritingStyle.normalizeSnapshot(snapshot.writingStyle);
129
278
  return { executionSnapshot: compact };
130
279
  }
131
280
 
@@ -163,17 +312,20 @@
163
312
  function mergeSessionReviewState(incoming, existing, reviewRunIds) {
164
313
  if (!existing || incoming.id !== existing.id || incoming.projectId !== existing.projectId
165
314
  || !incoming.accountScopeId || incoming.accountScopeId !== existing.accountScopeId) return incoming;
166
- var terminal = run => ['accepted', 'rejected'].includes(run?.trackedChangeStatus);
315
+ var terminal = run => ['accepted', 'rejected'].includes(run?.trackedChangeStatus) || run?.undoStatus === 'applied';
167
316
  var incomingRuns = new Map((incoming.runs || []).map(run => [run.id, run]));
168
317
  var existingRuns = new Map((existing.runs || []).map(run => [run.id, run]));
169
318
  var requestedIds = new Set(reviewRunIds || []);
170
- var explicitReview = Array.from(requestedIds).some(id =>
171
- ['accepted', 'rejected', 'needs_review'].includes(incomingRuns.get(id)?.trackedChangeStatus));
319
+ var explicitReview = Array.from(requestedIds).some(id => {
320
+ var run = incomingRuns.get(id);
321
+ return ['accepted', 'rejected', 'needs_review'].includes(run?.trackedChangeStatus)
322
+ || ['applied', 'partial'].includes(run?.undoStatus);
323
+ });
172
324
  var newer = (Date.parse(incoming.updatedAt) || 0) >= (Date.parse(existing.updatedAt) || 0);
173
325
  if (!newer && !explicitReview) return incoming;
174
326
  var base = newer ? incoming : existing;
175
- var fields = ['trackedChangeStatus', 'undoStatus', 'undoTrackedChanges', 'undoExpectedFiles',
176
- 'undoOperations', 'undoBaseFiles', 'appliedOperations', 'trackedChangeCaptures', 'settlement', 'settlementFacts'];
327
+ var fields = ['trackedChangeStatus', 'undoStatus', 'undoOwnerProtocol', 'undoTrackedChanges', 'undoExpectedFiles',
328
+ 'undoOperations', 'undoBaseFiles', 'appliedOperations', 'trackedChangeCaptures', 'recoveryRetention', 'settlement', 'settlementFacts'];
177
329
  var changed = false;
178
330
  var runs = (base.runs || []).map(function (run) {
179
331
  var previous = existingRuns.get(run.id), candidate = incomingRuns.get(run.id);
@@ -212,7 +364,44 @@
212
364
  return (hash >>> 0).toString(16).padStart(8, '0');
213
365
  }
214
366
 
367
+ // A successful durable write can omit an oversized checkpoint while the
368
+ // current tab still has it. Warn only the view and exact action revision
369
+ // that was saved; never mutate or remove its in-memory recovery material.
370
+ function projectRetentionUpdates({ liveState, capturedState, written, capturedScope, currentScope } = {}) {
371
+ if (!capturedScope?.accountScopeId || !capturedScope.projectId
372
+ || !Number.isSafeInteger(capturedScope.generation)
373
+ || ['accountScopeId', 'projectId', 'generation'].some(key => capturedScope[key] !== currentScope?.[key])) return [];
374
+ var fields = ['appliedOperations', 'undoOperations', 'undoBaseFiles', 'undoTrackedChanges',
375
+ 'undoExpectedFiles', 'undoStatus', 'trackedChangeStatus', 'pendingDirectoryCleanup'];
376
+ var fingerprint = run => JSON.stringify(fields.map(field => run[field]));
377
+ var updates = [];
378
+ for (var record of written || []) {
379
+ if (record.accountScopeId !== capturedScope.accountScopeId || record.projectId !== capturedScope.projectId) continue;
380
+ var live = liveState?.sessions?.find(session => session.id === record.id);
381
+ var captured = capturedState?.sessions?.find(session => session.id === record.id);
382
+ for (var storedRun of record.runs || []) {
383
+ var run = live?.runs?.find(run => run.id === storedRun.id);
384
+ var original = captured?.runs?.find(run => run.id === storedRun.id);
385
+ if (!run || !original || run.runProjectId !== capturedScope.projectId
386
+ || original.runProjectId !== capturedScope.projectId || !hasReloadableRunActionPayload(run)) continue;
387
+ try {
388
+ if (fingerprint(run) !== fingerprint(original)) continue;
389
+ if (storedRun.recoveryRetention?.state === 'omitted') updates.push({ runId: run.id, retention: { ...storedRun.recoveryRetention } });
390
+ else if (fingerprint(storedRun) === fingerprint(original)) updates.push({ runId: run.id, retention: null });
391
+ } catch (_error) { /* Invalid data cannot establish a revision. */ }
392
+ }
393
+ }
394
+ return updates;
395
+ }
396
+
397
+ function projectRetentionWarnings(input) {
398
+ return projectRetentionUpdates(input).filter(update => update.retention).map(update => update.runId);
399
+ }
400
+
215
401
  return {
402
+ projectRetentionUpdates: projectRetentionUpdates,
403
+ projectRetentionWarnings: projectRetentionWarnings,
404
+ compactSessionBatchActions: compactSessionBatchActions,
216
405
  compactStructuredEventValue: compactStructuredEventValue,
217
406
  mergeSessionReviewState: mergeSessionReviewState,
218
407
  compactRunsForStorage: compactRunsForStorage,
@@ -0,0 +1,40 @@
1
+ (function (root, factory) {
2
+ if (typeof module === 'object' && module.exports) module.exports = factory();
3
+ else root.CodexOverleafModuleRegistry.define('StorageValuePruning', [], factory);
4
+ })(typeof globalThis !== 'undefined' ? globalThis : this, function () {
5
+ 'use strict';
6
+
7
+ function removeEmptySummaryFields(value) {
8
+ var result = {};
9
+ var keys = Object.keys(value || {});
10
+ for (var i = 0; i < keys.length; i++) {
11
+ var key = keys[i];
12
+ var item = value[key];
13
+ if (item === undefined || item === '' || item === null) {
14
+ continue;
15
+ }
16
+ if (Array.isArray(item) && item.length === 0) {
17
+ continue;
18
+ }
19
+ if (item && typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0) {
20
+ continue;
21
+ }
22
+ result[key] = item;
23
+ }
24
+ return result;
25
+ }
26
+
27
+ function removeEmptyFields(value) {
28
+ var result = {};
29
+ var keys = Object.keys(value);
30
+ for (var i = 0; i < keys.length; i++) {
31
+ var key = keys[i];
32
+ if (value[key] !== undefined && value[key] !== '') {
33
+ result[key] = value[key];
34
+ }
35
+ }
36
+ return result;
37
+ }
38
+
39
+ return { removeEmptySummaryFields, removeEmptyFields };
40
+ });
@@ -0,0 +1,174 @@
1
+ (function initSubagentActivityModel(root, factory) {
2
+ if (typeof module === 'object' && module.exports) {
3
+ module.exports = factory(require('./agentTranscript'), require('./runActivityModel'));
4
+ } else root.CodexOverleafModuleRegistry.define('SubagentActivityModel', ['AgentTranscript', 'RunActivityModel'], factory);
5
+ })(typeof globalThis !== 'undefined' ? globalThis : window, function subagentActivityModelFactory(Transcript, Activity) {
6
+ 'use strict';
7
+ const MAX_AGENTS = 16, MAX_EVENTS = 100, MAX_CHARS = 48000;
8
+ const STATES = new Set(['pending', 'running', 'completed', 'failed', 'cancelled', 'unknown']);
9
+ const TERMINAL = new Set(['completed', 'failed', 'cancelled']);
10
+ const string = value => typeof value === 'string' ? value : '';
11
+ function clean(value, sanitize = string, limit = 24000) {
12
+ return string(sanitize(string(value))).slice(0, limit);
13
+ }
14
+ function trim(agent) {
15
+ if (agent.events.length > MAX_EVENTS) { agent.events = agent.events.slice(-MAX_EVENTS); agent.clipped = true; }
16
+ while (agent.events.length > 1 && JSON.stringify(agent.events).length > MAX_CHARS) {
17
+ agent.events.shift(); agent.clipped = true;
18
+ }
19
+ return agent;
20
+ }
21
+ function normalize(agents, sanitize = string) {
22
+ const seen = new Set();
23
+ return (Array.isArray(agents) ? agents : []).slice(0, MAX_AGENTS).filter(agent => {
24
+ if (!agent || !['broker', 'codex'].includes(agent.source)) return false;
25
+ const id = agent.source === 'broker' ? agent.jobId : agent.threadId;
26
+ if (typeof id !== 'string' || !/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,159}$/.test(id)) return false;
27
+ const key = agent.source + ':' + id;
28
+ if (seen.has(key)) return false;
29
+ seen.add(key); return true;
30
+ }).map(agent => trim({
31
+ v: 1, source: agent.source, key: agent.source + ':' + (agent.source === 'broker' ? agent.jobId : agent.threadId),
32
+ jobId: clean(agent.jobId, sanitize, 160), threadId: clean(agent.threadId, sanitize, 160),
33
+ parentThreadId: clean(agent.parentThreadId, sanitize, 160),
34
+ title: clean(agent.title, sanitize, 160), task: clean(agent.task, sanitize, 4096),
35
+ model: clean(agent.model, sanitize, 160), reasoningEffort: clean(agent.reasoningEffort, sanitize, 32),
36
+ status: STATES.has(agent.status) ? agent.status : 'unknown',
37
+ startedAt: clean(agent.startedAt, sanitize, 64), updatedAt: clean(agent.updatedAt, sanitize, 64),
38
+ finishedAt: clean(agent.finishedAt, sanitize, 64),
39
+ lastSequence: Number.isSafeInteger(agent.lastSequence) ? agent.lastSequence : 0,
40
+ nativeEventSeq: Number.isSafeInteger(agent.nativeEventSeq) ? agent.nativeEventSeq : 0,
41
+ clipped: agent.clipped === true, historyUnavailable: agent.historyUnavailable === true,
42
+ events: (Array.isArray(agent.events) ? agent.events : []).filter(event => event && typeof event.title === 'string')
43
+ .slice(-MAX_EVENTS).map(event => ({
44
+ title: clean(event.title, sanitize), status: clean(event.status, sanitize, 32),
45
+ timestamp: clean(event.timestamp, sanitize, 64),
46
+ kind: event.kind === 'stream' ? 'stream' : 'activity',
47
+ streamKey: clean(event.streamKey, sanitize, 600), streamRole: event.streamRole === 'assistant' ? 'assistant' : '',
48
+ streamPhase: Activity.normalizePhase(event.streamPhase),
49
+ activity: Activity.normalize(event.activity, sanitize)
50
+ }))
51
+ }));
52
+ }
53
+ function effectiveStatus(agent, run) {
54
+ if (TERMINAL.has(agent.status) || agent.status === 'unknown' || run.status === 'running') return agent.status;
55
+ return ['cancelled', 'rejected'].includes(run.status) ? 'cancelled' : 'unknown';
56
+ }
57
+ function terminalTime(agent, run) {
58
+ const terminal = [agent.finishedAt, run.status === 'running' ? '' : run.finishedAt]
59
+ .map(value => Date.parse(value || '')).find(Number.isFinite);
60
+ const evidence = [agent.startedAt, agent.updatedAt, ...(agent.events || []).map(event => event.timestamp)];
61
+ if (run.status !== 'running') evidence.push(run.startedAt, run.updatedAt, ...(run.events || []).map(event => event.timestamp));
62
+ return terminal ?? Math.max(...evidence.map(value => Date.parse(value || '')).filter(Number.isFinite));
63
+ }
64
+ function elapsedMs(agent, run, now = Date.now()) {
65
+ const start = Date.parse(agent.startedAt || '');
66
+ const live = run.status === 'running' && ['pending', 'running'].includes(effectiveStatus(agent, run));
67
+ return Number.isFinite(start) ? Math.max(0, (live ? now : terminalTime(agent, run)) - start) : null;
68
+ }
69
+ function append(agent, input, sanitize) {
70
+ const event = {
71
+ title: clean(input.title, sanitize), status: input.status || 'running',
72
+ timestamp: input.timestamp || new Date().toISOString(),
73
+ kind: input.kind === 'stream' ? 'stream' : 'activity',
74
+ streamKey: input.streamKey || '', streamRole: input.streamRole || '',
75
+ streamPhase: Activity.normalizePhase(input.streamPhase),
76
+ activity: Activity.normalize(input.activity, sanitize)
77
+ };
78
+ if (!event.title) return;
79
+ const key = event.kind === 'stream' ? 'stream:' + event.streamKey : event.activity?.id;
80
+ const previous = key && agent.events.find(old => (old.kind === 'stream' ? 'stream:' + old.streamKey : old.activity?.id) === key);
81
+ if (previous) {
82
+ if (previous.status === 'completed' && event.status === 'running' && input.appendText) return;
83
+ const fullText = input.appendText ? previous.title + event.title : event.title;
84
+ if (fullText.length > 24000) agent.clipped = true;
85
+ const activity = previous.activity && event.activity ? { ...previous.activity, ...event.activity,
86
+ command: event.activity.command || previous.activity.command,
87
+ output: event.activity.output || previous.activity.output,
88
+ paths: event.activity.paths?.length ? event.activity.paths : previous.activity.paths,
89
+ files: event.activity.files?.length ? event.activity.files : previous.activity.files } : event.activity || previous.activity;
90
+ Object.assign(previous, event, { title: fullText.slice(0, 24000), activity });
91
+ } else agent.events.push(event);
92
+ trim(agent);
93
+ }
94
+ function addAnswer(agent, answer, timestamp, sanitize) {
95
+ if (!answer) return;
96
+ const last = agent.events.filter(event => event.kind === 'stream' && event.streamRole === 'assistant').at(-1);
97
+ const safe = clean(answer, sanitize);
98
+ if (last?.title.trim() === safe.trim()) { last.status = 'completed'; return; }
99
+ append(agent, { kind: 'stream', streamRole: 'assistant', streamPhase: 'final_answer',
100
+ streamKey: last?.streamPhase === 'final_answer' ? last.streamKey : 'answer:' + agent.key,
101
+ title: safe, status: 'completed', timestamp }, sanitize);
102
+ }
103
+ function ingest(run, raw, options = {}) {
104
+ const type = string(raw?.type), detail = raw?.detail || {};
105
+ if (type === 'codex.subagent.drained') return true;
106
+ if (!['codex.subagent.queued', 'codex.subagent.started', 'codex.subagent.completed',
107
+ 'codex.subagent.failed', 'codex.subagent.rejected', 'codex.subagent.event', 'codex.subagent.observed'].includes(type)) return false;
108
+ const source = detail.source === 'codex' ? 'codex' : 'broker';
109
+ const id = source === 'broker' ? string(detail.jobId || detail.id) : string(detail.threadId);
110
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,159}$/.test(id)) return true;
111
+ const sanitize = options.sanitize || string, key = source + ':' + id;
112
+ const agents = run.subagents || (run.subagents = []);
113
+ let agent = agents.find(item => item.key === key);
114
+ if (!agent) {
115
+ if (agents.length >= MAX_AGENTS) return true;
116
+ agent = { v: 1, source, key, jobId: source === 'broker' ? id : '', threadId: source === 'codex' ? id : '',
117
+ title: id, task: '', status: 'pending', events: [], nativeEventSeq: 0, lastSequence: 0 };
118
+ agents.push(agent);
119
+ }
120
+ const seq = Number(options.nativeEventSeq) || 0;
121
+ if (seq > 0 && seq <= (agent.nativeEventSeq || 0)) return true;
122
+ const sequence = Number(detail.sequence) || 0;
123
+ if (sequence > 0 && sequence <= (agent.lastSequence || 0)) return true;
124
+ agent.nativeEventSeq = Math.max(agent.nativeEventSeq || 0, seq);
125
+ agent.lastSequence = Math.max(agent.lastSequence || 0, sequence);
126
+ const timestamp = string(raw.timestamp) || new Date().toISOString(), at = Date.parse(string(raw.timestamp));
127
+ const wasTerminal = TERMINAL.has(agent.status), previousEnd = terminalTime(agent, run);
128
+ if (Number.isFinite(at) && at < Date.parse(agent.startedAt || '')) return true;
129
+ agent.updatedAt = timestamp;
130
+ for (const field of ['title', 'task', 'threadId', 'parentThreadId', 'model', 'reasoningEffort']) {
131
+ const value = detail[field] || (field === 'title' ? raw.title : '');
132
+ if (typeof value === 'string' && value) agent[field] = clean(value, sanitize, field === 'task' ? 4096 : 160);
133
+ }
134
+ agent.clipped ||= detail.historyClipped === true;
135
+ if (typeof detail.historyUnavailable === 'boolean') agent.historyUnavailable = detail.historyUnavailable;
136
+ let next = type.endsWith('.queued') ? 'pending' : type.endsWith('.started') ? 'running'
137
+ : type.endsWith('.completed') ? 'completed' : type.endsWith('.rejected') ? 'failed'
138
+ : type.endsWith('.failed') ? (detail.status === 'cancelled' ? 'cancelled' : 'failed') : detail.status;
139
+ const inner = type === 'codex.subagent.event' ? detail.event : null;
140
+ const method = inner?.detail?.method, params = inner?.detail?.params || {};
141
+ if (method === 'turn/started') next = 'running';
142
+ if (method === 'turn/completed' && source === 'codex') next = params.turn?.status === 'interrupted' ? 'cancelled' : params.turn?.status;
143
+ const reopening = wasTerminal && method === 'turn/started';
144
+ if (STATES.has(next) && (!wasTerminal || TERMINAL.has(next) || reopening)) agent.status = next;
145
+ if (reopening) { agent.startedAt = timestamp; agent.finishedAt = ''; }
146
+ if (agent.status === 'running' && !agent.startedAt) agent.startedAt = timestamp;
147
+ if (TERMINAL.has(agent.status) || run.status !== 'running') {
148
+ // Late snapshots describe the same stopped interval; only a new turn resets it.
149
+ const end = wasTerminal || run.status !== 'running' || !Number.isFinite(at) ? previousEnd : at;
150
+ if (Number.isFinite(end)) agent.finishedAt = new Date(end).toISOString();
151
+ }
152
+ if (inner) {
153
+ const boundThread = inner.detail?.threadId || params.threadId || params.thread?.id;
154
+ if (boundThread) agent.threadId = clean(boundThread, sanitize, 160);
155
+ if (params.thread?.model) agent.model = clean(params.thread.model, sanitize, 160);
156
+ const mapped = Transcript.mapAgentEventToActivity(inner, { locale: options.locale });
157
+ const activity = Activity.capture({ ...mapped, technicalDetail: mapped?.technicalDetail || inner }, sanitize);
158
+ if (mapped?.visible && mapped.kind !== 'technical' && (!mapped.streamRole || mapped.streamRole === 'assistant')) {
159
+ const itemId = params.item?.id || params.itemId || inner.detail?.itemId;
160
+ const turnId = params.turnId || inner.detail?.turnId || '';
161
+ append(agent, { ...mapped, timestamp, activity,
162
+ streamKey: mapped.kind === 'stream' ? turnId + ':' + (itemId || mapped.streamKey || 'assistant') : '' }, sanitize);
163
+ }
164
+ }
165
+ if (TERMINAL.has(agent.status)) {
166
+ for (const event of agent.events) if (event.kind === 'stream' && event.status === 'running') event.status = 'completed';
167
+ addAnswer(agent, detail.summary, timestamp, sanitize);
168
+ if (detail.reason) append(agent, { title: clean(detail.reason, sanitize, 1200), status: 'warning', timestamp,
169
+ activity: { kind: 'notice', id: key + ':failure', state: agent.status === 'failed' ? 'failed' : 'warning' } }, sanitize);
170
+ }
171
+ return true;
172
+ }
173
+ return { normalize, ingest, effectiveStatus, elapsedMs };
174
+ });