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.
- package/README.md +275 -305
- package/README.zh-CN.md +290 -320
- package/extension/bootstrap/background.js +99 -19
- package/extension/bootstrap/manifest.template.json +9 -4
- package/extension/bootstrap/popup.html +11 -16
- package/extension/bootstrap/popupFallback.js +55 -0
- package/extension/bootstrap/update.js +25 -2
- package/extension/bootstrap/updateStatus.js +1 -0
- package/extension/runtime-manifest.json +3 -1
- package/extension/src/background.js +234 -56
- package/extension/src/backgroundBootstrapMigration.js +181 -0
- package/extension/src/backgroundSharedSessions.js +440 -0
- package/extension/src/backgroundUpdateCoordinator.js +541 -381
- package/extension/src/backgroundUpdateSafety.js +173 -0
- package/extension/src/content/activeTurnControl.js +16 -2
- package/extension/src/content/applyResultFormatters.js +46 -73
- package/extension/src/content/assetTransferBroker.js +244 -12
- package/extension/src/content/changeHistoryView.js +175 -0
- package/extension/src/content/composerAttachments.js +117 -67
- package/extension/src/content/composerPanel.js +41 -8
- package/extension/src/content/contentRuntime.js +1084 -1099
- package/extension/src/content/diagnosticsController.js +122 -97
- package/extension/src/content/diagnosticsExport.js +236 -0
- package/extension/src/content/diagnosticsPanel.js +78 -19
- package/extension/src/content/diffReviewPanel.js +8 -5
- package/extension/src/content/directoryCleanupRecovery.js +54 -0
- package/extension/src/content/generated/content.bundle.js +14680 -3606
- package/extension/src/content/generated/content.bundle.meta.json +30 -3
- package/extension/src/content/globalPreferencesController.js +1 -1
- package/extension/src/content/legacyGlobalRegistry.js +25 -1
- package/extension/src/content/localSkillsPanel.js +141 -16
- package/extension/src/content/markdownDomRenderer.js +9 -4
- package/extension/src/content/markdownText.js +5 -6
- package/extension/src/content/modelPicker.js +8 -5
- package/extension/src/content/nativeCompatibilityController.js +45 -20
- package/extension/src/content/otWarmMirror.js +4 -5
- package/extension/src/content/otWarmMirrorController.js +17 -20
- package/extension/src/content/pageBridgeClient.js +33 -5
- package/extension/src/content/panelMaintenance.js +87 -132
- package/extension/src/content/panelRenderer.js +10 -0
- package/extension/src/content/pendingInputView.js +109 -76
- package/extension/src/content/projectProviderSelection.js +13 -4
- package/extension/src/content/projectSessionCleanup.js +109 -62
- package/extension/src/content/projectSettingsCoordinator.js +39 -2
- package/extension/src/content/providerSettingsCoordinator.js +63 -14
- package/extension/src/content/providerSettingsDialog.js +724 -113
- package/extension/src/content/recentProjects.js +21 -6
- package/extension/src/content/runActivitySummary.js +665 -0
- package/extension/src/content/runCompletionMeta.js +344 -0
- package/extension/src/content/runController.js +40 -15
- package/extension/src/content/runFailureNotice.js +34 -12
- package/extension/src/content/runGuidanceController.js +76 -30
- package/extension/src/content/runGuidanceView.js +59 -10
- package/extension/src/content/runPresence.js +306 -0
- package/extension/src/content/runQueueScheduler.js +150 -43
- package/extension/src/content/runRecoveryActions.js +146 -0
- package/extension/src/content/runResultActions.js +11 -8
- package/extension/src/content/runReviewController.js +574 -0
- package/extension/src/content/runScrollLayout.js +21 -2
- package/extension/src/content/runTimelineView.js +315 -290
- package/extension/src/content/scopedPersistencePanelState.js +51 -6
- package/extension/src/content/selectionContextView.js +300 -0
- package/extension/src/content/sensitivePreflight.js +140 -0
- package/extension/src/content/sessionForkController.js +80 -17
- package/extension/src/content/sessionManager.js +1 -1
- package/extension/src/content/sessionPersistence.js +6 -1
- package/extension/src/content/settingsPanel.js +84 -55
- package/extension/src/content/settingsWorkbench.js +379 -0
- package/extension/src/content/sharedSessionViewSync.js +109 -0
- package/extension/src/content/subagentActivityView.js +195 -0
- package/extension/src/content/trackedChangeCaptureController.js +7 -3
- package/extension/src/content/updateIdle.js +4 -1
- package/extension/src/content/updateNotice.js +179 -56
- package/extension/src/content/updateSafetyReceiver.js +58 -0
- package/extension/src/content/writebackController.js +308 -2
- package/extension/src/content/writebackOrchestrator.js +213 -199
- package/extension/src/content/writebackPlan.js +231 -0
- package/extension/src/content/writebackRecovery.js +122 -0
- package/extension/src/content/writingStyleSettings.js +600 -0
- package/extension/src/content/writtenChangesView.js +152 -0
- package/extension/src/page/binaryAssetUploader.js +223 -23
- package/extension/src/page/fileMover.js +256 -0
- package/extension/src/page/overleafProjectSnapshot.js +1 -0
- package/extension/src/page/ownedDirectoryCleanup.js +94 -0
- package/extension/src/page/referenceProjects.js +149 -0
- package/extension/src/page/reviewContext.js +113 -0
- package/extension/src/page/saveState.js +20 -6
- package/extension/src/page/snapshotRouter.js +124 -48
- package/extension/src/page/textCoordinates.js +102 -0
- package/extension/src/page/textFileCreator.js +442 -71
- package/extension/src/page/trackedChangeCapture.js +53 -57
- package/extension/src/page/trackedChangeOwnership.js +216 -0
- package/extension/src/page/trackedChangeReplay.js +184 -0
- package/extension/src/page/trackedChangesLifecycle.js +343 -339
- package/extension/src/page/treeOperations.js +33 -12
- package/extension/src/page/updateSafetyProbe.js +41 -0
- package/extension/src/page/writebackReceiptJournal.js +114 -0
- package/extension/src/page/writebackRouter.js +242 -201
- package/extension/src/pageBridge.js +73 -102
- package/extension/src/popup.js +261 -65
- package/extension/src/shared/agentTranscript.js +41 -4
- package/extension/src/shared/auditRecords.js +73 -0
- package/extension/src/shared/changeHistoryModel.js +94 -0
- package/extension/src/shared/compatibility.js +22 -6
- package/extension/src/shared/compileAdapter.js +101 -37
- package/extension/src/shared/composerAttachmentDraft.js +151 -0
- package/extension/src/shared/directoryCleanupProof.js +43 -0
- package/extension/src/shared/failureReasons.js +329 -3
- package/extension/src/shared/globalPreferences.js +31 -14
- package/extension/src/shared/governanceRules.js +4 -37
- package/extension/src/shared/i18n.js +389 -25
- package/extension/src/shared/managedUpdateProjection.js +8 -5
- package/extension/src/shared/nativeRequestIdentity.js +1 -0
- package/extension/src/shared/pageRpcContract.js +9 -2
- package/extension/src/shared/projectFiles.js +21 -44
- package/extension/src/shared/providerProfiles.js +114 -3
- 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/runInputQueue.js +48 -5
- package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
- package/extension/src/shared/selectionContext.js +37 -0
- package/extension/src/shared/sessionState.js +166 -30
- package/extension/src/shared/settlementFacts.js +10 -2
- package/extension/src/shared/sharedSessionBridge.js +311 -0
- package/extension/src/shared/sharedSessionTransfer.js +140 -0
- package/extension/src/shared/staleGuard.js +118 -13
- package/extension/src/shared/storageDb.js +77 -78
- package/extension/src/shared/storageMigration.js +74 -111
- package/extension/src/shared/storageRunActions.js +211 -22
- package/extension/src/shared/storageValuePruning.js +40 -0
- package/extension/src/shared/subagentActivityModel.js +174 -0
- package/extension/src/shared/undoOperations.js +216 -6
- package/extension/src/shared/updateConsent.js +42 -11
- package/extension/src/shared/updateRuntimeIdentity.js +1 -1
- package/extension/src/shared/writebackIntent.js +78 -0
- package/extension/src/shared/writebackOperationEvidence.js +4 -15
- package/extension/src/shared/writebackSettlement.js +67 -48
- package/extension/src/shared/writingStyle.js +33 -0
- package/extension/styles/panel.css +1987 -385
- package/extension/styles/popup.css +110 -0
- package/native-host/src/anthropicBridgeRequest.js +6 -3
- package/native-host/src/anthropicBridgeResponse.js +6 -2
- package/native-host/src/anthropicMessagesBridge.js +24 -16
- package/native-host/src/bootstrapMigration.js +296 -0
- package/native-host/src/bootstrapMigrationContract.js +101 -0
- package/native-host/src/bootstrapUpdate.js +233 -0
- package/native-host/src/bootstrapUpdateWatchdog.js +44 -0
- package/native-host/src/chatBridgeResponse.js +10 -0
- package/native-host/src/chatCompletionsBridge.js +21 -15
- package/native-host/src/codexConfigPaths.js +106 -0
- package/native-host/src/codexHome.js +66 -73
- package/native-host/src/codexHomeScope.js +124 -0
- package/native-host/src/codexInheritedAuth.js +90 -0
- package/native-host/src/codexLocalSkills.js +301 -0
- package/native-host/src/codexModelRecovery.js +107 -0
- package/native-host/src/codexPromptAssembly.js +33 -12
- package/native-host/src/codexProviderLaunch.js +3 -3
- package/native-host/src/codexProviderTest.js +24 -26
- package/native-host/src/codexRuntimeIdentity.js +1 -0
- package/native-host/src/codexSessionRunner.js +211 -318
- package/native-host/src/codexSessionTiming.js +21 -8
- package/native-host/src/codexSkillIsolation.js +170 -0
- package/native-host/src/codexThreadFork.js +19 -3
- package/native-host/src/index.js +19 -7
- package/native-host/src/managedInstall.js +115 -39
- package/native-host/src/managedInstallRecovery.js +140 -0
- package/native-host/src/managedRuntimeEvidence.js +57 -0
- package/native-host/src/mirrorWorkspace.js +92 -22
- package/native-host/src/nativeDoctor.js +15 -0
- package/native-host/src/nativeEnvironment.js +70 -0
- package/native-host/src/nativeHelperLifecycle.js +21 -0
- package/native-host/src/nativeHostRegistration.js +33 -0
- package/native-host/src/nativeQuotas.js +15 -8
- package/native-host/src/nativeRunLifecycle.js +71 -0
- package/native-host/src/overleafWorkspaceRules.js +16 -0
- package/native-host/src/processStopBarrier.js +115 -0
- package/native-host/src/projectPathPlatform.js +30 -0
- package/native-host/src/providerHttp.js +80 -0
- package/native-host/src/providerModelCatalog.js +4 -3
- package/native-host/src/providerProfile.js +17 -3
- package/native-host/src/providerReasoning.js +10 -11
- package/native-host/src/providerRuntime.js +1 -0
- package/native-host/src/providerStore.js +76 -14
- package/native-host/src/releaseTransport.js +14 -5
- package/native-host/src/responsesPassthroughBridge.js +266 -52
- package/native-host/src/runtimeInstaller.js +21 -1
- package/native-host/src/selectionScope.js +86 -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/subagentAdmission.js +26 -0
- package/native-host/src/subagentBroker.js +176 -159
- package/native-host/src/subagentTelemetry.js +325 -0
- package/native-host/src/subagentWorkspace.js +103 -0
- package/native-host/src/subagentWorkspacePath.js +34 -0
- package/native-host/src/taskRunnerRuntime.js +130 -57
- package/native-host/src/tomlStatements.js +140 -0
- package/native-host/src/turnAttachments.js +113 -0
- package/native-host/src/updateManager.js +406 -38
- 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 +475 -0
- package/native-host/src/writingStyleStore.js +73 -0
- package/package.json +1 -1
- package/scripts/install-managed.mjs +1 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
(function initUndoOperations(root, factory) {
|
|
2
2
|
if (typeof module === 'object' && module.exports) {
|
|
3
|
-
module.exports = factory();
|
|
3
|
+
module.exports = factory(require('./staleGuard'));
|
|
4
4
|
} else {
|
|
5
|
-
root.CodexOverleafUndoOperations = factory();
|
|
5
|
+
root.CodexOverleafUndoOperations = factory(root.CodexOverleafStaleGuard);
|
|
6
6
|
}
|
|
7
|
-
})(typeof globalThis !== 'undefined' ? globalThis : window, function undoOperationsFactory() {
|
|
7
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window, function undoOperationsFactory(StaleGuard) {
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
function buildUndoOperations(project, appliedOperations) {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
const sourceFilesByPath = new Map(workingFilesByPath);
|
|
18
19
|
const undo = [];
|
|
19
20
|
const fullRestoreEditPaths = new Set();
|
|
20
21
|
|
|
@@ -29,7 +30,8 @@
|
|
|
29
30
|
}
|
|
30
31
|
const currentBeforeEdit = workingFilesByPath.get(operation.path);
|
|
31
32
|
if (!fullRestoreEditPaths.has(operation.path)) {
|
|
32
|
-
const inversePatches = buildInverseTextPatches(
|
|
33
|
+
const inversePatches = buildInverseTextPatches(sourceFilesByPath.get(operation.path), operation.patches,
|
|
34
|
+
operation.verifiedContent, operation.path);
|
|
33
35
|
if (inversePatches.length) {
|
|
34
36
|
undo.push(normalizeUndoOperation({
|
|
35
37
|
type: 'edit',
|
|
@@ -70,10 +72,13 @@
|
|
|
70
72
|
if (!operation.path || !operation.to) {
|
|
71
73
|
continue;
|
|
72
74
|
}
|
|
75
|
+
if (operation.moveProof && !operation.moveProof.targetEntityId) continue;
|
|
73
76
|
undo.push(normalizeUndoOperation({
|
|
74
77
|
type: 'move',
|
|
75
78
|
path: operation.to,
|
|
76
79
|
to: operation.path,
|
|
80
|
+
...(operation.moveProof ? { moveProof: { ...operation.moveProof,
|
|
81
|
+
sourceEntityId: operation.moveProof.targetEntityId, targetEntityId: operation.moveProof.sourceEntityId } } : {}),
|
|
77
82
|
reason: 'Undo move'
|
|
78
83
|
}));
|
|
79
84
|
} else if (operation.type === 'delete') {
|
|
@@ -89,12 +94,13 @@
|
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
applyOperationToFiles(workingFilesByPath, operation);
|
|
97
|
+
applyOperationToFiles(sourceFilesByPath, { ...operation, verifiedContent: undefined });
|
|
92
98
|
}
|
|
93
99
|
|
|
94
100
|
return undo.reverse();
|
|
95
101
|
}
|
|
96
102
|
|
|
97
|
-
function buildInverseTextPatches(textBeforeEdit, patches) {
|
|
103
|
+
function buildInverseTextPatches(textBeforeEdit, patches, verifiedContent, path) {
|
|
98
104
|
if (!Array.isArray(patches) || !patches.length) {
|
|
99
105
|
return [];
|
|
100
106
|
}
|
|
@@ -108,7 +114,7 @@
|
|
|
108
114
|
}
|
|
109
115
|
|
|
110
116
|
let offset = 0;
|
|
111
|
-
|
|
117
|
+
const inverse = normalized.patches.map(patch => {
|
|
112
118
|
const from = patch.from + offset;
|
|
113
119
|
const to = from + patch.insert.length;
|
|
114
120
|
offset += patch.insert.length - (patch.to - patch.from);
|
|
@@ -119,6 +125,41 @@
|
|
|
119
125
|
insert: patch.expected
|
|
120
126
|
};
|
|
121
127
|
});
|
|
128
|
+
if (typeof verifiedContent !== 'string' || verifiedContent === applied.text) return inverse;
|
|
129
|
+
// The stored checkpoint uses the verified editor post-image. Its inverse
|
|
130
|
+
// must use those same offsets, while Native patches retain their source
|
|
131
|
+
// representation for later operations in the batch.
|
|
132
|
+
const prepared = StaleGuard.prepareOperationPatches({ type: 'edit', path, patches: inverse }, verifiedContent,
|
|
133
|
+
StaleGuard.buildBaseFileLookup([{ path, content: applied.text }]));
|
|
134
|
+
return prepared.ok && applyTextPatches(verifiedContent, prepared.patches).ok ? prepared.patches : [];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function selectExpectedFilesForTrackedUndo(project, operations = [], trackedChanges = [], previousExpectedFiles = []) {
|
|
138
|
+
const paths = new Set();
|
|
139
|
+
for (const change of trackedChanges || []) if (change?.path) paths.add(change.path);
|
|
140
|
+
for (const operation of operations || []) {
|
|
141
|
+
if (operation?.path) paths.add(operation.path);
|
|
142
|
+
if (operation?.to) paths.add(operation.to);
|
|
143
|
+
}
|
|
144
|
+
const expectedByPath = new Map();
|
|
145
|
+
for (const file of previousExpectedFiles || []) {
|
|
146
|
+
if (paths.has(file?.path) && typeof file?.content === 'string' && !expectedByPath.has(file.path)) {
|
|
147
|
+
expectedByPath.set(file.path, { path: file.path, content: file.content });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Reconstruct the pre-image with the same inverse patches as plain Undo.
|
|
151
|
+
// This preserves the editor's unchanged line endings and collaborator
|
|
152
|
+
// content, including when the ZIP baseline used a different representation.
|
|
153
|
+
const hasVerifiedPatches = operations.some(operation => typeof operation?.verifiedContent === 'string'
|
|
154
|
+
&& Array.isArray(operation.patches) && operation.patches.length);
|
|
155
|
+
const checkpoint = hasVerifiedPatches ? buildUndoCheckpoint(project, operations) : null;
|
|
156
|
+
const restored = checkpoint ? buildExpectedFilesAfterOperations({ files: checkpoint.undoBaseFiles }, checkpoint.undoOperations) : new Map();
|
|
157
|
+
for (const file of project?.files || []) {
|
|
158
|
+
if (paths.has(file?.path) && typeof file?.content === 'string' && !expectedByPath.has(file.path)) {
|
|
159
|
+
expectedByPath.set(file.path, { path: file.path, content: restored.get(file.path) ?? file.content });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return Array.from(expectedByPath.values());
|
|
122
163
|
}
|
|
123
164
|
|
|
124
165
|
function buildUndoCheckpoint(project, appliedOperations) {
|
|
@@ -130,6 +171,166 @@
|
|
|
130
171
|
};
|
|
131
172
|
}
|
|
132
173
|
|
|
174
|
+
// File creation has its own inverse even when text edits use Reviewing.
|
|
175
|
+
// Store post-images, never infer an empty pre-image for a missing file.
|
|
176
|
+
function buildCreatedFileUndoCheckpoint(project, appliedOperations, previous = {}) {
|
|
177
|
+
const originalPaths = new Set((project?.files || []).map(file => file?.path));
|
|
178
|
+
const priorFiles = filesListToMap(previous.undoBaseFiles);
|
|
179
|
+
const created = new Map();
|
|
180
|
+
for (const operation of previous.undoOperations || []) {
|
|
181
|
+
const proof = operation?.undoCreatedFile;
|
|
182
|
+
if (operation?.type !== 'delete' || proof?.v !== 1) continue;
|
|
183
|
+
if (proof.kind === 'text' && priorFiles.has(operation.path)) {
|
|
184
|
+
created.set(operation.path, { kind: 'text', content: priorFiles.get(operation.path), createdDirectories: proof.createdDirectories });
|
|
185
|
+
} else if (proof.kind === 'binary' && /^[a-f0-9]{64}$/i.test(proof.sha256 || '')) {
|
|
186
|
+
created.set(operation.path, { kind: 'binary', sha256: proof.sha256.toLowerCase(), createdDirectories: proof.createdDirectories });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
for (const operation of appliedOperations || []) {
|
|
190
|
+
if (!operation?.path) continue;
|
|
191
|
+
const path = operation.path;
|
|
192
|
+
if (operation.type === 'create' || operation.type === 'binary-create') {
|
|
193
|
+
if (originalPaths.has(path) && !created.has(path)) continue;
|
|
194
|
+
if (operation.type === 'create' && typeof operation.content === 'string') {
|
|
195
|
+
created.set(path, { kind: 'text', content: typeof operation.verifiedContent === 'string'
|
|
196
|
+
? operation.verifiedContent : operation.content, createdDirectories: operation.createdDirectories });
|
|
197
|
+
} else {
|
|
198
|
+
const hash = operation.sha256 || operation.assetRef?.sha256;
|
|
199
|
+
if (operation.previousExists !== true && /^[a-f0-9]{64}$/i.test(hash || '')) {
|
|
200
|
+
created.set(path, { kind: 'binary', sha256: hash.toLowerCase(), createdDirectories: operation.createdDirectories });
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
} else if (operation.type === 'edit' && created.get(path)?.kind === 'text') {
|
|
204
|
+
const files = new Map([[path, created.get(path).content]]);
|
|
205
|
+
applyOperationToFiles(files, operation);
|
|
206
|
+
created.set(path, { ...created.get(path), kind: 'text', content: files.get(path) });
|
|
207
|
+
} else if (['delete', 'rename', 'move', 'overwrite-binary'].includes(operation.type)) {
|
|
208
|
+
// Existing rename/overwrite recovery retains ownership of these cases.
|
|
209
|
+
created.delete(path);
|
|
210
|
+
if (operation.to) created.delete(operation.to);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const undoBaseFiles = [], undoOperations = [];
|
|
214
|
+
for (const [path, proof] of Array.from(created).reverse()) {
|
|
215
|
+
const undoCreatedFile = proof.kind === 'binary'
|
|
216
|
+
? { v: 1, kind: 'binary', sha256: proof.sha256 } : { v: 1, kind: 'text' };
|
|
217
|
+
if (Array.isArray(proof.createdDirectories) && proof.createdDirectories.length) {
|
|
218
|
+
undoCreatedFile.createdDirectories = proof.createdDirectories.map(item => ({ ...item }));
|
|
219
|
+
}
|
|
220
|
+
undoOperations.push({ ...normalizeUndoOperation({ type: 'delete', path, reason: 'Undo create' }), undoCreatedFile });
|
|
221
|
+
if (proof.kind === 'text') undoBaseFiles.push({ path, content: proof.content });
|
|
222
|
+
}
|
|
223
|
+
// Reviewing has no text insertion/deletion refs for a native metadata move.
|
|
224
|
+
// Keep its identity-bound inverse with the other file-level proofs.
|
|
225
|
+
undoOperations.push(...buildUndoOperations(project, appliedOperations).filter(operation => operation.type === 'move' && operation.moveProof));
|
|
226
|
+
return { undoOperations, undoBaseFiles };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function isFileUndoOperation(operation) {
|
|
230
|
+
return operation?.undoCreatedFile?.v === 1
|
|
231
|
+
|| (operation?.type === 'move' && operation.moveProof?.v === 1)
|
|
232
|
+
|| (operation?.type === 'create' && typeof operation.content === 'string');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// A deleted original has no editor post-image. Its inverse is a guarded
|
|
236
|
+
// file creation, backed by both the forward delete and the captured original.
|
|
237
|
+
// This also recovers older Track-on records that omitted that inverse.
|
|
238
|
+
function getFileUndoOperations(run = {}) {
|
|
239
|
+
const operations = (run.undoOperations || []).filter(isFileUndoOperation);
|
|
240
|
+
const before = filesListToMap(run.undoExpectedFiles);
|
|
241
|
+
const after = buildExpectedFilesAfterOperations({ files: run.undoExpectedFiles }, run.appliedOperations);
|
|
242
|
+
const deleted = new Set((run.appliedOperations || []).filter(operation => operation?.type === 'delete'
|
|
243
|
+
&& before.has(operation.path) && !after.has(operation.path)).map(operation => operation.path));
|
|
244
|
+
return [...operations.filter(operation => !deleted.has(operation.path)), ...Array.from(deleted, path =>
|
|
245
|
+
normalizeUndoOperation({ type: 'create', path, content: before.get(path), reason: 'Undo delete' }))];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function prepareRunUndo(run = {}) {
|
|
249
|
+
const files = getFileUndoOperations(run);
|
|
250
|
+
const restored = new Set(files.filter(operation => operation.type === 'create').map(operation => operation.path));
|
|
251
|
+
const pending = [...files], operations = [];
|
|
252
|
+
for (const operation of run.undoOperations || []) {
|
|
253
|
+
if (isFileUndoOperation(operation)) {
|
|
254
|
+
const index = pending.findIndex(file => file.path === operation.path && file.type === operation.type);
|
|
255
|
+
if (index >= 0) operations.push(...pending.splice(index, 1));
|
|
256
|
+
} else if (!restored.has(operation.path)) operations.push(operation);
|
|
257
|
+
}
|
|
258
|
+
return { ...run, undoOperations: [...operations, ...pending] };
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function textUndoRun(run = {}) {
|
|
262
|
+
const restored = new Set(getFileUndoOperations(run).flatMap(operation => operation.type === 'create' ? [operation.path]
|
|
263
|
+
: operation.type === 'move' ? [operation.path, operation.to] : []));
|
|
264
|
+
return { ...run,
|
|
265
|
+
undoExpectedFiles: (run.undoExpectedFiles || []).filter(file => !restored.has(file.path)),
|
|
266
|
+
undoTrackedChanges: (run.undoTrackedChanges || []).filter(ref => !restored.has(ref.path))
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function mergeFileUndoResult(textResult, fileResult, operations) {
|
|
271
|
+
const applied = [...(textResult.applied || []), ...(fileResult.applied || [])];
|
|
272
|
+
const skipped = [...(textResult.skipped || []), ...(fileResult.skipped || [])];
|
|
273
|
+
for (const operation of operations) {
|
|
274
|
+
if (!(fileResult.applied || []).some(entry => entry.operation?.path === operation.path
|
|
275
|
+
&& entry.operation?.type === operation.type && entry.result?.ok === true && entry.result?.verified === true
|
|
276
|
+
&& entry.result.verification === 'overleaf-zip')
|
|
277
|
+
&& !(fileResult.skipped || []).some(entry => entry.operation?.path === operation.path)) {
|
|
278
|
+
skipped.push({ operation, result: { ok: false, code: 'undo_operation_failed',
|
|
279
|
+
reason: 'The file restoration has no verified server receipt.' } });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return { ...textResult, ok: textResult.ok !== false && fileResult.ok !== false && !skipped.length, applied, skipped };
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Consume only independently verified rollback receipts. Forward writes
|
|
286
|
+
// remain audit evidence; recovery arrays describe only unfinished work.
|
|
287
|
+
function advanceUndoCheckpoint(run = {}, result = {}, verifyText = () => false) {
|
|
288
|
+
const operations = Array.isArray(run?.undoOperations) ? run.undoOperations : [];
|
|
289
|
+
const applied = Array.isArray(result.applied) ? result.applied : [];
|
|
290
|
+
const skipped = Array.isArray(result.skipped) ? result.skipped : [];
|
|
291
|
+
const failed = path => skipped.some(entry => {
|
|
292
|
+
const target = entry?.operation?.path || entry?.trackedChange?.path || entry?.result?.failure?.file;
|
|
293
|
+
return !target || target === path;
|
|
294
|
+
});
|
|
295
|
+
if (result.failure || result.error) return run;
|
|
296
|
+
const textPaths = new Set((run.undoExpectedFiles || [])
|
|
297
|
+
.filter(file => file?.path && typeof file.content === 'string' && !failed(file.path)
|
|
298
|
+
&& typeof verifyText === 'function' && verifyText(file) === true)
|
|
299
|
+
.map(file => file.path));
|
|
300
|
+
const deletedPaths = new Set(operations.filter(operation => operation?.type === 'delete'
|
|
301
|
+
&& operation.undoCreatedFile?.v === 1 && !failed(operation.path)
|
|
302
|
+
&& applied.some(entry => entry?.operation?.type === 'delete' && entry.operation.path === operation.path
|
|
303
|
+
&& JSON.stringify(entry.operation.undoCreatedFile) === JSON.stringify(operation.undoCreatedFile)
|
|
304
|
+
&& entry.result?.ok === true && entry.result.verified === true
|
|
305
|
+
&& entry.result.verification === 'overleaf-zip')).map(operation => operation.path));
|
|
306
|
+
const restoredPaths = new Set(operations.filter(operation => operation?.type === 'create'
|
|
307
|
+
&& !failed(operation.path) && applied.some(entry => entry?.operation?.type === 'create'
|
|
308
|
+
&& entry.operation.path === operation.path && entry.operation.content === operation.content
|
|
309
|
+
&& entry.result?.ok === true && entry.result.verified === true
|
|
310
|
+
&& entry.result.verification === 'overleaf-zip')).map(operation => operation.path));
|
|
311
|
+
const movedPaths = new Set(operations.filter(operation => operation?.type === 'move' && operation.moveProof?.v === 1
|
|
312
|
+
&& !failed(operation.path) && applied.some(entry => entry?.operation?.type === 'move'
|
|
313
|
+
&& entry.operation.path === operation.path && entry.operation.to === operation.to
|
|
314
|
+
&& JSON.stringify(entry.operation.moveProof) === JSON.stringify(operation.moveProof)
|
|
315
|
+
&& entry.result?.ok === true && entry.result.verified === true && entry.result.verification === 'overleaf-zip'))
|
|
316
|
+
.flatMap(operation => [operation.path, operation.to]));
|
|
317
|
+
for (const path of restoredPaths) textPaths.add(path);
|
|
318
|
+
for (const path of movedPaths) textPaths.add(path);
|
|
319
|
+
if (!textPaths.size && !deletedPaths.size) return run;
|
|
320
|
+
const pending = operations.filter(operation => !restoredPaths.has(operation.path) && !(operation?.type === 'edit' && textPaths.has(operation.path))
|
|
321
|
+
&& !(operation?.type === 'move' && movedPaths.has(operation.path))
|
|
322
|
+
&& !(operation?.type === 'delete' && operation.undoCreatedFile?.v === 1 && deletedPaths.has(operation.path)));
|
|
323
|
+
const needed = new Set(pending.flatMap(operation => [operation?.path, operation?.to]).filter(Boolean));
|
|
324
|
+
return { ...run,
|
|
325
|
+
undoOperations: pending,
|
|
326
|
+
undoBaseFiles: (run.undoBaseFiles || []).filter(file => needed.has(file?.path)
|
|
327
|
+
|| (!textPaths.has(file?.path) && !deletedPaths.has(file?.path))),
|
|
328
|
+
undoExpectedFiles: (run.undoExpectedFiles || []).filter(file => !textPaths.has(file?.path)),
|
|
329
|
+
undoTrackedChanges: (run.undoTrackedChanges || []).filter(ref => !textPaths.has(ref?.path)),
|
|
330
|
+
trackedChangeCaptures: (run.trackedChangeCaptures || []).filter(capture => !textPaths.has(capture?.path))
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
133
334
|
function buildSnapshotRestoreUndo(run = {}) {
|
|
134
335
|
const undoOperations = Array.isArray(run.undoOperations) ? run.undoOperations : [];
|
|
135
336
|
const originalByPath = buildOriginalFilesForSnapshotUndo(run, undoOperations);
|
|
@@ -311,6 +512,7 @@
|
|
|
311
512
|
insert: String(patch.insert ?? '')
|
|
312
513
|
}));
|
|
313
514
|
}
|
|
515
|
+
if (operation.type === 'move' && operation.moveProof?.v === 1) normalized.moveProof = JSON.parse(JSON.stringify(operation.moveProof));
|
|
314
516
|
return normalized;
|
|
315
517
|
}
|
|
316
518
|
|
|
@@ -369,9 +571,17 @@
|
|
|
369
571
|
}
|
|
370
572
|
|
|
371
573
|
return {
|
|
574
|
+
isFileUndoOperation,
|
|
575
|
+
getFileUndoOperations,
|
|
576
|
+
prepareRunUndo,
|
|
577
|
+
textUndoRun,
|
|
578
|
+
mergeFileUndoResult,
|
|
372
579
|
buildUndoCheckpoint,
|
|
580
|
+
buildCreatedFileUndoCheckpoint,
|
|
581
|
+
advanceUndoCheckpoint,
|
|
373
582
|
buildExpectedFilesAfterOperations,
|
|
374
583
|
buildUndoOperations,
|
|
584
|
+
selectExpectedFilesForTrackedUndo,
|
|
375
585
|
buildSnapshotRestoreUndo
|
|
376
586
|
};
|
|
377
587
|
});
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
'idle',
|
|
14
14
|
'checking',
|
|
15
15
|
'update_available',
|
|
16
|
+
'manual_install_required',
|
|
16
17
|
'downloading',
|
|
17
18
|
'staged',
|
|
18
19
|
'waiting_for_idle',
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
idle: { value: 0, determinate: true, phase: 'idle' },
|
|
42
43
|
checking: { value: 0, determinate: false, phase: 'checking' },
|
|
43
44
|
update_available: { value: 0, determinate: true, phase: 'available' },
|
|
45
|
+
manual_install_required: { value: 0, determinate: true, phase: 'manual' },
|
|
44
46
|
downloading: { value: 35, determinate: false, phase: 'downloading' },
|
|
45
47
|
staged: { value: 65, determinate: true, phase: 'staged' },
|
|
46
48
|
waiting_for_idle: { value: 65, determinate: true, phase: 'waiting' },
|
|
@@ -66,6 +68,9 @@
|
|
|
66
68
|
blocker: blockers[0] || '',
|
|
67
69
|
blockers,
|
|
68
70
|
transactionId: safeId(value.transactionId),
|
|
71
|
+
operationId: safeId(value.operationId),
|
|
72
|
+
cancelRequested: value.cancelRequested === true,
|
|
73
|
+
recoveryPending: value.recoveryPending === true,
|
|
69
74
|
initiatedBy: ['automatic', 'manual'].includes(value.initiatedBy) ? value.initiatedBy : '',
|
|
70
75
|
lastCheckedAt: finiteNumber(value.lastCheckedAt),
|
|
71
76
|
stagedAt: finiteNumber(value.stagedAt),
|
|
@@ -73,11 +78,24 @@
|
|
|
73
78
|
deadlineAt: finiteNumber(value.deadlineAt),
|
|
74
79
|
heartbeatAt: finiteNumber(value.heartbeatAt),
|
|
75
80
|
postponeUntil: finiteNumber(value.postponeUntil),
|
|
81
|
+
cooldownUntil: finiteNumber(value.cooldownUntil),
|
|
76
82
|
code: safeToken(value.code),
|
|
77
|
-
message: String(value.message || '').replace(/\s+/g, ' ').trim().slice(0, 300)
|
|
83
|
+
message: String(value.message || '').replace(/\s+/g, ' ').trim().slice(0, 300),
|
|
84
|
+
manualReason: normalizeManualReason(value.manualReason)
|
|
78
85
|
};
|
|
79
86
|
}
|
|
80
87
|
|
|
88
|
+
// Signed per-locale reason a release needs a one-time reinstall.
|
|
89
|
+
function normalizeManualReason(value) {
|
|
90
|
+
if (!value || typeof value !== 'object') return {};
|
|
91
|
+
const out = {};
|
|
92
|
+
for (const locale of ['en', 'zh']) {
|
|
93
|
+
const text = String(value[locale] || '').replace(/\s+/g, ' ').trim().slice(0, 400);
|
|
94
|
+
if (text) out[locale] = text;
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
|
|
81
99
|
function normalizeConsentState(value = {}) {
|
|
82
100
|
return {
|
|
83
101
|
schemaVersion: 1,
|
|
@@ -101,11 +119,19 @@
|
|
|
101
119
|
const state = normalizeUpdateState(updateValue, options.currentVersion);
|
|
102
120
|
const consent = normalizeConsentState(consentValue);
|
|
103
121
|
const newer = compareStableVersions(state.latestVersion, state.currentVersion) > 0;
|
|
104
|
-
const snoozed = newer &&
|
|
105
|
-
consent.snoozedVersion === state.latestVersion &&
|
|
106
|
-
consent.snoozedUntil > now;
|
|
107
122
|
const execution = EXECUTION_STATES.has(state.state);
|
|
108
123
|
const available = state.state === 'update_available' && newer;
|
|
124
|
+
// A newer release that only a reinstall can apply. It is shown even after
|
|
125
|
+
// an automatic check, because no Update now button can ever resolve it.
|
|
126
|
+
// Compare with the running version: after the reinstall the stored state
|
|
127
|
+
// still names the old one, and the notice must clear by itself.
|
|
128
|
+
const runningVersion = safeVersion(options.currentVersion) || state.currentVersion;
|
|
129
|
+
const manualInstall = state.state === 'manual_install_required'
|
|
130
|
+
&& (compareStableVersions(state.latestVersion, runningVersion) > 0
|
|
131
|
+
|| (state.code === 'prerelease_promotion_requires_manual_update'
|
|
132
|
+
&& state.latestVersion === runningVersion));
|
|
133
|
+
const snoozed = (newer || manualInstall) &&
|
|
134
|
+
consent.snoozedVersion === state.latestVersion && consent.snoozedUntil > now;
|
|
109
135
|
const progress = getProgressModel(state);
|
|
110
136
|
const quietFailure = state.state === 'failed' &&
|
|
111
137
|
state.initiatedBy !== 'manual' &&
|
|
@@ -124,16 +150,21 @@
|
|
|
124
150
|
},
|
|
125
151
|
progress,
|
|
126
152
|
available,
|
|
153
|
+
manualInstall,
|
|
127
154
|
snoozed,
|
|
128
155
|
execution,
|
|
129
|
-
showPanel:
|
|
130
|
-
|
|
131
|
-
|
|
156
|
+
showPanel: state.cancelRequested || state.recoveryPending
|
|
157
|
+
|| (state.state === 'checking' && state.initiatedBy === 'manual')
|
|
158
|
+
|| ((available || manualInstall) && !snoozed) || execution || state.state === 'rolled_back' || visibleFailure,
|
|
159
|
+
badge: getBadge(state, { available: available || manualInstall, snoozed }),
|
|
132
160
|
actions: {
|
|
133
|
-
check: ['idle', 'committed', 'rolled_back', 'failed'].includes(state.state),
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
161
|
+
check: !state.cancelRequested && !state.recoveryPending && ['idle', 'committed', 'rolled_back', 'failed', 'manual_install_required'].includes(state.state),
|
|
162
|
+
copyInstall: manualInstall,
|
|
163
|
+
install: available && !state.cancelRequested && !state.recoveryPending,
|
|
164
|
+
later: !state.recoveryPending && (available || manualInstall || ['staged', 'waiting_for_idle'].includes(state.state)),
|
|
165
|
+
cancel: !state.recoveryPending && (state.cancelRequested || ['checking', 'downloading', 'staged', 'waiting_for_idle'].includes(state.state)),
|
|
166
|
+
recover: state.recoveryPending,
|
|
167
|
+
retry: !state.cancelRequested && !state.recoveryPending && ['failed', 'rolled_back'].includes(state.state)
|
|
137
168
|
}
|
|
138
169
|
};
|
|
139
170
|
}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
if (!status.managed || !result.installedVersion || !result.nativeVersion ||
|
|
19
19
|
!result.extensionVersion || !result.runtimeVersion) return result;
|
|
20
20
|
if (['authorized', 'bound'].includes(status.authorization?.state) ||
|
|
21
|
-
['staged', 'activation_pending', 'applying', 'awaiting_health'].includes(status.transaction?.state)) {
|
|
21
|
+
['staged', 'activation_pending', 'applying', 'bootstrap_pending', 'bootstrap_rolling_back', 'awaiting_health', 'rolling_back'].includes(status.transaction?.state)) {
|
|
22
22
|
return { ...result, state: 'transaction_active' };
|
|
23
23
|
}
|
|
24
24
|
if (status.installedAligned !== true) return { ...result, state: 'repair_required' };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
(function (root, factory) {
|
|
2
|
+
if (typeof module === 'object' && module.exports) module.exports = factory(require('./undoOperations'));
|
|
3
|
+
else root.CodexOverleafModuleRegistry.define('WritebackIntent', ['UndoOperations'], factory);
|
|
4
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window, function (Undo) {
|
|
5
|
+
'use strict';
|
|
6
|
+
const MAX_BYTES = 300 * 1024;
|
|
7
|
+
const types = new Set(['edit', 'create', 'delete', 'rename', 'move', 'binary-create', 'overwrite-binary']);
|
|
8
|
+
const path = value => typeof value === 'string' && value && !value.startsWith('/')
|
|
9
|
+
&& !/^[A-Za-z]:/.test(value) && !value.replace(/\\/g, '/').split('/').some(part => !part || part === '.' || part === '..');
|
|
10
|
+
function normalize(value) {
|
|
11
|
+
if (!value || typeof value !== 'object' || !value.id || !value.projectId || !value.accountScopeId
|
|
12
|
+
|| !value.sessionId || !value.runId || !Array.isArray(value.operations) || value.operations.length > 100) return null;
|
|
13
|
+
const operations = [];
|
|
14
|
+
for (const input of value.operations) {
|
|
15
|
+
if (!types.has(input?.type) || !path(input.path) || (input.to && !path(input.to))) return null;
|
|
16
|
+
const op = { type: input.type, path: input.path };
|
|
17
|
+
for (const key of ['to', 'content', 'replaceAll', 'find', 'replace', 'sha256', 'mimeType']) {
|
|
18
|
+
if (typeof input[key] === 'string') op[key] = input[key];
|
|
19
|
+
}
|
|
20
|
+
if (Number.isSafeInteger(input.size)) op.size = input.size;
|
|
21
|
+
if (input.moveProof !== undefined) {
|
|
22
|
+
const proof = input.moveProof;
|
|
23
|
+
if (input.type !== 'move' || proof?.v !== 1 || !['text', 'binary'].includes(proof.kind)
|
|
24
|
+
|| !/^[a-f0-9]{64}$/i.test(proof.sha256 || '')) return null;
|
|
25
|
+
op.moveProof = { v: 1, kind: proof.kind, sha256: proof.sha256.toLowerCase() };
|
|
26
|
+
if (proof.entityType !== undefined) {
|
|
27
|
+
if (!['doc', 'file'].includes(proof.entityType)) return null;
|
|
28
|
+
op.moveProof.entityType = proof.entityType;
|
|
29
|
+
}
|
|
30
|
+
for (const key of ['sourceEntityId', 'targetEntityId']) {
|
|
31
|
+
if (proof[key] !== undefined) {
|
|
32
|
+
if (typeof proof[key] !== 'string' || !proof[key] || proof[key].length > 160 || /[\0\r\n]/.test(proof[key])) return null;
|
|
33
|
+
op.moveProof[key] = proof[key];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (Array.isArray(input.patches)) {
|
|
38
|
+
if (input.patches.length > 1000) return null;
|
|
39
|
+
op.patches = input.patches.map(p => ({ from: p.from, to: p.to, expected: String(p.expected ?? ''), insert: String(p.insert ?? '') }));
|
|
40
|
+
if (op.patches.some(p => !Number.isSafeInteger(p.from) || !Number.isSafeInteger(p.to) || p.from < 0 || p.to < p.from)) return null;
|
|
41
|
+
}
|
|
42
|
+
operations.push(op);
|
|
43
|
+
}
|
|
44
|
+
const paths = new Set(operations.flatMap(op => [op.path, op.to].filter(Boolean)));
|
|
45
|
+
const baseFiles = (Array.isArray(value.baseFiles) ? value.baseFiles : [])
|
|
46
|
+
.filter(file => paths.has(file?.path) && typeof file.content === 'string')
|
|
47
|
+
.map(file => ({ path: file.path, content: file.content }));
|
|
48
|
+
const result = { v: 1, id: String(value.id).slice(0, 160), projectId: String(value.projectId).slice(0, 160),
|
|
49
|
+
accountScopeId: String(value.accountScopeId).slice(0, 160), sessionId: String(value.sessionId).slice(0, 160),
|
|
50
|
+
runId: String(value.runId).slice(0, 160), createdAt: String(value.createdAt || '').slice(0, 64),
|
|
51
|
+
requireReviewing: value.requireReviewing === true, operations, baseFiles };
|
|
52
|
+
if (typeof value.requestId === 'string') result.requestId = value.requestId.slice(0, 160);
|
|
53
|
+
const size = typeof TextEncoder === 'function' ? new TextEncoder().encode(JSON.stringify(result)).length : JSON.stringify(result).length * 2;
|
|
54
|
+
return size <= MAX_BYTES ? result : null;
|
|
55
|
+
}
|
|
56
|
+
function expectedFiles(value) {
|
|
57
|
+
return Undo.buildExpectedFilesAfterOperations({ files: value.baseFiles }, value.operations.filter(op => !op.type.includes('binary')));
|
|
58
|
+
}
|
|
59
|
+
function normalizeSaveCheck(value) {
|
|
60
|
+
if (!value?.projectId || !value.accountScopeId || !value.sessionId || !value.runId
|
|
61
|
+
|| !Array.isArray(value.files) || value.files.length > 1000) return null;
|
|
62
|
+
const files = [];
|
|
63
|
+
for (const file of value.files) {
|
|
64
|
+
if (!path(file?.path)) return null;
|
|
65
|
+
if (file.absent === true) files.push({ path: file.path, absent: true });
|
|
66
|
+
else if (/^[a-f0-9]{64}$/i.test(file.sha256 || '')) {
|
|
67
|
+
if (file.kind !== undefined && !['text', 'binary'].includes(file.kind)) return null;
|
|
68
|
+
files.push({ path: file.path, sha256: file.sha256.toLowerCase(),
|
|
69
|
+
...(file.kind ? { kind: file.kind } : {}) });
|
|
70
|
+
}
|
|
71
|
+
else return null;
|
|
72
|
+
}
|
|
73
|
+
return files.length ? { v: 1, projectId: String(value.projectId).slice(0, 160),
|
|
74
|
+
accountScopeId: String(value.accountScopeId).slice(0, 160), sessionId: String(value.sessionId).slice(0, 160),
|
|
75
|
+
runId: String(value.runId).slice(0, 160), createdAt: String(value.createdAt || '').slice(0, 64), files } : null;
|
|
76
|
+
}
|
|
77
|
+
return { normalize, normalizeSaveCheck, expectedFiles, MAX_BYTES };
|
|
78
|
+
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
(function initCodexOverleafWritebackOperationEvidence(root, factory) {
|
|
2
2
|
if (typeof module === 'object' && module.exports) {
|
|
3
|
-
module.exports = factory();
|
|
3
|
+
module.exports = factory(require('./failureReasons'));
|
|
4
4
|
} else {
|
|
5
|
-
root.CodexOverleafModuleRegistry.define('WritebackOperationEvidence', [], factory);
|
|
5
|
+
root.CodexOverleafModuleRegistry.define('WritebackOperationEvidence', ['FailureReasons'], factory);
|
|
6
6
|
}
|
|
7
|
-
})(typeof window !== 'undefined' ? window : globalThis, function writebackOperationEvidenceFactory() {
|
|
7
|
+
})(typeof window !== 'undefined' ? window : globalThis, function writebackOperationEvidenceFactory(FailureReasons) {
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
function normalizeOperationEvidence(operations = [], applyResult = {}) {
|
|
@@ -99,18 +99,7 @@
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
function normalizeFailure(result, operation) {
|
|
102
|
-
|
|
103
|
-
if (!result?.code) return null;
|
|
104
|
-
return {
|
|
105
|
-
code: result.code,
|
|
106
|
-
stage: result.stage || 'write',
|
|
107
|
-
severity: result.severity || 'error',
|
|
108
|
-
userMessage: result.reason || result.message || result.code,
|
|
109
|
-
retryable: result.retryable === true,
|
|
110
|
-
file: operation?.path || operation?.to || '',
|
|
111
|
-
changedDocument: result.changedDocument === true,
|
|
112
|
-
terminalState: result.terminalState || ''
|
|
113
|
-
};
|
|
102
|
+
return FailureReasons.normalizeWritebackFailure(result, operation);
|
|
114
103
|
}
|
|
115
104
|
|
|
116
105
|
function normalizeTrackedChanges(value) {
|