codex-overleaf-link 2.4.1 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +272 -314
- package/README.zh-CN.md +287 -329
- package/extension/bootstrap/background.js +47 -10
- package/extension/bootstrap/manifest.template.json +9 -4
- package/extension/bootstrap/popup.html +10 -16
- package/extension/bootstrap/update.js +25 -2
- package/extension/runtime-manifest.json +3 -1
- package/extension/src/background.js +28 -3
- package/extension/src/backgroundSharedSessions.js +380 -0
- package/extension/src/backgroundUpdateCoordinator.js +442 -379
- package/extension/src/content/activeTurnControl.js +8 -0
- package/extension/src/content/assetTransferBroker.js +186 -12
- package/extension/src/content/changeHistoryView.js +175 -0
- package/extension/src/content/composerAttachments.js +24 -22
- package/extension/src/content/composerPanel.js +23 -8
- package/extension/src/content/contentRuntime.js +507 -507
- package/extension/src/content/diagnosticsController.js +1 -2
- package/extension/src/content/diagnosticsExport.js +222 -0
- package/extension/src/content/diagnosticsPanel.js +48 -19
- package/extension/src/content/diffReviewPanel.js +8 -5
- package/extension/src/content/generated/content.bundle.js +8330 -1349
- package/extension/src/content/generated/content.bundle.meta.json +22 -3
- package/extension/src/content/legacyGlobalRegistry.js +19 -1
- package/extension/src/content/localSkillsPanel.js +42 -7
- package/extension/src/content/markdownDomRenderer.js +9 -4
- package/extension/src/content/modelPicker.js +1 -1
- package/extension/src/content/pageBridgeClient.js +18 -3
- package/extension/src/content/panelMaintenance.js +48 -121
- package/extension/src/content/panelRenderer.js +4 -0
- package/extension/src/content/pendingInputView.js +109 -76
- package/extension/src/content/providerSettingsCoordinator.js +17 -6
- package/extension/src/content/providerSettingsDialog.js +661 -108
- package/extension/src/content/recentProjects.js +10 -1
- package/extension/src/content/runActivitySummary.js +631 -0
- package/extension/src/content/runController.js +3 -1
- package/extension/src/content/runFailureNotice.js +14 -1
- package/extension/src/content/runGuidanceController.js +4 -3
- package/extension/src/content/runPresence.js +306 -0
- package/extension/src/content/runQueueScheduler.js +2 -1
- package/extension/src/content/runResultActions.js +123 -3
- package/extension/src/content/runTimelineView.js +186 -154
- package/extension/src/content/selectionContextView.js +300 -0
- package/extension/src/content/sessionPersistence.js +6 -1
- package/extension/src/content/settingsPanel.js +77 -52
- package/extension/src/content/settingsWorkbench.js +374 -0
- package/extension/src/content/sharedSessionViewSync.js +72 -0
- package/extension/src/content/subagentActivityView.js +195 -0
- package/extension/src/content/trackedChangeCaptureController.js +7 -3
- package/extension/src/content/updateNotice.js +121 -50
- package/extension/src/content/writebackController.js +257 -0
- package/extension/src/content/writebackOrchestrator.js +146 -141
- package/extension/src/content/writebackPlan.js +231 -0
- package/extension/src/content/writebackRecovery.js +122 -0
- package/extension/src/content/writingStyleSettings.js +576 -0
- package/extension/src/content/writtenChangesView.js +152 -0
- package/extension/src/page/binaryAssetUploader.js +97 -19
- package/extension/src/page/overleafProjectSnapshot.js +1 -0
- package/extension/src/page/referenceProjects.js +148 -0
- package/extension/src/page/saveState.js +14 -2
- package/extension/src/page/snapshotRouter.js +44 -13
- package/extension/src/page/textCoordinates.js +102 -0
- package/extension/src/page/textFileCreator.js +350 -59
- package/extension/src/page/trackedChangeCapture.js +42 -56
- package/extension/src/page/trackedChangeOwnership.js +198 -0
- package/extension/src/page/trackedChangeReplay.js +164 -0
- package/extension/src/page/trackedChangesLifecycle.js +135 -149
- package/extension/src/page/treeOperations.js +26 -2
- package/extension/src/page/writebackReceiptJournal.js +112 -0
- package/extension/src/page/writebackRouter.js +175 -135
- package/extension/src/pageBridge.js +56 -101
- package/extension/src/popup.js +203 -59
- package/extension/src/shared/agentTranscript.js +18 -4
- package/extension/src/shared/auditRecords.js +71 -0
- package/extension/src/shared/changeHistoryModel.js +94 -0
- package/extension/src/shared/compatibility.js +1 -1
- package/extension/src/shared/compileAdapter.js +42 -0
- package/extension/src/shared/failureReasons.js +20 -0
- package/extension/src/shared/globalPreferences.js +1 -1
- package/extension/src/shared/i18n.js +93 -25
- package/extension/src/shared/managedUpdateProjection.js +6 -3
- package/extension/src/shared/pageRpcContract.js +7 -1
- package/extension/src/shared/providerProfiles.js +109 -0
- package/extension/src/shared/runActivityModel.js +361 -0
- package/extension/src/shared/runExecutionSnapshot.js +8 -2
- package/extension/src/shared/runExecutionSnapshotCodec.js +16 -4
- package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
- package/extension/src/shared/selectionContext.js +28 -0
- package/extension/src/shared/sessionState.js +97 -6
- package/extension/src/shared/sharedSessionBridge.js +288 -0
- package/extension/src/shared/storageDb.js +22 -55
- package/extension/src/shared/storageMigration.js +3 -0
- package/extension/src/shared/storageRunActions.js +10 -4
- package/extension/src/shared/storageValuePruning.js +40 -0
- package/extension/src/shared/subagentActivityModel.js +174 -0
- package/extension/src/shared/undoOperations.js +87 -0
- package/extension/src/shared/updateConsent.js +37 -8
- package/extension/src/shared/writebackIntent.js +62 -0
- package/extension/src/shared/writebackSettlement.js +29 -10
- package/extension/src/shared/writingStyle.js +33 -0
- package/extension/styles/panel.css +1972 -384
- package/extension/styles/popup.css +110 -0
- package/native-host/src/anthropicBridgeRequest.js +2 -1
- package/native-host/src/codexModelRecovery.js +107 -0
- package/native-host/src/codexPromptAssembly.js +2 -0
- package/native-host/src/codexProviderLaunch.js +3 -3
- package/native-host/src/codexRuntimeIdentity.js +1 -0
- package/native-host/src/codexSessionRunner.js +106 -140
- package/native-host/src/codexSessionTiming.js +3 -0
- package/native-host/src/managedInstall.js +5 -4
- package/native-host/src/nativeEnvironment.js +70 -0
- package/native-host/src/nativeQuotas.js +15 -8
- package/native-host/src/overleafWorkspaceRules.js +16 -0
- package/native-host/src/processStopBarrier.js +80 -0
- package/native-host/src/providerModelCatalog.js +4 -3
- package/native-host/src/providerProfile.js +13 -1
- package/native-host/src/providerReasoning.js +9 -5
- package/native-host/src/providerStore.js +4 -0
- package/native-host/src/releaseTransport.js +14 -5
- package/native-host/src/selectionScope.js +58 -0
- package/native-host/src/skills/parallel-subagents/SKILL.md +31 -3
- package/native-host/src/skills/writing-style-builder/SKILL.md +146 -0
- package/native-host/src/subagentBroker.js +102 -98
- package/native-host/src/subagentTelemetry.js +316 -0
- package/native-host/src/subagentWorkspace.js +103 -0
- package/native-host/src/subagentWorkspacePath.js +31 -0
- package/native-host/src/taskRunnerRuntime.js +55 -5
- package/native-host/src/turnAttachments.js +113 -0
- package/native-host/src/updateManager.js +122 -12
- package/native-host/src/updateNetworkControl.js +75 -0
- package/native-host/src/updateTrust.js +21 -2
- package/native-host/src/vendor/pdfjs/LICENSE +177 -0
- package/native-host/src/vendor/pdfjs/SOURCE.txt +3 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/LICENSE +36 -0
- package/native-host/src/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/pdf.mjs +26740 -0
- package/native-host/src/vendor/pdfjs/pdf.worker.mjs +62201 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/native-host/src/writingStyleEvidence.js +102 -0
- package/native-host/src/writingStylePdfWorker.js +35 -0
- package/native-host/src/writingStyleProfile.js +165 -0
- package/native-host/src/writingStyleRuntime.js +447 -0
- package/package.json +1 -1
|
@@ -4,14 +4,18 @@
|
|
|
4
4
|
require('./i18n'),
|
|
5
5
|
require('./settlementFacts'),
|
|
6
6
|
require('./runInputQueue'),
|
|
7
|
+
require('./selectionContext'),
|
|
7
8
|
require('./lineReferences'),
|
|
8
9
|
require('./pathRedaction'),
|
|
9
|
-
require('./sessionTitle')
|
|
10
|
+
require('./sessionTitle'),
|
|
11
|
+
require('./runActivityModel'),
|
|
12
|
+
require('./subagentActivityModel'),
|
|
13
|
+
require('./writebackIntent')
|
|
10
14
|
);
|
|
11
15
|
} else {
|
|
12
16
|
root.CodexOverleafModuleRegistry.define(
|
|
13
17
|
'SessionState',
|
|
14
|
-
['I18n', 'SettlementFacts', 'RunInputQueue', 'LineReferences', 'PathRedaction', 'SessionTitle'],
|
|
18
|
+
['I18n', 'SettlementFacts', 'RunInputQueue', 'SelectionContext', 'LineReferences', 'PathRedaction', 'SessionTitle', 'RunActivityModel', 'SubagentActivityModel', 'WritebackIntent'],
|
|
15
19
|
factory
|
|
16
20
|
);
|
|
17
21
|
}
|
|
@@ -19,9 +23,13 @@
|
|
|
19
23
|
i18n,
|
|
20
24
|
SettlementFacts,
|
|
21
25
|
RunInputQueue,
|
|
26
|
+
SelectionContext,
|
|
22
27
|
LineReferences,
|
|
23
28
|
PathRedaction,
|
|
24
|
-
SessionTitle
|
|
29
|
+
SessionTitle,
|
|
30
|
+
RunActivityModel,
|
|
31
|
+
SubagentActivityModel,
|
|
32
|
+
WritebackIntent
|
|
25
33
|
) {
|
|
26
34
|
'use strict';
|
|
27
35
|
|
|
@@ -232,6 +240,7 @@
|
|
|
232
240
|
: fallbackState.speedTier,
|
|
233
241
|
requireReviewing: session.requireReviewing !== false,
|
|
234
242
|
focusFiles: normalizeFocusFiles(session.focusFiles),
|
|
243
|
+
selectionContext: SelectionContext.normalize(session.selectionContext),
|
|
235
244
|
projectReferenceFiles: normalizeProjectReferenceFiles(session.projectReferenceFiles),
|
|
236
245
|
codexThreadId: typeof session.codexThreadId === 'string' ? session.codexThreadId : '',
|
|
237
246
|
forkedFromSessionId: typeof session.forkedFromSessionId === 'string' ? session.forkedFromSessionId : '',
|
|
@@ -319,6 +328,7 @@
|
|
|
319
328
|
state.runs = Array.isArray(active.runs) ? active.runs : [];
|
|
320
329
|
state.task = typeof active.task === 'string' ? active.task : '';
|
|
321
330
|
state.focusFiles = normalizeFocusFiles(active.focusFiles);
|
|
331
|
+
state.selectionContext = SelectionContext.normalize(active.selectionContext);
|
|
322
332
|
state.mode = normalizeMode(active.mode);
|
|
323
333
|
state.requireReviewing = active.requireReviewing !== false;
|
|
324
334
|
|
|
@@ -354,6 +364,7 @@
|
|
|
354
364
|
: DEFAULT_PANEL_STATE.speedTier,
|
|
355
365
|
requireReviewing: overrides.requireReviewing !== false,
|
|
356
366
|
focusFiles: normalizeFocusFiles(overrides.focusFiles),
|
|
367
|
+
selectionContext: SelectionContext.normalize(overrides.selectionContext),
|
|
357
368
|
projectReferenceFiles: normalizeProjectReferenceFiles(overrides.projectReferenceFiles),
|
|
358
369
|
codexThreadId: typeof overrides.codexThreadId === 'string' ? overrides.codexThreadId : '',
|
|
359
370
|
forkedFromSessionId: typeof overrides.forkedFromSessionId === 'string' ? overrides.forkedFromSessionId : '',
|
|
@@ -592,7 +603,48 @@
|
|
|
592
603
|
.slice(-20);
|
|
593
604
|
}
|
|
594
605
|
|
|
606
|
+
function recordedRunFailure(run) {
|
|
607
|
+
const event = [...(Array.isArray(run?.events) ? run.events : [])].reverse()
|
|
608
|
+
.find(item => item && item.kind !== 'technical' && item.subagent !== true);
|
|
609
|
+
if (!event || event.status !== 'failed' || (event.kind && event.kind !== 'activity')
|
|
610
|
+
|| event.streamRole || event.streamKey || event.guidanceId) return null;
|
|
611
|
+
if (!['Codex returned a result, but local post-processing of this run failed.',
|
|
612
|
+
'Codex 已经返回了结果,但本地处理这一轮时出错了。'].includes(event.title)) return null;
|
|
613
|
+
const meta = RunActivityModel.capture(event);
|
|
614
|
+
// Capture encodes even an unscoped local event as [threadId, turnId].
|
|
615
|
+
const scoped = meta?.scope && meta.scope !== JSON.stringify(['', '']);
|
|
616
|
+
if (meta?.kind !== 'notice' || meta.state !== 'failed' || meta.id || scoped || meta.noticeSource) return null;
|
|
617
|
+
const ended = Date.parse(event.timestamp), started = Date.parse(run.startedAt);
|
|
618
|
+
if (!Number.isFinite(ended) || (Number.isFinite(started) && ended < started)) return null;
|
|
619
|
+
return event;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// On restore only: a run that already finished (finishedAt plus a terminal
|
|
623
|
+
// report as its last visible event) but was persisted as running by a stale
|
|
624
|
+
// status write. Live retries also carry an old finishedAt, so never in memory.
|
|
625
|
+
function recoverSettledRunningRun(run) {
|
|
626
|
+
if (run?.status !== 'running' || !Number.isFinite(Date.parse(run.finishedAt))) return run;
|
|
627
|
+
const last = [...(Array.isArray(run.events) ? run.events : [])].reverse()
|
|
628
|
+
.find(item => item && item.kind !== 'technical' && item.subagent !== true);
|
|
629
|
+
if (last?.kind !== 'report' || !['completed', 'failed'].includes(last.status)
|
|
630
|
+
|| Date.parse(last.timestamp) > Date.parse(run.finishedAt)) return run;
|
|
631
|
+
return { ...run, status: last.status };
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
function recoverRecordedRunFailure(run, locale = i18n.DEFAULT_LOCALE) {
|
|
635
|
+
if (run?.status !== 'running') return run;
|
|
636
|
+
const event = recordedRunFailure(run);
|
|
637
|
+
if (!event) return run;
|
|
638
|
+
// This acknowledgement is emitted only by the parent's terminal catch.
|
|
639
|
+
// It survives a render failure that prevented the old owner from settling.
|
|
640
|
+
return { ...run, status: 'failed',
|
|
641
|
+
statusText: i18n.t(locale, 'processedFailed', { elapsed: '' }).trim(),
|
|
642
|
+
finishedAt: Number.isFinite(Date.parse(run.finishedAt)) ? run.finishedAt : event.timestamp };
|
|
643
|
+
}
|
|
644
|
+
|
|
595
645
|
function normalizeRun(run, options = {}) {
|
|
646
|
+
if (options.restoreRunningRuns === true || options.recoverSettledRuns === true) run = recoverSettledRunningRun(run);
|
|
647
|
+
run = recoverRecordedRunFailure(run, options.locale);
|
|
596
648
|
const shouldStopRestoredRun = options.restoreRunningRuns === true && run.status === 'running';
|
|
597
649
|
const locale = options.locale || i18n.DEFAULT_LOCALE;
|
|
598
650
|
const events = normalizeRunEvents(run.events);
|
|
@@ -622,12 +674,13 @@
|
|
|
622
674
|
model: typeof run.model === 'string' ? run.model : '',
|
|
623
675
|
reasoningEffort: typeof run.reasoningEffort === 'string' ? run.reasoningEffort : '',
|
|
624
676
|
speedTier: typeof run.speedTier === 'string' ? run.speedTier : '',
|
|
625
|
-
status: shouldStopRestoredRun ? 'interrupted' : normalizeRunStatus(run.status),
|
|
677
|
+
status: shouldStopRestoredRun ? 'interrupted' : normalizeRunStatus(run.status, run),
|
|
626
678
|
statusText: shouldStopRestoredRun ? i18n.t(locale, 'restoredRunStoppedStatus') : sanitizeAssistantVisibleText(run.statusText),
|
|
627
679
|
runProjectId: normalizeProjectPrefKey(run.runProjectId),
|
|
628
680
|
startedAt: typeof run.startedAt === 'string' ? run.startedAt : '',
|
|
629
681
|
finishedAt: shouldStopRestoredRun ? new Date().toISOString() : typeof run.finishedAt === 'string' ? run.finishedAt : '',
|
|
630
682
|
events: events.slice(-MAX_RUN_EVENTS),
|
|
683
|
+
...(run.subagents?.length ? { subagents: SubagentActivityModel.normalize(run.subagents, sanitizeAssistantVisibleText) } : {}),
|
|
631
684
|
attachments: normalizeRunAttachments(run.attachments, STORAGE_DEFAULT_LIMITS),
|
|
632
685
|
appliedOperations: Array.isArray(run.appliedOperations) ? run.appliedOperations : [],
|
|
633
686
|
undoOperations: Array.isArray(run.undoOperations) ? run.undoOperations : [],
|
|
@@ -660,6 +713,7 @@
|
|
|
660
713
|
normalized.trackedChangeCaptures = sanitizeAssistantVisibleValue(run.trackedChangeCaptures);
|
|
661
714
|
}
|
|
662
715
|
applyTrackedChangeStatus(normalized, run.trackedChangeStatus);
|
|
716
|
+
Object.assign(normalized, pickWritebackRecovery(run));
|
|
663
717
|
|
|
664
718
|
return normalized;
|
|
665
719
|
}
|
|
@@ -722,13 +776,20 @@
|
|
|
722
776
|
'running',
|
|
723
777
|
'completed',
|
|
724
778
|
'failed',
|
|
779
|
+
'cancelled',
|
|
725
780
|
'interrupted',
|
|
726
781
|
'background_completed',
|
|
727
782
|
'needs_review_after_navigation',
|
|
728
783
|
'abandoned_after_navigation'
|
|
729
784
|
]);
|
|
730
785
|
|
|
731
|
-
function normalizeRunStatus(status) {
|
|
786
|
+
function normalizeRunStatus(status, run = {}) {
|
|
787
|
+
if (status === 'running' && recordedRunFailure(run)) return 'failed';
|
|
788
|
+
if (status === 'rejected') return 'cancelled';
|
|
789
|
+
// Older normalizers rewrote cancelled runs to pending or completed.
|
|
790
|
+
// Recover only with a terminal timestamp and an explicit plugin event.
|
|
791
|
+
if (['pending', 'completed'].includes(status) && Number.isFinite(Date.parse(run.finishedAt))
|
|
792
|
+
&& Array.isArray(run.events) && run.events.some(RunActivityModel.isRoutineCancellationEvent)) return 'cancelled';
|
|
732
793
|
if (VALID_RUN_STATUS.has(status)) return status;
|
|
733
794
|
// Legacy persisted runs without an explicit status fall back to `completed`
|
|
734
795
|
// (the historical default for the recovery branch); unknown values land on
|
|
@@ -753,6 +814,9 @@
|
|
|
753
814
|
timestamp: typeof event.timestamp === 'string' ? event.timestamp : '',
|
|
754
815
|
kind: typeof event.kind === 'string' ? event.kind : 'activity',
|
|
755
816
|
technicalDetail: sanitizeAssistantVisibleValue(event.technicalDetail),
|
|
817
|
+
activity: RunActivityModel.capture(event, sanitizeAssistantVisibleText),
|
|
818
|
+
streamPhase: RunActivityModel.normalizePhase(event.streamPhase),
|
|
819
|
+
subagent: event.subagent === true ? true : undefined,
|
|
756
820
|
guidanceId: sanitizeAssistantVisibleText(event.guidanceId),
|
|
757
821
|
streamKey: sanitizeAssistantVisibleText(event.streamKey),
|
|
758
822
|
streamRole: sanitizeAssistantVisibleText(event.streamRole)
|
|
@@ -1123,6 +1187,7 @@
|
|
|
1123
1187
|
speedTier: normalizeSpeedTier(session.speedTier || fallbackState.speedTier),
|
|
1124
1188
|
requireReviewing: session.requireReviewing !== false,
|
|
1125
1189
|
focusFiles: normalizeFocusFiles(session.focusFiles),
|
|
1190
|
+
selectionContext: SelectionContext.normalize(session.selectionContext),
|
|
1126
1191
|
projectReferenceFiles: normalizeProjectReferenceFiles(session.projectReferenceFiles),
|
|
1127
1192
|
codexThreadId: typeof session.codexThreadId === 'string' ? session.codexThreadId : '',
|
|
1128
1193
|
forkedFromSessionId: normalizeTextField(session.forkedFromSessionId, 160),
|
|
@@ -1196,6 +1261,7 @@
|
|
|
1196
1261
|
}
|
|
1197
1262
|
|
|
1198
1263
|
function compactRunForStorage(run, limits, keepUndoPayload, settlementFacts = null) {
|
|
1264
|
+
run = recoverRecordedRunFailure(run);
|
|
1199
1265
|
const undoPayload = compactUndoPayload(run, limits, keepUndoPayload);
|
|
1200
1266
|
const compact = {
|
|
1201
1267
|
id: run.id,
|
|
@@ -1204,12 +1270,13 @@
|
|
|
1204
1270
|
model: normalizeTextField(run.model, 80),
|
|
1205
1271
|
reasoningEffort: typeof run.reasoningEffort === 'string' ? run.reasoningEffort : '',
|
|
1206
1272
|
speedTier: typeof run.speedTier === 'string' ? run.speedTier : '',
|
|
1207
|
-
status: normalizeRunStatus(run.status),
|
|
1273
|
+
status: normalizeRunStatus(run.status, run),
|
|
1208
1274
|
statusText: summarizeTextForStorage(run.statusText, 'status text'),
|
|
1209
1275
|
runProjectId: normalizeProjectPrefKey(run.runProjectId),
|
|
1210
1276
|
startedAt: typeof run.startedAt === 'string' ? run.startedAt : '',
|
|
1211
1277
|
finishedAt: typeof run.finishedAt === 'string' ? run.finishedAt : '',
|
|
1212
1278
|
events: compactRunEvents(run.events, limits),
|
|
1279
|
+
...(run.subagents?.length ? { subagents: SubagentActivityModel.normalize(run.subagents, sanitizeAssistantVisibleText) } : {}),
|
|
1213
1280
|
attachments: compactRunAttachmentsForStorage(run.attachments, limits),
|
|
1214
1281
|
appliedOperations: [],
|
|
1215
1282
|
undoOperations: undoPayload.undoOperations,
|
|
@@ -1236,6 +1303,7 @@
|
|
|
1236
1303
|
if (run.interruptedDraft) {
|
|
1237
1304
|
compact.interruptedDraft = sanitizeAssistantVisibleValue(run.interruptedDraft);
|
|
1238
1305
|
}
|
|
1306
|
+
Object.assign(compact, pickWritebackRecovery(run));
|
|
1239
1307
|
if (VALID_TRACKED_CHANGE_STATUS.has(run.trackedChangeStatus)) {
|
|
1240
1308
|
compact.trackedChangeStatus = run.trackedChangeStatus;
|
|
1241
1309
|
}
|
|
@@ -1256,6 +1324,8 @@
|
|
|
1256
1324
|
streamKey: typeof event.streamKey === 'string' ? event.streamKey : '',
|
|
1257
1325
|
streamRole: typeof event.streamRole === 'string' ? event.streamRole : ''
|
|
1258
1326
|
};
|
|
1327
|
+
compact.activity = RunActivityModel.capture(event, sanitizeAssistantVisibleText);
|
|
1328
|
+
compact.streamPhase = RunActivityModel.normalizePhase(event.streamPhase);
|
|
1259
1329
|
if (event.subagent === true) {
|
|
1260
1330
|
compact.subagent = true;
|
|
1261
1331
|
}
|
|
@@ -1616,7 +1686,24 @@
|
|
|
1616
1686
|
return new Blob([serialized]).size;
|
|
1617
1687
|
}
|
|
1618
1688
|
|
|
1689
|
+
function pickWritebackRecovery(run = {}) {
|
|
1690
|
+
if (run.forkSnapshot === true || run.undoStatus === 'applied' || run.trackedChangeStatus === 'rejected') return {};
|
|
1691
|
+
const result = {};
|
|
1692
|
+
const retry = WritebackIntent.normalize(run.retryWriteback);
|
|
1693
|
+
if (retry && retry.runId === run.id && retry.projectId === normalizeProjectPrefKey(run.runProjectId)
|
|
1694
|
+
&& retry.operations.every(op => (op.type === 'create' && typeof op.content === 'string')
|
|
1695
|
+
|| (op.type === 'edit' && (op.patches?.length || typeof op.replaceAll === 'string')
|
|
1696
|
+
&& retry.baseFiles.some(file => file.path === op.path))
|
|
1697
|
+
|| (op.type === 'delete' && retry.baseFiles.some(file => file.path === op.path)))
|
|
1698
|
+
&& !containsSecretLikeText(retry)) result.retryWriteback = retry;
|
|
1699
|
+
const check = WritebackIntent.normalizeSaveCheck(run.saveCheck);
|
|
1700
|
+
if (check && check.runId === run.id && check.projectId === normalizeProjectPrefKey(run.runProjectId)) result.saveCheck = check;
|
|
1701
|
+
if (typeof run.saveConfirmedAt === 'string' && Number.isFinite(Date.parse(run.saveConfirmedAt))) result.saveConfirmedAt = run.saveConfirmedAt;
|
|
1702
|
+
return result;
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1619
1705
|
return {
|
|
1706
|
+
pickWritebackRecovery,
|
|
1620
1707
|
DEFAULT_PANEL_STATE,
|
|
1621
1708
|
createSession,
|
|
1622
1709
|
deleteSession,
|
|
@@ -1630,7 +1717,11 @@
|
|
|
1630
1717
|
setActiveSession,
|
|
1631
1718
|
updateActiveSession,
|
|
1632
1719
|
normalizeRuns,
|
|
1720
|
+
normalizeRunStatus,
|
|
1721
|
+
recoverRecordedRunFailure,
|
|
1722
|
+
recoverSettledRunningRun,
|
|
1633
1723
|
normalizeProjectReferenceFiles,
|
|
1724
|
+
normalizeSelectionContext: SelectionContext.normalize,
|
|
1634
1725
|
prepareStateForStorage,
|
|
1635
1726
|
estimateJsonBytes,
|
|
1636
1727
|
computeSafeTaskSummary
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
(function (root, factory) {
|
|
2
|
+
if (typeof module === 'object' && module.exports) module.exports = factory();
|
|
3
|
+
else root.CodexOverleafModuleRegistry.define('SharedSessionBridge', [], factory);
|
|
4
|
+
})(typeof globalThis !== 'undefined' ? globalThis : this, function () {
|
|
5
|
+
'use strict';
|
|
6
|
+
const MESSAGE = 'codex-overleaf/shared-sessions-v1';
|
|
7
|
+
const LOCK_PORT = 'codex-overleaf/shared-session-lock-v1';
|
|
8
|
+
const CHANGE_KEY = 'codex-overleaf-shared-sessions-changed-v1';
|
|
9
|
+
const BASE = Symbol('shared-session-base');
|
|
10
|
+
const failure = (code, message) => Object.assign(new Error(message), { code });
|
|
11
|
+
const clone = value => value == null ? value : JSON.parse(JSON.stringify(value));
|
|
12
|
+
const clean = record => {
|
|
13
|
+
const result = clone(record);
|
|
14
|
+
if (result) delete result.sharedRevision;
|
|
15
|
+
return result;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function createBridge(environment = globalThis) {
|
|
19
|
+
const chromeApi = environment.chrome;
|
|
20
|
+
const clientId = environment.crypto?.randomUUID?.() || 'page-' + Date.now() + '-' + Math.random();
|
|
21
|
+
const migrations = new Map(), baselines = new Map(), heldLocks = new Map();
|
|
22
|
+
let legacy, wrapped;
|
|
23
|
+
function enabled() {
|
|
24
|
+
return Boolean(chromeApi?.runtime?.sendMessage && chromeApi?.runtime?.connect
|
|
25
|
+
&& environment.location?.protocol === 'https:'
|
|
26
|
+
&& ['overleaf.com', 'www.overleaf.com', 'cn.overleaf.com'].includes(environment.location?.hostname)
|
|
27
|
+
&& /^\/project(?:\/|$)/.test(environment.location?.pathname || ''));
|
|
28
|
+
}
|
|
29
|
+
function capture(projectId = '', accountScopeId) {
|
|
30
|
+
const current = environment.codexOverleafDeriveAccountScopeId?.();
|
|
31
|
+
if (!current || (accountScopeId && current !== accountScopeId))
|
|
32
|
+
throw failure('account_scope_unavailable', 'A stable matching Overleaf account is required for shared history.');
|
|
33
|
+
return { accountScopeId: current, projectId };
|
|
34
|
+
}
|
|
35
|
+
function assertScope(value) { capture(value.projectId, value.accountScopeId); }
|
|
36
|
+
const cacheKey = (value, id) => value.accountScopeId + ':' + id;
|
|
37
|
+
const lockKey = (kind, value) => kind === 'preferences' ? 'preferences' : 'state:' + value.accountScopeId;
|
|
38
|
+
async function request(method, value, args = {}) {
|
|
39
|
+
assertScope(value);
|
|
40
|
+
const lock = heldLocks.get(lockKey('state', value));
|
|
41
|
+
if (lock?.lost) throw failure('storage_lock_lost', 'The background storage connection was lost.');
|
|
42
|
+
const response = await chromeApi.runtime.sendMessage({
|
|
43
|
+
...args, type: MESSAGE, method, scope: value, clientId, lockToken: lock?.token || ''
|
|
44
|
+
});
|
|
45
|
+
assertScope(value);
|
|
46
|
+
if (!response?.ok)
|
|
47
|
+
throw failure(response?.error?.code || 'shared_store_unavailable',
|
|
48
|
+
response?.error?.message || 'Shared history is unavailable. Reload the extension and this page.');
|
|
49
|
+
return response.result;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Live ports own the locks. Worker/page termination releases them without
|
|
53
|
+
// allowing a stale client to silently fall back to an origin-local lock.
|
|
54
|
+
async function acquire(kind, value, work) {
|
|
55
|
+
assertScope(value);
|
|
56
|
+
const key = lockKey(kind, value), port = chromeApi.runtime.connect({ name: LOCK_PORT });
|
|
57
|
+
let timer, heartbeat, released = false, lock = null, rejectGrant;
|
|
58
|
+
const granted = new Promise((resolve, reject) => {
|
|
59
|
+
rejectGrant = reject;
|
|
60
|
+
port.onMessage.addListener(message => {
|
|
61
|
+
if (message?.type !== 'granted' || lock || released) return;
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
lock = { token: message.token, lost: false };
|
|
64
|
+
heldLocks.set(key, lock);
|
|
65
|
+
resolve();
|
|
66
|
+
});
|
|
67
|
+
port.onDisconnect.addListener(() => {
|
|
68
|
+
// Read lastError to consume the runtime's disconnected-port warning.
|
|
69
|
+
void chromeApi.runtime.lastError;
|
|
70
|
+
if (lock) lock.lost = true;
|
|
71
|
+
if (!released) reject(failure('storage_lock_lost', 'The shared history lock disconnected.'));
|
|
72
|
+
});
|
|
73
|
+
timer = environment.setTimeout(() => reject(failure('storage_lock_timeout',
|
|
74
|
+
'Another page is saving history. Retry after it finishes.')), 20000);
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
heartbeat = environment.setInterval(() => {
|
|
78
|
+
try { port.postMessage({ type: 'ping' }); }
|
|
79
|
+
catch (_error) {
|
|
80
|
+
if (lock) lock.lost = true;
|
|
81
|
+
rejectGrant(failure('storage_lock_lost', 'The shared history lock disconnected.'));
|
|
82
|
+
}
|
|
83
|
+
}, 15000);
|
|
84
|
+
port.postMessage({ type: 'acquire', kind, scope: value });
|
|
85
|
+
await granted;
|
|
86
|
+
assertScope(value);
|
|
87
|
+
const result = await work();
|
|
88
|
+
assertScope(value);
|
|
89
|
+
if (lock.lost) throw failure('storage_lock_lost', 'The shared history lock was lost before completion.');
|
|
90
|
+
return result;
|
|
91
|
+
} finally {
|
|
92
|
+
released = true;
|
|
93
|
+
environment.clearTimeout(timer);
|
|
94
|
+
environment.clearInterval(heartbeat);
|
|
95
|
+
if (heldLocks.get(key) === lock) heldLocks.delete(key);
|
|
96
|
+
port.disconnect();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function migrate(value) {
|
|
100
|
+
const account = value.accountScopeId;
|
|
101
|
+
if (!migrations.has(account)) {
|
|
102
|
+
const pending = (async () => {
|
|
103
|
+
const status = await request('migration-status', value);
|
|
104
|
+
if (status.complete) return;
|
|
105
|
+
if (!legacy) throw failure('shared_store_unavailable', 'Legacy history storage is not ready.');
|
|
106
|
+
// Read the original site DB once. Only explicitly owned records may
|
|
107
|
+
// cross origins. Unknown-account rows remain untouched for recovery.
|
|
108
|
+
const records = (await legacy.getAllSessions())
|
|
109
|
+
.filter(record => record?.accountScopeId === account && record.projectId && record.id);
|
|
110
|
+
await acquire('state', value, async () => {
|
|
111
|
+
for (const record of records) {
|
|
112
|
+
const recordScope = capture(record.projectId, account);
|
|
113
|
+
await request('import', recordScope, {
|
|
114
|
+
record: legacy.buildSessionRecord(record, { preserveRunActionPayload: true })
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
await request('migration-complete', value);
|
|
118
|
+
});
|
|
119
|
+
})();
|
|
120
|
+
migrations.set(account, pending);
|
|
121
|
+
pending.catch(() => { if (migrations.get(account) === pending) migrations.delete(account); });
|
|
122
|
+
}
|
|
123
|
+
await migrations.get(account);
|
|
124
|
+
assertScope(value);
|
|
125
|
+
}
|
|
126
|
+
async function withLock(kind, input, work) {
|
|
127
|
+
const value = capture(input.projectId, input.accountScopeId);
|
|
128
|
+
await migrate(value); // Before acquiring either lock: no migration/lock cycle.
|
|
129
|
+
return acquire(kind, value, work);
|
|
130
|
+
}
|
|
131
|
+
async function withWrite(value, work) {
|
|
132
|
+
await migrate(value);
|
|
133
|
+
const held = heldLocks.get(lockKey('state', value));
|
|
134
|
+
if (held) {
|
|
135
|
+
if (held.lost) throw failure('storage_lock_lost', 'The shared history lock was lost.');
|
|
136
|
+
return work();
|
|
137
|
+
}
|
|
138
|
+
return acquire('state', value, work);
|
|
139
|
+
}
|
|
140
|
+
function tag(record, value, adopt) {
|
|
141
|
+
if (!record) return record;
|
|
142
|
+
const base = clean(record);
|
|
143
|
+
if (adopt) baselines.set(cacheKey(value, record.id), base);
|
|
144
|
+
Object.defineProperty(record, BASE, { value: base, enumerable: true });
|
|
145
|
+
return record;
|
|
146
|
+
}
|
|
147
|
+
async function list(projectId = '', adopt = true) {
|
|
148
|
+
const value = capture(projectId);
|
|
149
|
+
await migrate(value);
|
|
150
|
+
const result = []; let after = '';
|
|
151
|
+
do {
|
|
152
|
+
const page = await request('list', value, { after });
|
|
153
|
+
for (const record of page.records) {
|
|
154
|
+
result.push(tag(record, value, adopt && !heldLocks.has(lockKey('state', value))));
|
|
155
|
+
}
|
|
156
|
+
after = page.next;
|
|
157
|
+
} while (after);
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
function adopt(records) {
|
|
161
|
+
const value = capture();
|
|
162
|
+
for (const record of records) {
|
|
163
|
+
if (record.accountScopeId === value.accountScopeId)
|
|
164
|
+
baselines.set(cacheKey(value, record.id), clean(record));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function hasLocalChanges(session) {
|
|
168
|
+
const base = baselines.get(cacheKey(capture(), session.id));
|
|
169
|
+
return Boolean(base && (session.updatedAt !== base.updatedAt || session.task !== base.task));
|
|
170
|
+
}
|
|
171
|
+
function wasStored(id) { return baselines.has(cacheKey(capture(), id)); }
|
|
172
|
+
async function put(records, options = {}) {
|
|
173
|
+
if (!records.length) return [];
|
|
174
|
+
const value = capture(records[0].projectId, records[0].accountScopeId);
|
|
175
|
+
if (records.some(record => record.projectId !== value.projectId || record.accountScopeId !== value.accountScopeId))
|
|
176
|
+
throw failure('shared_store_scope_mismatch', 'A session batch must belong to one account and project.');
|
|
177
|
+
return withWrite(value, async () => {
|
|
178
|
+
const entries = records.map(record => ({
|
|
179
|
+
record: clean(record),
|
|
180
|
+
base: record[BASE] || baselines.get(cacheKey(value, record.id)) || null
|
|
181
|
+
}));
|
|
182
|
+
const written = await request('put', value, { entries, reviewRunIds: options.reviewRunIds || [] });
|
|
183
|
+
// Keep the caller's submitted view as its merge baseline. A merged
|
|
184
|
+
// remote change has not necessarily been applied to the visible UI.
|
|
185
|
+
for (const entry of entries) baselines.set(cacheKey(value, entry.record.id), clean(entry.record));
|
|
186
|
+
return written;
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
async function get(id) {
|
|
190
|
+
const value = capture();
|
|
191
|
+
await migrate(value);
|
|
192
|
+
const record = await request('get', value, { id });
|
|
193
|
+
return tag(record, value, !heldLocks.has(lockKey('state', value)));
|
|
194
|
+
}
|
|
195
|
+
async function erase(method, projectId = '', id) {
|
|
196
|
+
const value = capture(projectId);
|
|
197
|
+
return withWrite(value, () => request(method, value, { id }));
|
|
198
|
+
}
|
|
199
|
+
function decorate(api) {
|
|
200
|
+
legacy = api;
|
|
201
|
+
wrapped = { ...api };
|
|
202
|
+
const route = (name, shared) => {
|
|
203
|
+
wrapped[name] = function (...args) {
|
|
204
|
+
return enabled() ? shared(...args) : api[name](...args);
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
route('buildSessionRecord', (input, options) => {
|
|
208
|
+
const record = api.buildSessionRecord(input, options);
|
|
209
|
+
const base = input[BASE] || baselines.get(cacheKey({ accountScopeId: record.accountScopeId }, record.id));
|
|
210
|
+
if (base) Object.defineProperty(record, BASE, { value: clone(base), enumerable: true });
|
|
211
|
+
return record;
|
|
212
|
+
});
|
|
213
|
+
route('getAllSessions', () => list());
|
|
214
|
+
route('getRecord', (store, id) => store === 'sessions' ? get(id) : api.getRecord(store, id));
|
|
215
|
+
route('getAllByIndex', async (store, index, value) => {
|
|
216
|
+
if (store !== 'sessions') return api.getAllByIndex(store, index, value);
|
|
217
|
+
const records = await list(index === 'projectId' ? value : '');
|
|
218
|
+
return records.filter(record => record[index] === value);
|
|
219
|
+
});
|
|
220
|
+
route('claimSessionsForAccount', async (projectId, accountScopeId, deleted = []) => {
|
|
221
|
+
capture(projectId, accountScopeId);
|
|
222
|
+
return (await list(projectId)).filter(record => !deleted.includes(record.id));
|
|
223
|
+
});
|
|
224
|
+
route('putRecord', async (store, record) =>
|
|
225
|
+
store === 'sessions' ? (await put([record]))[0] : api.putRecord(store, record));
|
|
226
|
+
route('putRecords', (store, records, options) =>
|
|
227
|
+
store === 'sessions' ? put(records, options) : api.putRecords(store, records));
|
|
228
|
+
route('deleteRecord', (store, id) =>
|
|
229
|
+
store === 'sessions' ? erase('delete', '', id) : api.deleteRecord(store, id));
|
|
230
|
+
route('deleteByIndex', async (store, index, value) => {
|
|
231
|
+
if (store !== 'sessions') return api.deleteByIndex(store, index, value);
|
|
232
|
+
if (index === 'projectId') return erase('clear-project', value);
|
|
233
|
+
for (const record of (await list()).filter(record => record[index] === value))
|
|
234
|
+
await erase('delete', record.projectId, record.id);
|
|
235
|
+
});
|
|
236
|
+
route('clearStore', store =>
|
|
237
|
+
store === 'sessions' ? erase('clear-account') : api.clearStore(store));
|
|
238
|
+
route('clearAllStores', async () => {
|
|
239
|
+
const value = capture();
|
|
240
|
+
await erase('clear-account');
|
|
241
|
+
// Preserve other accounts' legacy backups. Auxiliary stores remain
|
|
242
|
+
// site-local and retain their existing explicit clear-all semantics.
|
|
243
|
+
for (const record of await api.getAllSessions()) {
|
|
244
|
+
if (record.accountScopeId === value.accountScopeId) await api.deleteRecord('sessions', record.id);
|
|
245
|
+
}
|
|
246
|
+
for (const store of Object.keys(api.STORES)) if (store !== 'sessions') await api.clearStore(store);
|
|
247
|
+
baselines.clear();
|
|
248
|
+
});
|
|
249
|
+
route('listRecentProjectsAcrossAccount', async options => {
|
|
250
|
+
if (!options?.accountScopeId) return [];
|
|
251
|
+
capture('', options.accountScopeId);
|
|
252
|
+
return api.filterRecentProjectsAcrossAccount(await list(), options);
|
|
253
|
+
});
|
|
254
|
+
Object.assign(wrapped, {
|
|
255
|
+
sharedSessionsEnabled: enabled,
|
|
256
|
+
withSharedLock: withLock,
|
|
257
|
+
readSharedProjectSnapshot: projectId => list(projectId, false),
|
|
258
|
+
adoptSharedSessionBaseline: adopt,
|
|
259
|
+
hasUnpersistedSharedSession: hasLocalChanges,
|
|
260
|
+
wasSharedSessionStored: wasStored
|
|
261
|
+
});
|
|
262
|
+
return wrapped;
|
|
263
|
+
}
|
|
264
|
+
function subscribe(listener) {
|
|
265
|
+
if (!enabled() || !chromeApi.storage?.onChanged) return () => {};
|
|
266
|
+
const onChange = (changes, area) => {
|
|
267
|
+
const change = changes[CHANGE_KEY]?.newValue;
|
|
268
|
+
if (area !== 'local' || !change || change.clientId === clientId) return;
|
|
269
|
+
const account = environment.codexOverleafDeriveAccountScopeId?.();
|
|
270
|
+
if (account && change.accountScopeId === account) listener(change);
|
|
271
|
+
};
|
|
272
|
+
chromeApi.storage.onChanged.addListener(onChange);
|
|
273
|
+
return () => chromeApi.storage.onChanged.removeListener(onChange);
|
|
274
|
+
}
|
|
275
|
+
return { enabled, decorate, withLock, subscribe,
|
|
276
|
+
async readMeta(input) {
|
|
277
|
+
const value = capture(input.projectId, input.accountScopeId);
|
|
278
|
+
await migrate(value);
|
|
279
|
+
return request('meta-read', value);
|
|
280
|
+
},
|
|
281
|
+
async writeMeta(input, meta) {
|
|
282
|
+
const value = capture(input.projectId, input.accountScopeId);
|
|
283
|
+
return request('meta-write', value, { meta });
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
return { createBridge, ...createBridge() };
|
|
288
|
+
});
|