codex-overleaf-link 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +272 -311
- package/README.zh-CN.md +287 -326
- 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 +572 -571
- 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 +8974 -1781
- 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 +51 -120
- 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 +364 -356
- 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 +194 -164
- package/extension/src/content/scopedPersistenceCoordinator.js +2 -1
- package/extension/src/content/scopedPersistencePanelState.js +45 -2
- package/extension/src/content/selectionContextView.js +300 -0
- package/extension/src/content/sessionPersistence.js +10 -2
- package/extension/src/content/settingsPanel.js +93 -54
- 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 +58 -3
- 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 +139 -150
- package/extension/src/page/treeOperations.js +36 -29
- package/extension/src/page/writebackReceiptJournal.js +112 -0
- package/extension/src/page/writebackRouter.js +176 -136
- package/extension/src/pageBridge.js +59 -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 +187 -65
- 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 +23 -55
- package/extension/src/shared/storageMigration.js +3 -0
- package/extension/src/shared/storageRunActions.js +54 -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 +2136 -744
- 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 +146 -177
- package/native-host/src/codexSessionTiming.js +71 -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/readProgressGuard.js +84 -17
- 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
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
? Math.max(0, Number(deps.writebackOpenSettleMs))
|
|
18
18
|
: 1200;
|
|
19
19
|
const diagnosticsRevision = String(deps.diagnosticsRevision || '');
|
|
20
|
+
const now = deps.now || Date.now;
|
|
20
21
|
// Cross-world cancel signal reader. Returns the current page-bridge
|
|
21
22
|
// sequence number, which monotonically increments when content-side
|
|
22
23
|
// calls pageBridge.cancelActiveWrite. applyOperationsCore captures the
|
|
@@ -269,6 +270,11 @@
|
|
|
269
270
|
fallbackUserMessage: 'The edit anchor no longer matches current Overleaf content.',
|
|
270
271
|
fallbackNextAction: 'Rerun the task against the current document.'
|
|
271
272
|
},
|
|
273
|
+
write_operation_failed: {
|
|
274
|
+
stage: 'write', severity: 'error', defaultRetryable: true,
|
|
275
|
+
fallbackUserMessage: 'Editor write call failed.',
|
|
276
|
+
fallbackNextAction: 'Retry after the editor is stable.'
|
|
277
|
+
},
|
|
272
278
|
write_observed_mismatch: {
|
|
273
279
|
stage: 'verify', severity: 'error', defaultRetryable: false,
|
|
274
280
|
fallbackUserMessage: 'Codex attempted to write, but the content read back from Overleaf did not match the approved change.',
|
|
@@ -398,7 +404,8 @@
|
|
|
398
404
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
399
405
|
if (!isEditingConfirmedForNoTraceUndo(getReviewingState({}))) {
|
|
400
406
|
toggle = await setReviewingEnabled(false, { waitMs: 1800 });
|
|
401
|
-
if (!toggle.ok
|
|
407
|
+
if (!toggle.ok && (!['editing_not_confirmed', 'reviewing_disable_failed'].includes(toggle.code)
|
|
408
|
+
|| !isEditingConfirmedForNoTraceUndo(getReviewingState({})))) return toggle;
|
|
402
409
|
changed = changed || toggle.changed === true;
|
|
403
410
|
}
|
|
404
411
|
await delay(180);
|
|
@@ -447,20 +454,8 @@
|
|
|
447
454
|
document: window.document,
|
|
448
455
|
treeOperations
|
|
449
456
|
});
|
|
450
|
-
//
|
|
451
|
-
//
|
|
452
|
-
// bumps. Two layers of responsiveness:
|
|
453
|
-
// 1. Between-ops check — short-circuits the next iteration so the
|
|
454
|
-
// remaining ops never start.
|
|
455
|
-
// 2. Race the in-flight op against a cancellation poller (50ms
|
|
456
|
-
// interval) so a click DURING a slow op (e.g. inside a 5s
|
|
457
|
-
// waitForActiveFile poll) is observed within ~50ms instead of
|
|
458
|
-
// having to wait out the op's internal timeout. The op promise
|
|
459
|
-
// keeps running in the page world after the race resolves — its
|
|
460
|
-
// eventual result is ignored. This is "user-perceived instant
|
|
461
|
-
// cancel": the spinner stops, the run settles to cancelled, and
|
|
462
|
-
// any DOM mutation already in flight on the op cannot be undone
|
|
463
|
-
// from here anyway.
|
|
457
|
+
// Preserve the actual result of an in-flight operation so its readback and
|
|
458
|
+
// undo evidence survive cancellation. The checkpoints stop undispatched work.
|
|
464
459
|
const cancelBaselineSequence = readWriteCancellationSequence();
|
|
465
460
|
const cancelledSkipResult = {
|
|
466
461
|
ok: false,
|
|
@@ -477,58 +472,34 @@
|
|
|
477
472
|
changedDocument: false
|
|
478
473
|
}
|
|
479
474
|
};
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
475
|
+
const createCandidates = operations.map(normalizeOperationPaths).filter(operation => operation.type === 'create'
|
|
476
|
+
&& operations.filter(other => [other.path, other.to].includes(operation.path)).length === 1);
|
|
477
|
+
const createBatch = createCandidates.length && typeof deps.beginTextCreateBatch === 'function'
|
|
478
|
+
? await deps.beginTextCreateBatch(createCandidates, { isCurrent: () =>
|
|
479
|
+
treeOperations.getProjectId?.() === runProjectId && readWriteCancellationSequence() === cancelBaselineSequence }) : null;
|
|
480
|
+
const deferredCreates = [];
|
|
481
|
+
const reopenQueue = [];
|
|
482
|
+
const deadlineFailure = () => Number.isFinite(options.deadlineAt) && now() >= options.deadlineAt
|
|
483
|
+
? { ok: false, code: 'writeback_deadline_exceeded', changedDocument: false,
|
|
484
|
+
reason: 'The undo time budget expired before this operation could start.' } : null;
|
|
485
|
+
const editOptions = () => ({ baseFileLookup, runProjectId,
|
|
486
|
+
recheckWriteProject: writeGuardSurface ? () => {
|
|
487
|
+
const expired = deadlineFailure();
|
|
488
|
+
return expired ? { applied: [], skipped: [{ operation: {}, result: expired }] }
|
|
489
|
+
: writeGuardSurface.runWriteGuard({ runProjectId });
|
|
490
|
+
} : null,
|
|
491
|
+
trackReviewingChanges: options.trackReviewingChanges === true, noTraceUndo: options.noTraceUndo === true });
|
|
492
|
+
const record = (operation, result) => {
|
|
493
|
+
if (result.trackedChangeCapture) trackedChangeCaptures.push(result.trackedChangeCapture);
|
|
494
|
+
if (operation.type === 'edit' && result.ok && Array.isArray(result.trackedChanges)) {
|
|
495
|
+
trackedChanges.push(...result.trackedChanges);
|
|
489
496
|
}
|
|
497
|
+
(result.ok ? applied : skipped).push({ operation, result });
|
|
498
|
+
options.onOperationResult?.({ operation, result });
|
|
490
499
|
};
|
|
491
|
-
// 50ms-poller racer using recursive setTimeout. setInterval is NOT
|
|
492
|
-
// exposed in the test VM context that hosts pageBridge (only setTimeout /
|
|
493
|
-
// clearTimeout are wired), so this implementation must avoid it. Each
|
|
494
|
-
// tick re-schedules itself only while the racer has not resolved;
|
|
495
|
-
// dispose() flips a flag so any tick that fires after dispose is a no-op.
|
|
496
|
-
// Resolves the first time the cancellation sequence bumps past baseline.
|
|
497
|
-
function createCancellationRacer() {
|
|
498
|
-
let resolved = false;
|
|
499
|
-
let resolveFn;
|
|
500
|
-
const promise = new Promise(resolve => { resolveFn = resolve; });
|
|
501
|
-
let timer = null;
|
|
502
|
-
function tick() {
|
|
503
|
-
if (resolved) return;
|
|
504
|
-
if (readWriteCancellationSequence() !== cancelBaselineSequence) {
|
|
505
|
-
resolved = true;
|
|
506
|
-
resolveFn();
|
|
507
|
-
return;
|
|
508
|
-
}
|
|
509
|
-
timer = window.setTimeout(tick, 50);
|
|
510
|
-
}
|
|
511
|
-
timer = window.setTimeout(tick, 50);
|
|
512
|
-
return {
|
|
513
|
-
promise,
|
|
514
|
-
dispose() {
|
|
515
|
-
resolved = true;
|
|
516
|
-
if (timer) window.clearTimeout(timer);
|
|
517
|
-
}
|
|
518
|
-
};
|
|
519
|
-
}
|
|
520
|
-
const CANCELLED_RACE_SENTINEL = Symbol('writebackRouter.cancelled');
|
|
521
|
-
async function raceOpAgainstCancellation(opPromise) {
|
|
522
|
-
// Once an editor operation starts, preserve its actual result and undo
|
|
523
|
-
// metadata. The loop's pre-operation cancellation check stops the tail.
|
|
524
|
-
return await opPromise;
|
|
525
|
-
}
|
|
526
500
|
|
|
527
501
|
for (const rawOperation of operations) {
|
|
528
|
-
//
|
|
529
|
-
// runs before the writeGuard re-check so a click-cancel that arrived
|
|
530
|
-
// during the previous op's await microtasks short-circuits before we
|
|
531
|
-
// burn time on guard / open-file work for the next op.
|
|
502
|
+
// Stop undispatched work when cancellation arrives during an awaited operation.
|
|
532
503
|
if (readWriteCancellationSequence() !== cancelBaselineSequence) {
|
|
533
504
|
skipped.push({ operation: normalizeOperationPaths(rawOperation), result: cancelledSkipResult });
|
|
534
505
|
const remainingForCancel = operations.slice(operations.indexOf(rawOperation) + 1);
|
|
@@ -537,16 +508,11 @@
|
|
|
537
508
|
}
|
|
538
509
|
break;
|
|
539
510
|
}
|
|
540
|
-
//
|
|
541
|
-
// guard is available, verify the editor still shows the same project
|
|
542
|
-
// before committing the next write. Mismatch → push aborted_project_changed
|
|
543
|
-
// for THIS op and every remaining op in the queue, then return.
|
|
511
|
+
// Re-check project ownership before this operation and preserve every skipped tail entry.
|
|
544
512
|
if (runProjectId && writeGuardSurface) {
|
|
545
513
|
const guardBlock = await writeGuardSurface.runWriteGuard({ runProjectId });
|
|
546
514
|
if (guardBlock) {
|
|
547
|
-
//
|
|
548
|
-
// caller can attribute the abort to a real operation path, then
|
|
549
|
-
// pad the remaining ops with the same failure shape.
|
|
515
|
+
// Keep the current path and the remaining operations attributable.
|
|
550
516
|
const guardFailure = guardBlock.skipped[0].result;
|
|
551
517
|
skipped.push({ operation: normalizeOperationPaths(rawOperation), result: guardFailure });
|
|
552
518
|
const remaining = operations.slice(operations.indexOf(rawOperation) + 1);
|
|
@@ -557,23 +523,24 @@
|
|
|
557
523
|
}
|
|
558
524
|
}
|
|
559
525
|
const operation = normalizeOperationPaths(rawOperation);
|
|
560
|
-
const pathSafety = validateOperationProjectPaths(operation);
|
|
526
|
+
const pathSafety = deadlineFailure() || validateOperationProjectPaths(operation);
|
|
561
527
|
if (!pathSafety.ok) {
|
|
562
528
|
skipped.push({ operation, result: pathSafety });
|
|
563
529
|
continue;
|
|
564
530
|
}
|
|
565
|
-
let
|
|
531
|
+
let result;
|
|
566
532
|
if (operation.type === 'edit') {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
}));
|
|
533
|
+
result = await applyEditOperation(operation, editOptions());
|
|
534
|
+
if (isUntouchedOpenFailure(result)) {
|
|
535
|
+
reopenQueue.push({ operation, result });
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
573
538
|
} else if (['binary-create', 'overwrite-binary'].includes(operation.type)) {
|
|
574
|
-
|
|
539
|
+
result = await applyBinaryAssetOperation(operation, { baseFileLookup, baseBinaryFileLookup });
|
|
575
540
|
} else if (['create', 'rename', 'move', 'delete'].includes(operation.type)) {
|
|
576
|
-
|
|
541
|
+
result = await applyFileTreeOperation(operation, { baseFileLookup, runProjectId, deadlineAt: options.deadlineAt,
|
|
542
|
+
createBatch: createBatch?.targets.has(operation.path) ? createBatch : null,
|
|
543
|
+
retryCreates: options.retryCreates === true });
|
|
577
544
|
} else {
|
|
578
545
|
skipped.push({
|
|
579
546
|
operation,
|
|
@@ -584,27 +551,37 @@
|
|
|
584
551
|
});
|
|
585
552
|
continue;
|
|
586
553
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
if (raceResult === CANCELLED_RACE_SENTINEL) {
|
|
592
|
-
skipped.push({ operation, result: cancelledInFlightResult });
|
|
593
|
-
const remainingAfterCancel = operations.slice(operations.indexOf(rawOperation) + 1);
|
|
594
|
-
for (const tailOperation of remainingAfterCancel) {
|
|
595
|
-
skipped.push({ operation: normalizeOperationPaths(tailOperation), result: cancelledSkipResult });
|
|
596
|
-
}
|
|
597
|
-
break;
|
|
598
|
-
}
|
|
599
|
-
const result = raceResult;
|
|
600
|
-
if (result.trackedChangeCapture) trackedChangeCaptures.push(result.trackedChangeCapture);
|
|
601
|
-
if (operation.type === 'edit' && result.ok && Array.isArray(result.trackedChanges)) {
|
|
602
|
-
trackedChanges.push(...result.trackedChanges);
|
|
554
|
+
if (operation.type === 'create' && createBatch?.pending.has(operation.path)
|
|
555
|
+
&& !createBatch.blocked.has(operation.path)) {
|
|
556
|
+
deferredCreates.push({ operation, result });
|
|
557
|
+
continue;
|
|
603
558
|
}
|
|
604
|
-
(
|
|
559
|
+
record(operation, result);
|
|
605
560
|
}
|
|
606
561
|
|
|
607
|
-
|
|
562
|
+
// A file that could not be opened mid-batch usually opens once the
|
|
563
|
+
// previous document has settled: give untouched open failures one pass.
|
|
564
|
+
if (reopenQueue.length && readWriteCancellationSequence() === cancelBaselineSequence
|
|
565
|
+
&& !skipped.some(entry => entry.result?.code === 'aborted_project_changed')) {
|
|
566
|
+
await delay(deps.reopenRetryDelayMs ?? 1200);
|
|
567
|
+
}
|
|
568
|
+
for (const entry of reopenQueue) {
|
|
569
|
+
const blocked = readWriteCancellationSequence() !== cancelBaselineSequence
|
|
570
|
+
|| skipped.some(item => item.result?.code === 'aborted_project_changed')
|
|
571
|
+
|| Boolean(runProjectId && writeGuardSurface && await writeGuardSurface.runWriteGuard({ runProjectId }));
|
|
572
|
+
const result = blocked ? entry.result : await applyEditOperation(entry.operation, editOptions());
|
|
573
|
+
record(entry.operation, result);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
if (deferredCreates.length) {
|
|
577
|
+
const confirmed = await deps.finishTextCreateBatch(createBatch, deferredCreates, applied);
|
|
578
|
+
for (const entry of confirmed) {
|
|
579
|
+
(entry.result.ok ? applied : skipped).push(entry);
|
|
580
|
+
if (entry.result.ok) recordFileTreeOperationSuccess(entry.operation, baseFileLookup);
|
|
581
|
+
options.onOperationResult?.(entry);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
if (applied.some(entry => entry.result?.changedDocument !== false)) {
|
|
608
585
|
compileBridge.markSourceEdited();
|
|
609
586
|
}
|
|
610
587
|
|
|
@@ -617,29 +594,10 @@
|
|
|
617
594
|
};
|
|
618
595
|
}
|
|
619
596
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
597
|
+
function isUntouchedOpenFailure(result) {
|
|
598
|
+
return result?.ok === false && result.failure?.code === 'target_file_open_failed'
|
|
599
|
+
&& result.failure.changedDocument === false;
|
|
600
|
+
}
|
|
643
601
|
|
|
644
602
|
async function applyEditOperation(operation, options = {}) {
|
|
645
603
|
const currentPath = getActiveFilePath();
|
|
@@ -778,12 +736,23 @@
|
|
|
778
736
|
return result;
|
|
779
737
|
}
|
|
780
738
|
|
|
781
|
-
const verified = await verifyActiveEditorText(nextContent, operation.path);
|
|
739
|
+
const verified = await verifyActiveEditorText(nextContent, operation.path, deps.writeVerifyWaitMs ?? 2500, current);
|
|
782
740
|
if (!verified.ok) {
|
|
783
741
|
const decorated = attachWritebackDebug(verified, 'write_verification', operation, options.baseFileLookup, readActiveEditorText(), {
|
|
784
742
|
initialActivePath: currentPath,
|
|
785
743
|
editorReadyDebug: editorReady.debug || null
|
|
786
744
|
});
|
|
745
|
+
const evidence = { originalCode: verified.code || '', writeMethod: result.method || '', writeStarted: true,
|
|
746
|
+
...verified.evidence };
|
|
747
|
+
if (verified.evidence?.observedIsBefore && verified.evidence.activeMatchesTarget) {
|
|
748
|
+
// The editor still holds exactly the pre-write text: the write never landed, so a retry is safe.
|
|
749
|
+
decorated.failure = buildPageFailure('write_operation_failed', {
|
|
750
|
+
file: operation?.path || '', operationType: operation?.type || 'edit', changedDocument: false,
|
|
751
|
+
userMessage: `Overleaf did not accept the edit to ${operation?.path || 'the target file'}; the document was left unchanged.`,
|
|
752
|
+
technicalMessage: verified.reason || '', evidence
|
|
753
|
+
});
|
|
754
|
+
return decorated;
|
|
755
|
+
}
|
|
787
756
|
// §9.3 write_observed_mismatch: the write call landed but the readback
|
|
788
757
|
// does not match. changedDocument:true — the editor state moved, just
|
|
789
758
|
// not as Codex expected.
|
|
@@ -793,12 +762,7 @@
|
|
|
793
762
|
changedDocument: true,
|
|
794
763
|
userMessage: `${operation?.path || 'The target file'} did not read back the content Codex wrote; the document state may differ from what was approved.`,
|
|
795
764
|
technicalMessage: verified.reason || '',
|
|
796
|
-
evidence
|
|
797
|
-
originalCode: verified.code || '',
|
|
798
|
-
expectedLength: verified.expectedLength,
|
|
799
|
-
actualLength: verified.actualLength,
|
|
800
|
-
writeStarted: true
|
|
801
|
-
}
|
|
765
|
+
evidence
|
|
802
766
|
});
|
|
803
767
|
return decorated;
|
|
804
768
|
}
|
|
@@ -808,12 +772,12 @@
|
|
|
808
772
|
// Overleaf renders review markers asynchronously after the editor text
|
|
809
773
|
// has already changed. A single 120 ms snapshot intermittently missed
|
|
810
774
|
// those markers, leaving a Reviewing write with Undo but no Accept.
|
|
811
|
-
//
|
|
812
|
-
//
|
|
813
|
-
//
|
|
775
|
+
// Complete normal Track attribution while this file is still active.
|
|
776
|
+
// Slow batches are covered by request receipts; Accept replay retains
|
|
777
|
+
// its independent safety window proving that no new tracking was added.
|
|
814
778
|
const trackedDiff = trackReviewingChanges
|
|
815
779
|
? await captureTrackedWrite({ trackedBefore, captureBaseline, operation, beforeContent: current,
|
|
816
|
-
postContent: nextContent, runProjectId: options.runProjectId })
|
|
780
|
+
postContent: nextContent, runProjectId: options.runProjectId, waitMs: deps.trackCaptureWaitMs ?? 35000 })
|
|
817
781
|
: await waitForTrackedChangeDiff(trackedBefore, operationPaths, {
|
|
818
782
|
waitMs: 3600, intervalMs: 180, stopOnFirst: true
|
|
819
783
|
});
|
|
@@ -860,7 +824,7 @@
|
|
|
860
824
|
}
|
|
861
825
|
|
|
862
826
|
|
|
863
|
-
async function verifyActiveEditorText(expected, filePath, waitMs = 1000) {
|
|
827
|
+
async function verifyActiveEditorText(expected, filePath, waitMs = 1000, before) {
|
|
864
828
|
const deadline = Date.now() + waitMs;
|
|
865
829
|
let actual = readActiveEditorText();
|
|
866
830
|
while (actual !== expected && Date.now() < deadline) {
|
|
@@ -877,10 +841,37 @@
|
|
|
877
841
|
code: 'write_verification_failed',
|
|
878
842
|
reason: `${filePath || '当前文件'} 写入后读回内容和 Codex 预期不一致,已停止把这次操作标记为成功。请刷新 Overleaf 后重试。`,
|
|
879
843
|
expectedLength: String(expected || '').length,
|
|
880
|
-
actualLength: String(actual || '').length
|
|
844
|
+
actualLength: String(actual || '').length,
|
|
845
|
+
evidence: describeReadbackMismatch(expected, actual, before, filePath)
|
|
881
846
|
};
|
|
882
847
|
}
|
|
883
848
|
|
|
849
|
+
// Content-free mismatch evidence: offsets, lengths and short hashes only.
|
|
850
|
+
function describeReadbackMismatch(expected, actual, before, filePath) {
|
|
851
|
+
const left = String(expected ?? ''), right = String(actual ?? '');
|
|
852
|
+
let firstDiff = 0;
|
|
853
|
+
while (firstDiff < left.length && left[firstDiff] === right[firstDiff]) firstDiff += 1;
|
|
854
|
+
let tail = 0;
|
|
855
|
+
while (tail < left.length - firstDiff && tail < right.length - firstDiff
|
|
856
|
+
&& left[left.length - 1 - tail] === right[right.length - 1 - tail]) tail += 1;
|
|
857
|
+
const activePath = getActiveFilePath() || '';
|
|
858
|
+
return { expectedLength: left.length, actualLength: right.length, firstDiffOffset: firstDiff,
|
|
859
|
+
expectedDiffLength: left.length - firstDiff - tail, actualDiffLength: right.length - firstDiff - tail,
|
|
860
|
+
expectedHash: shortHash(left), actualHash: shortHash(right),
|
|
861
|
+
beforeHash: typeof before === 'string' ? shortHash(before) : '',
|
|
862
|
+
observedIsBefore: typeof before === 'string' && right === before,
|
|
863
|
+
activePath, activeMatchesTarget: !filePath || activePath === filePath };
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
function shortHash(value) {
|
|
867
|
+
let hash = 0x811c9dc5;
|
|
868
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
869
|
+
hash ^= value.charCodeAt(index);
|
|
870
|
+
hash = Math.imul(hash, 0x01000193) >>> 0;
|
|
871
|
+
}
|
|
872
|
+
return hash.toString(16).padStart(8, '0');
|
|
873
|
+
}
|
|
874
|
+
|
|
884
875
|
async function ensureEditorReadyForOperation(operation, baseFileLookup, initialActivePath) {
|
|
885
876
|
if (!operation?.path) {
|
|
886
877
|
return {
|
|
@@ -1376,8 +1367,20 @@
|
|
|
1376
1367
|
}
|
|
1377
1368
|
|
|
1378
1369
|
async function applyFileTreeOperation(operation, options = {}) {
|
|
1370
|
+
if (operation.type === 'delete' && operation.undoCreatedFile) {
|
|
1371
|
+
return applyCreatedFileUndo(operation, options);
|
|
1372
|
+
}
|
|
1379
1373
|
const initialProjectId = treeOperations.getProjectId?.();
|
|
1380
1374
|
const initialCancellationSequence = readWriteCancellationSequence();
|
|
1375
|
+
if (operation.type === 'create' && options.createBatch && typeof deps.createTextFile === 'function') {
|
|
1376
|
+
if (options.baseFileLookup?.has(operation.path) && options.retryCreates !== true) {
|
|
1377
|
+
return checkFileTreeOperationFreshness(operation, options.baseFileLookup);
|
|
1378
|
+
}
|
|
1379
|
+
return deps.createTextFile(operation, { batch: options.createBatch,
|
|
1380
|
+
allowExistingMatches: options.retryCreates === true,
|
|
1381
|
+
isCurrent: () => treeOperations.getProjectId?.() === initialProjectId
|
|
1382
|
+
&& readWriteCancellationSequence() === initialCancellationSequence });
|
|
1383
|
+
}
|
|
1381
1384
|
const freshness = await checkFileTreeOperationFreshness(operation, options.baseFileLookup);
|
|
1382
1385
|
if (!freshness.ok) {
|
|
1383
1386
|
return freshness;
|
|
@@ -1436,7 +1439,7 @@
|
|
|
1436
1439
|
return { ...fileTreeVerificationFailed(operation, 'Server receipt is missing or stale.'), changedDocument: true };
|
|
1437
1440
|
}
|
|
1438
1441
|
recordFileTreeOperationSuccess(operation, options.baseFileLookup);
|
|
1439
|
-
return { ok: true, method: created.method, verified: true };
|
|
1442
|
+
return { ...created, ok: true, method: created.method, verified: true };
|
|
1440
1443
|
}
|
|
1441
1444
|
return {
|
|
1442
1445
|
ok: false,
|
|
@@ -1445,6 +1448,43 @@
|
|
|
1445
1448
|
};
|
|
1446
1449
|
}
|
|
1447
1450
|
|
|
1451
|
+
async function applyCreatedFileUndo(operation, options = {}) {
|
|
1452
|
+
const projectId = treeOperations.getProjectId?.();
|
|
1453
|
+
const cancellation = readWriteCancellationSequence();
|
|
1454
|
+
const proof = operation.undoCreatedFile;
|
|
1455
|
+
const expected = options.baseFileLookup?.get(operation.path);
|
|
1456
|
+
const text = proof?.v === 1 && proof.kind === 'text' && typeof expected === 'string';
|
|
1457
|
+
const binary = proof?.v === 1 && proof.kind === 'binary' && /^[a-f0-9]{64}$/i.test(proof.sha256 || '');
|
|
1458
|
+
const isCurrent = () => Boolean(projectId) && projectId === options.runProjectId
|
|
1459
|
+
&& treeOperations.getProjectId?.() === projectId && readWriteCancellationSequence() === cancellation;
|
|
1460
|
+
if (!isCurrent() || (!text && !binary) || typeof deps.deleteTextFile !== 'function') {
|
|
1461
|
+
return { ok: false, code: 'undo_operation_failed', changedDocument: false,
|
|
1462
|
+
reason: 'Verified created-file deletion is unavailable for this run.' };
|
|
1463
|
+
}
|
|
1464
|
+
if (text && projectPathExists(operation.path)) {
|
|
1465
|
+
const current = await readCurrentTextFileForFreshness(operation.path);
|
|
1466
|
+
if (!current.ok || current.text !== expected || !isCurrent()) {
|
|
1467
|
+
return { ok: false, code: 'undo_operation_failed', changedDocument: false,
|
|
1468
|
+
reason: 'The created file changed after this run and was left untouched.' };
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
const result = await deps.deleteTextFile(operation, {
|
|
1472
|
+
isCurrent, undoCreatedFile: true, deadlineAt: options.deadlineAt,
|
|
1473
|
+
expectedContent: text ? expected : undefined,
|
|
1474
|
+
prepareTextPreimage: text ? () => readCurrentTextFileForFreshness(operation.path) : undefined,
|
|
1475
|
+
expectedSha256: binary ? proof.sha256.toLowerCase() : undefined,
|
|
1476
|
+
canDelete: () => isCurrent() && (binary || (treeOperations.getActiveFilePath?.() === operation.path
|
|
1477
|
+
&& readActiveEditorText() === expected))
|
|
1478
|
+
});
|
|
1479
|
+
if (!result.ok) return result;
|
|
1480
|
+
if (!isCurrent() || result.verified !== true || result.verification !== 'overleaf-zip') {
|
|
1481
|
+
return { ok: false, code: 'undo_operation_failed', changedDocument: result.changedDocument !== false,
|
|
1482
|
+
reason: 'The created file has no current server deletion receipt.' };
|
|
1483
|
+
}
|
|
1484
|
+
recordFileTreeOperationSuccess(operation, options.baseFileLookup);
|
|
1485
|
+
return result;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1448
1488
|
async function verifyFileTreeOperation(operation) {
|
|
1449
1489
|
await delay(120);
|
|
1450
1490
|
const sourcePath = operation.path;
|
|
@@ -1890,7 +1930,7 @@
|
|
|
1890
1930
|
captureTrackedWrite, reconcileTrackedChangeCapture,
|
|
1891
1931
|
waitForTrackedChangeDiff
|
|
1892
1932
|
} = trackedChangesLifecycleModule.create({
|
|
1893
|
-
window,
|
|
1933
|
+
window, confirmReviewWriteback: deps.confirmReviewWriteback,
|
|
1894
1934
|
checkWritebackRunProjectId,
|
|
1895
1935
|
buildNoTraceUndoBlockedResult,
|
|
1896
1936
|
buildReviewingRequiredBlockedResult,
|