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
|
@@ -63,6 +63,8 @@
|
|
|
63
63
|
let writebackSettlement;
|
|
64
64
|
let injectedWritebackSettlement;
|
|
65
65
|
let assetTransferBroker;
|
|
66
|
+
let stageWritebackRecovery;
|
|
67
|
+
let settleWritebackRecovery;
|
|
66
68
|
|
|
67
69
|
function buildSettlement(input = {}) {
|
|
68
70
|
return writebackSettlement?.settle instanceof Function
|
|
@@ -98,7 +100,24 @@
|
|
|
98
100
|
return pending;
|
|
99
101
|
}
|
|
100
102
|
|
|
103
|
+
function selectionViolationNextStep() {
|
|
104
|
+
return tx('Select the intended region again and request only changes within it. Valid written parts can be undone.',
|
|
105
|
+
'请重新选择目标范围,仅请求修改该范围。已写入的合法部分可撤销。');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function buildWithheldEntry(change) {
|
|
109
|
+
const reason = writebackController.formatUnsupportedLocalChangeReason(change, getLocale());
|
|
110
|
+
const nextAction = change.reason === 'selection_scope_violation' ? selectionViolationNextStep()
|
|
111
|
+
: tx('The main agent must review the withheld file before syncing it.', '主代理需核对未同步文件后再写回。');
|
|
112
|
+
return { operation: { type: 'create', path: change.path }, result: { ok: false,
|
|
113
|
+
code: change.reason, reason, changedDocument: false, failure: { code: change.reason,
|
|
114
|
+
stage: 'preflight', severity: 'blocked', retryable: false, terminalState: 'blocked', changedDocument: false,
|
|
115
|
+
userMessage: reason, nextAction } } };
|
|
116
|
+
}
|
|
117
|
+
|
|
101
118
|
async function applySyncChangesToOverleaf(syncChanges = [], project = {}, options = {}) {
|
|
119
|
+
const activeRun = getCurrentRunView?.();
|
|
120
|
+
const saveTarget = { runProjectId: activeRun?.runProjectId || '', recordId: activeRun?.recordId || '', sessionId: activeRun?.sessionId || '' };
|
|
102
121
|
const runMode = options.mode || getState().mode;
|
|
103
122
|
const runRequireReviewing = typeof options.requireReviewing === 'boolean'
|
|
104
123
|
? options.requireReviewing
|
|
@@ -106,6 +125,23 @@
|
|
|
106
125
|
const assistantMessage = cleanFinalAnswer(options.assistantMessage || getAssistantAnswerForCurrentRun());
|
|
107
126
|
const unsupportedChanges = Array.isArray(options.unsupportedChanges) ? options.unsupportedChanges : [];
|
|
108
127
|
appendUnsupportedLocalChanges(unsupportedChanges);
|
|
128
|
+
const withheldOnly = unsupportedChanges.filter(change => ['subagent_unfinished_output', 'subagent_unauthorized_edit', 'selection_scope_violation'].includes(change.reason));
|
|
129
|
+
if (runMode !== 'ask' && !syncChanges.length && withheldOnly.length) {
|
|
130
|
+
const skipped = withheldOnly.map(buildWithheldEntry);
|
|
131
|
+
const hasSelectionViolation = withheldOnly.some(change => change.reason === 'selection_scope_violation');
|
|
132
|
+
const applied = { ok: false, applied: [], skipped };
|
|
133
|
+
appendCompletionReport({ conclusion: assistantMessage || tx('Some generated changes were blocked.', '部分生成的改动已被阻止。'),
|
|
134
|
+
status: 'failed', operations: [], applyResults: [applied], mode: runMode,
|
|
135
|
+
nextStep: hasSelectionViolation
|
|
136
|
+
? selectionViolationNextStep()
|
|
137
|
+
: tx('The main agent must review and adopt the withheld files before syncing them.', '主代理需核对并接管未同步文件后再写回。') });
|
|
138
|
+
return { summaryLine: hasSelectionViolation
|
|
139
|
+
? tx('Changes outside the selection were blocked.', '选区外改动已被阻止。')
|
|
140
|
+
: tx('Generated files are awaiting review.', '生成文件待核对。'), hasSkippedOperations: true,
|
|
141
|
+
applied, settlement: buildSettlement({ operations: [], applyResult: applied }),
|
|
142
|
+
audit: buildAuditSummaryFromApply({ operations: [], applyResults: [applied], resultStatus: 'completed_with_skips' }) };
|
|
143
|
+
}
|
|
144
|
+
|
|
109
145
|
// Guard on the immutable submitted mode, not the mutable panel state.
|
|
110
146
|
if (options.mode === 'ask' && ((syncChanges || []).length || unsupportedChanges.length)) {
|
|
111
147
|
appendRunEvent({
|
|
@@ -148,7 +184,16 @@
|
|
|
148
184
|
}
|
|
149
185
|
let operations = buildSyncApplyOperations(syncChanges, project);
|
|
150
186
|
let visibleSyncChanges = syncChanges || [];
|
|
151
|
-
|
|
187
|
+
// A previous Native build can still report inferred metadata moves.
|
|
188
|
+
// Forward sync never promotes them to a new file or a new capability.
|
|
189
|
+
let additionalSkippedEntries = operations.filter(operation => operation.type === 'move').map(operation => ({
|
|
190
|
+
operation,
|
|
191
|
+
result: { ok: false, code: 'file_tree_controls_unavailable', changedDocument: false,
|
|
192
|
+
reason: tx('Automatic file moves are unavailable. Handle the path change in Overleaf before retrying.',
|
|
193
|
+
'暂不支持自动移动文件,请先在 Overleaf 中处理路径变化后再重试。') }
|
|
194
|
+
}));
|
|
195
|
+
operations = operations.filter(operation => operation.type !== 'move');
|
|
196
|
+
if (additionalSkippedEntries.length) visibleSyncChanges = filterSyncChangesByOperations(syncChanges, operations);
|
|
152
197
|
let skippedFilesForAudit = additionalSkippedEntries;
|
|
153
198
|
let appliedFilesForAudit = [];
|
|
154
199
|
const pathSafety = partitionUnsafeProjectPathOperations(operations);
|
|
@@ -173,13 +218,20 @@
|
|
|
173
218
|
visibleSyncChanges = filterSyncChangesByOperations(syncChanges, operations);
|
|
174
219
|
}
|
|
175
220
|
if (!operations.length) {
|
|
221
|
+
const blockedSettlement = buildSettlement({
|
|
222
|
+
operations: buildSyncApplyOperations(syncChanges, project),
|
|
223
|
+
applyResult: { ok: additionalSkippedEntries.length === 0, applied: [], skipped: additionalSkippedEntries }
|
|
224
|
+
});
|
|
225
|
+
const blockedFailure = blockedSettlement
|
|
226
|
+
? writebackSettlement.projectRunSettlement({ settlement: blockedSettlement.facts }).primaryFailure : undefined;
|
|
176
227
|
appendRunEvent({
|
|
177
228
|
title: tx('Codex did not produce file changes that need to sync back to Overleaf.', 'Codex 没有产生需要同步回 Overleaf 的文件改动。'),
|
|
178
229
|
status: 'completed'
|
|
179
230
|
});
|
|
180
231
|
appendCompletionReport({
|
|
181
232
|
conclusion: assistantMessage || tx('Codex finished locally. There are no changes to sync back to Overleaf.', 'Codex 已完成本地处理,没有需要同步回 Overleaf 的改动。'),
|
|
182
|
-
status: runMode === 'ask' ? tr('modeAsk') : 'completed',
|
|
233
|
+
status: additionalSkippedEntries.length ? 'failed' : runMode === 'ask' ? tr('modeAsk') : 'completed',
|
|
234
|
+
failure: blockedFailure,
|
|
183
235
|
operations: [],
|
|
184
236
|
applyResults: additionalSkippedEntries.length ? [{ ok: false, applied: [], skipped: additionalSkippedEntries }] : [],
|
|
185
237
|
unchangedReason: additionalSkippedEntries.find(item => item?.result?.reason)?.result.reason
|
|
@@ -190,14 +242,7 @@
|
|
|
190
242
|
return {
|
|
191
243
|
summaryLine: assistantMessage || tx('No changes to sync', '没有需要同步的改动'),
|
|
192
244
|
hasSkippedOperations: additionalSkippedEntries.length > 0,
|
|
193
|
-
settlement:
|
|
194
|
-
operations: buildSyncApplyOperations(syncChanges, project),
|
|
195
|
-
applyResult: {
|
|
196
|
-
ok: additionalSkippedEntries.length === 0,
|
|
197
|
-
applied: [],
|
|
198
|
-
skipped: additionalSkippedEntries
|
|
199
|
-
}
|
|
200
|
-
}),
|
|
245
|
+
settlement: blockedSettlement,
|
|
201
246
|
audit: buildAuditSummaryFromApply({
|
|
202
247
|
operations: buildSyncApplyOperations(syncChanges, project),
|
|
203
248
|
applyResults: additionalSkippedEntries.length ? [{ ok: false, applied: [], skipped: additionalSkippedEntries }] : [],
|
|
@@ -240,13 +285,20 @@
|
|
|
240
285
|
additionalSkippedEntries.push(...binaryDecision.skipped);
|
|
241
286
|
|
|
242
287
|
if (!operations.length) {
|
|
288
|
+
const approvalSettlement = buildSettlement({
|
|
289
|
+
operations: buildSyncApplyOperations(syncChanges, project),
|
|
290
|
+
applyResult: { ok: additionalSkippedEntries.length === 0, applied: [], skipped: additionalSkippedEntries }
|
|
291
|
+
});
|
|
292
|
+
const approvalFailure = approvalSettlement
|
|
293
|
+
? writebackSettlement.projectRunSettlement({ settlement: approvalSettlement.facts }).primaryFailure : undefined;
|
|
243
294
|
appendRunEvent({
|
|
244
295
|
title: tx('No approved file changes remain to sync back to Overleaf.', '没有剩余已确认的文件改动需要同步回 Overleaf。'),
|
|
245
296
|
status: 'completed'
|
|
246
297
|
});
|
|
247
298
|
appendCompletionReport({
|
|
248
299
|
conclusion: assistantMessage || tx('No approved changes were written back to Overleaf.', '没有已确认的改动写回 Overleaf。'),
|
|
249
|
-
status: runMode === 'ask' ? tr('modeAsk') : 'completed',
|
|
300
|
+
status: additionalSkippedEntries.length ? 'failed' : runMode === 'ask' ? tr('modeAsk') : 'completed',
|
|
301
|
+
failure: approvalFailure,
|
|
250
302
|
operations: [],
|
|
251
303
|
applyResults: additionalSkippedEntries.length ? [{ ok: false, applied: [], skipped: additionalSkippedEntries }] : [],
|
|
252
304
|
unchangedReason: additionalSkippedEntries.find(item => item?.result?.reason)?.result.reason
|
|
@@ -257,14 +309,7 @@
|
|
|
257
309
|
return {
|
|
258
310
|
summaryLine: tx('No changes applied', '没有应用改动'),
|
|
259
311
|
hasSkippedOperations: additionalSkippedEntries.length > 0,
|
|
260
|
-
settlement:
|
|
261
|
-
operations: buildSyncApplyOperations(syncChanges, project),
|
|
262
|
-
applyResult: {
|
|
263
|
-
ok: additionalSkippedEntries.length === 0,
|
|
264
|
-
applied: [],
|
|
265
|
-
skipped: additionalSkippedEntries
|
|
266
|
-
}
|
|
267
|
-
}),
|
|
312
|
+
settlement: approvalSettlement,
|
|
268
313
|
audit: buildAuditSummaryFromApply({
|
|
269
314
|
operations: buildSyncApplyOperations(syncChanges, project),
|
|
270
315
|
applyResults: additionalSkippedEntries.length ? [{ ok: false, applied: [], skipped: additionalSkippedEntries }] : [],
|
|
@@ -312,6 +357,13 @@
|
|
|
312
357
|
})
|
|
313
358
|
};
|
|
314
359
|
}
|
|
360
|
+
const writebackActivityId = 'overleaf-writeback:' + Date.now().toString(36);
|
|
361
|
+
appendRunEvent({
|
|
362
|
+
title: tx('Syncing approved changes to Overleaf.', '正在将已批准的改动同步到 Overleaf。'),
|
|
363
|
+
status: 'running',
|
|
364
|
+
activity: { v: 1, kind: 'sync', id: writebackActivityId, state: 'running', paths: operations.map(operation => operation.path).filter(Boolean) }
|
|
365
|
+
});
|
|
366
|
+
await stageWritebackRecovery?.(operations, saveTarget, runRequireReviewing, project);
|
|
315
367
|
const applied = operations.length
|
|
316
368
|
? mergeApplyResultSkipped(await assetTransferBroker.applyOperations({
|
|
317
369
|
operations,
|
|
@@ -321,10 +373,15 @@
|
|
|
321
373
|
// Welcome-panel + write-guard:
|
|
322
374
|
// immutable per-run project id, checked by the page-side guard
|
|
323
375
|
// against `_ide.project._id` before any mutation.
|
|
324
|
-
runProjectId: getCurrentRunView()?.runProjectId || ''
|
|
376
|
+
runProjectId: getCurrentRunView()?.runProjectId || '',
|
|
377
|
+
retryCreates: options.retryCreates === true
|
|
325
378
|
}), additionalSkippedEntries)
|
|
326
379
|
: mergeApplyResultSkipped({ ok: true, applied: [], skipped: [] }, additionalSkippedEntries);
|
|
327
380
|
const hasConfirmedApplyResult = hasApplyResultEntries(applied);
|
|
381
|
+
for (const change of unsupportedChanges.filter(item => ['subagent_unfinished_output', 'subagent_unauthorized_edit', 'selection_scope_violation'].includes(item.reason))) {
|
|
382
|
+
applied.skipped.push(buildWithheldEntry(change));
|
|
383
|
+
applied.ok = false;
|
|
384
|
+
}
|
|
328
385
|
// Record the apply result + undo checkpoint IMMEDIATELY, before any
|
|
329
386
|
// cancellable verify/mirror awaits below. A user-cancel during the
|
|
330
387
|
// post-write save-verify or mirror refresh throws codex_cancelled; if undo
|
|
@@ -333,7 +390,7 @@
|
|
|
333
390
|
// landed in Overleaf. The manual-confirm path already records undo right
|
|
334
391
|
// after its write — match that ordering here (v1.6.2).
|
|
335
392
|
appendApplyResult(applied);
|
|
336
|
-
recordUndoFromApply(project, applied);
|
|
393
|
+
await recordUndoFromApply(project, applied);
|
|
337
394
|
const skippedEntries = getSkippedEntries(applied);
|
|
338
395
|
if (skippedEntries.length) {
|
|
339
396
|
appendPartialWritebackWarning(applied);
|
|
@@ -342,36 +399,37 @@
|
|
|
342
399
|
renderReadOnlyDiffReview(getAppliedSyncChanges(syncChanges, applied));
|
|
343
400
|
}
|
|
344
401
|
const appliedPaths = getAppliedOperationPaths(applied);
|
|
402
|
+
appendRunEvent({
|
|
403
|
+
title: tx('Overleaf writeback returned its result.', 'Overleaf 写回已返回结果。'),
|
|
404
|
+
status: !hasConfirmedApplyResult || skippedEntries.length ? 'warning' : 'completed',
|
|
405
|
+
activity: { v: 1, kind: 'sync', id: writebackActivityId,
|
|
406
|
+
state: !hasConfirmedApplyResult || skippedEntries.length ? 'warning' : 'completed',
|
|
407
|
+
paths: operations.map(operation => operation.path).filter(Boolean),
|
|
408
|
+
written: appliedPaths.length, skipped: skippedEntries.length }
|
|
409
|
+
});
|
|
345
410
|
// Only probe save-state + refresh the mirror when real writes landed. A
|
|
346
411
|
// zero-write run (every operation skipped) has nothing to save-verify, so
|
|
347
412
|
// skip the ~5s probe and its misleading "could not verify saved" warning
|
|
348
413
|
// (v1.6.2).
|
|
349
|
-
const
|
|
350
|
-
? await verifyPostWriteSaveState()
|
|
351
|
-
: {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
reason: 'No applied writeback operations were returned.'
|
|
355
|
-
};
|
|
414
|
+
const confirmation = appliedPaths.length
|
|
415
|
+
? await verifyPostWriteSaveState(applied, project, saveTarget)
|
|
416
|
+
: { verification: { ok: false, state: 'not_checked', reason: 'No applied writeback operations were returned.' } };
|
|
417
|
+
const saveVerification = confirmation.verification;
|
|
418
|
+
await settleWritebackRecovery?.(applied, project, saveVerification, saveTarget);
|
|
356
419
|
if (appliedPaths.length) {
|
|
357
|
-
appendPostWriteSaveVerificationWarning(saveVerification);
|
|
420
|
+
appendPostWriteSaveVerificationWarning(saveVerification, saveTarget);
|
|
421
|
+
appendRunEvent({ kind: 'technical', title: 'Post-write save confirmation', status: 'info', detail: saveVerification });
|
|
358
422
|
}
|
|
359
423
|
// v1.7.5: the mirror refresh (zip snapshot + mirror.sync, often the
|
|
360
424
|
// slowest post-write step) no longer blocks the completion report. The
|
|
361
425
|
// pending promise is exposed so undoRun and the next runTask barrier on
|
|
362
426
|
// it — a mirror.sync landing AFTER an undo would otherwise push the
|
|
363
427
|
// pre-undo snapshot as the local baseline.
|
|
364
|
-
const mirrorSettlementTarget =
|
|
365
|
-
pendingMirrorRefresh = refreshProjectMirrorAfterWriteback(project, applied, saveVerification)
|
|
366
|
-
.catch(error => {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
`Overleaf was written, but the background workspace refresh failed: ${error.message}. The next run will reread the project.`,
|
|
370
|
-
`Overleaf 已写入,但后台刷新本地 workspace 失败:${error.message}。下一轮会重新读取项目。`
|
|
371
|
-
),
|
|
372
|
-
status: 'failed'
|
|
373
|
-
});
|
|
374
|
-
return 'failed';
|
|
428
|
+
const mirrorSettlementTarget = saveTarget;
|
|
429
|
+
pendingMirrorRefresh = refreshProjectMirrorAfterWriteback(project, applied, saveVerification, { target: saveTarget, snapshot: confirmation.snapshot })
|
|
430
|
+
.catch(async error => {
|
|
431
|
+
appendRunRecordEvent(saveTarget.recordId, { kind: 'technical', title: 'Mirror refresh requires a fresh read', status: 'info', detail: { reason: error.message } });
|
|
432
|
+
return invalidateWritebackMirror(saveTarget);
|
|
375
433
|
})
|
|
376
434
|
.then(state => {
|
|
377
435
|
if (typeof onMirrorRefreshSettled !== 'function') return;
|
|
@@ -388,7 +446,8 @@
|
|
|
388
446
|
const compileSummary = appliedPaths.length
|
|
389
447
|
? await autoRecompileAfterWriteback(appliedPaths, saveVerification, {
|
|
390
448
|
autoRecompile: options.autoRecompile,
|
|
391
|
-
mode: runMode
|
|
449
|
+
mode: runMode,
|
|
450
|
+
runProjectId: saveTarget.runProjectId
|
|
392
451
|
}).catch(error => {
|
|
393
452
|
appendRunEvent({
|
|
394
453
|
title: tx(`Post-write compile failed: ${error.message}`, `写后编译出错:${error.message}`),
|
|
@@ -435,6 +494,7 @@
|
|
|
435
494
|
compileErrors: compileSummary?.status === 'failed' && Array.isArray(compileSummary.errors)
|
|
436
495
|
? compileSummary.errors
|
|
437
496
|
: undefined,
|
|
497
|
+
saveVerification,
|
|
438
498
|
// Promote the primary per-operation skip failure to the run level when
|
|
439
499
|
// the writeback failed outright: target-file and write-stage codes only
|
|
440
500
|
// ever exist inside applied.skipped[], and without this promotion the
|
|
@@ -475,104 +535,100 @@
|
|
|
475
535
|
};
|
|
476
536
|
}
|
|
477
537
|
|
|
478
|
-
async function verifyPostWriteSaveState() {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
return {
|
|
493
|
-
...result,
|
|
494
|
-
ok: false,
|
|
495
|
-
state: 'verified_quiet'
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
|
-
if (result?.state === 'unknown_timeout' || result?.state === 'unavailable') {
|
|
499
|
-
return {
|
|
500
|
-
...result,
|
|
501
|
-
ok: false
|
|
502
|
-
};
|
|
503
|
-
}
|
|
504
|
-
return {
|
|
505
|
-
...result,
|
|
506
|
-
ok: false,
|
|
507
|
-
state: 'unknown_timeout'
|
|
508
|
-
};
|
|
509
|
-
} catch (error) {
|
|
510
|
-
return {
|
|
511
|
-
ok: false,
|
|
512
|
-
state: 'unavailable',
|
|
513
|
-
reason: error.message
|
|
514
|
-
};
|
|
515
|
-
}
|
|
538
|
+
async function verifyPostWriteSaveState(applied, project, target = {}) {
|
|
539
|
+
return writebackController.confirmPostWriteSave({
|
|
540
|
+
applied, project, runProjectId: target.runProjectId,
|
|
541
|
+
assertCurrent() {
|
|
542
|
+
if (!target.runProjectId || getCurrentProjectId() !== target.runProjectId) {
|
|
543
|
+
throw Object.assign(new Error('The Overleaf project changed during save confirmation.'), { code: 'aborted_project_changed', changedDocument: true });
|
|
544
|
+
}
|
|
545
|
+
if (target.recordId && getCurrentRunView()?.recordId !== target.recordId) {
|
|
546
|
+
throw Object.assign(new Error('The run stopped during save confirmation.'), { code: 'codex_cancelled', changedDocument: true });
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
readSaveState: params => callPageBridge('waitForSaveState', { ...params, runProjectId: target.runProjectId }),
|
|
550
|
+
readSnapshot: params => callPageBridge('getProjectSnapshot', { ...params, runProjectId: target.runProjectId })
|
|
551
|
+
});
|
|
516
552
|
}
|
|
517
553
|
|
|
518
|
-
function appendPostWriteSaveVerificationWarning(saveVerification = {}) {
|
|
519
|
-
if (saveVerification
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
'
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
});
|
|
554
|
+
function appendPostWriteSaveVerificationWarning(saveVerification = {}, target = {}) {
|
|
555
|
+
if (saveVerification.state === 'verified_saved') return;
|
|
556
|
+
// Missing confirmation is represented once in the report, with a check action.
|
|
557
|
+
if (saveVerification.signal !== 'offline') return;
|
|
558
|
+
const title = saveVerification.signal === 'offline'
|
|
559
|
+
? tx('Overleaf is offline. Keep this page open and reconnect so the changes can be saved.',
|
|
560
|
+
'Overleaf 当前离线。请保持页面开启,恢复连接后等待改动保存。')
|
|
561
|
+
: tx('Saving these changes is not yet confirmed. Keep this page open and check Overleaf’s save and connection status.',
|
|
562
|
+
'尚未确认本次改动已保存。请保持页面开启,检查 Overleaf 的保存和连接状态。');
|
|
563
|
+
if (target.recordId) appendRunRecordEvent(target.recordId, { title, status: 'warning' });
|
|
564
|
+
else appendRunEvent({ title, status: 'warning' });
|
|
529
565
|
}
|
|
530
566
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
// method — falls back to the full zip resync below.
|
|
538
|
-
const MIRROR_CONFIRMABLE_OPERATION_TYPES = new Set(['edit']);
|
|
539
|
-
|
|
540
|
-
async function tryConfirmMirrorWriteback(applied) {
|
|
541
|
-
const entries = Array.isArray(applied?.applied) ? applied.applied : [];
|
|
542
|
-
if (!entries.length) {
|
|
543
|
-
return false;
|
|
544
|
-
}
|
|
545
|
-
const paths = [];
|
|
546
|
-
for (const entry of entries) {
|
|
547
|
-
const operation = entry?.operation || {};
|
|
548
|
-
if (!MIRROR_CONFIRMABLE_OPERATION_TYPES.has(operation.type) || !operation.path) {
|
|
549
|
-
return false;
|
|
567
|
+
async function invalidateWritebackMirror(target = {}) {
|
|
568
|
+
let invalidated = false;
|
|
569
|
+
try {
|
|
570
|
+
if (target.runProjectId) {
|
|
571
|
+
const response = await sendBackgroundNative({ method: 'mirror.invalidate', params: { projectId: target.runProjectId } });
|
|
572
|
+
invalidated = response?.ok === true && response.result?.invalidated === true;
|
|
550
573
|
}
|
|
551
|
-
|
|
574
|
+
} catch (_error) { /* An unavailable host cannot acknowledge invalidation. */ }
|
|
575
|
+
let pageInvalidated = getCurrentProjectId() !== target.runProjectId;
|
|
576
|
+
if (!pageInvalidated) {
|
|
577
|
+
resetContextProject();
|
|
578
|
+
try {
|
|
579
|
+
const response = await callPageBridge('invalidateProjectSnapshot', { invalidateFileList: true, runProjectId: target.runProjectId });
|
|
580
|
+
pageInvalidated = response?.ok === true;
|
|
581
|
+
} catch (_error) { /* Leave the failure visible if both caches cannot be fenced. */ }
|
|
552
582
|
}
|
|
583
|
+
if (invalidated && pageInvalidated) return 'not-attempted';
|
|
584
|
+
const event = {
|
|
585
|
+
title: tx('The local project cache could not be reset. Check the local connection before starting another task.',
|
|
586
|
+
'本地项目缓存未能重置。请检查本地连接后再开始下一轮任务。'),
|
|
587
|
+
status: 'warning'
|
|
588
|
+
};
|
|
589
|
+
if (target.recordId) appendRunRecordEvent(target.recordId, event);
|
|
590
|
+
else appendRunEvent(event);
|
|
591
|
+
return 'failed';
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Text-only confirmation requires the page's verified post-image digest.
|
|
595
|
+
// Local files can change after writeback; Native must match those digests
|
|
596
|
+
// before advancing its baseline. Missing evidence and non-text/tree writes
|
|
597
|
+
// retain the authoritative ZIP fallback below.
|
|
598
|
+
|
|
599
|
+
async function tryConfirmMirrorWriteback(applied, runProjectId) {
|
|
553
600
|
try {
|
|
601
|
+
if (!runProjectId || getCurrentProjectId() !== runProjectId) return false;
|
|
602
|
+
const proof = await writebackController.buildMirrorWritebackConfirmation?.(applied);
|
|
603
|
+
if (!proof || getCurrentProjectId() !== runProjectId) return false;
|
|
554
604
|
const response = await sendBackgroundNative({
|
|
555
605
|
method: 'mirror.confirmWriteback',
|
|
556
606
|
params: {
|
|
557
|
-
projectId:
|
|
558
|
-
|
|
607
|
+
projectId: runProjectId,
|
|
608
|
+
...proof
|
|
559
609
|
}
|
|
560
610
|
});
|
|
561
|
-
|
|
611
|
+
const confirmations = Array.isArray(response?.result?.confirmed) ? response.result.confirmed : [];
|
|
612
|
+
const confirmed = new Map(confirmations.map(file => [file?.path, file?.hash]));
|
|
613
|
+
return getCurrentProjectId() === runProjectId && response?.ok === true && response?.result?.ok === true
|
|
614
|
+
&& confirmations.length === proof.expectedFiles.length
|
|
615
|
+
&& confirmed.size === proof.expectedFiles.length
|
|
616
|
+
&& proof.expectedFiles.every(file => confirmed.get(file.path) === file.sha256);
|
|
562
617
|
} catch (error) {
|
|
563
618
|
return false;
|
|
564
619
|
}
|
|
565
620
|
}
|
|
566
621
|
|
|
567
|
-
async function refreshProjectMirrorAfterWriteback(project = {}, applied = {}, saveVerification = {}) {
|
|
622
|
+
async function refreshProjectMirrorAfterWriteback(project = {}, applied = {}, saveVerification = {}, confirmation = {}) {
|
|
623
|
+
const target = confirmation.target || {};
|
|
568
624
|
if (saveVerification?.state !== 'verified_saved') {
|
|
569
|
-
return
|
|
625
|
+
return invalidateWritebackMirror(target);
|
|
570
626
|
}
|
|
571
627
|
if (!Array.isArray(applied?.applied) || !applied.applied.length) {
|
|
572
628
|
return 'not-attempted';
|
|
573
629
|
}
|
|
574
630
|
|
|
575
|
-
if (await tryConfirmMirrorWriteback(applied)) {
|
|
631
|
+
if (!confirmation.snapshot && await tryConfirmMirrorWriteback(applied, target.runProjectId)) {
|
|
576
632
|
appendRunEvent({
|
|
577
633
|
title: tx(
|
|
578
634
|
'Local Codex workspace confirmed in place (no project re-download needed). The next run starts from the latest content.',
|
|
@@ -588,10 +644,13 @@
|
|
|
588
644
|
status: 'running'
|
|
589
645
|
});
|
|
590
646
|
|
|
591
|
-
|
|
647
|
+
if (!target.runProjectId || getCurrentProjectId() !== target.runProjectId) return invalidateWritebackMirror(target);
|
|
648
|
+
if (!confirmation.snapshot) await callPageBridge('invalidateProjectSnapshot', {
|
|
649
|
+
runProjectId: target.runProjectId,
|
|
592
650
|
invalidateFileList: true
|
|
593
651
|
});
|
|
594
|
-
const freshProject = sanitizeRunProjectSnapshot(await callPageBridge('getProjectSnapshot', {
|
|
652
|
+
const freshProject = confirmation.snapshot || sanitizeRunProjectSnapshot(await callPageBridge('getProjectSnapshot', {
|
|
653
|
+
runProjectId: target.runProjectId,
|
|
595
654
|
force: true,
|
|
596
655
|
maxAgeMs: 0,
|
|
597
656
|
preferLightweight: true,
|
|
@@ -603,23 +662,18 @@
|
|
|
603
662
|
zipTimeoutMs: RUN_SNAPSHOT_ZIP_TIMEOUT_MS,
|
|
604
663
|
focusFiles: getAppliedOperationPaths(applied)
|
|
605
664
|
}));
|
|
606
|
-
if (
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
'Overleaf 已写入,但没有读到完整项目;暂不刷新本地 Codex workspace baseline,下一轮会重新读取。'
|
|
611
|
-
),
|
|
612
|
-
status: 'failed'
|
|
613
|
-
});
|
|
614
|
-
return 'failed';
|
|
665
|
+
if (getCurrentProjectId() !== target.runProjectId || freshProject?.id !== target.runProjectId
|
|
666
|
+
|| !freshProject?.files?.length || freshProject?.capabilities?.fullProjectSnapshot === false
|
|
667
|
+
|| freshProject?.capabilities?.skipped?.length) {
|
|
668
|
+
return invalidateWritebackMirror(target);
|
|
615
669
|
}
|
|
616
670
|
|
|
617
|
-
const syncedProject = mergeVerifiedAppliedFiles(freshProject, project, applied);
|
|
671
|
+
const syncedProject = confirmation.snapshot || mergeVerifiedAppliedFiles(freshProject, project, applied);
|
|
618
672
|
resetContextProject();
|
|
619
673
|
const response = await sendBackgroundNative({
|
|
620
674
|
method: 'mirror.sync',
|
|
621
675
|
params: {
|
|
622
|
-
projectId:
|
|
676
|
+
projectId: target.runProjectId,
|
|
623
677
|
project: syncedProject
|
|
624
678
|
}
|
|
625
679
|
});
|
|
@@ -631,15 +685,7 @@
|
|
|
631
685
|
return 'complete';
|
|
632
686
|
}
|
|
633
687
|
|
|
634
|
-
|
|
635
|
-
appendRunEvent({
|
|
636
|
-
title: tx(
|
|
637
|
-
`Overleaf was written, but refreshing the local workspace failed: ${message}`,
|
|
638
|
-
`Overleaf 已写入,但刷新本地 workspace 失败:${message}`
|
|
639
|
-
),
|
|
640
|
-
status: 'failed'
|
|
641
|
-
});
|
|
642
|
-
return 'failed';
|
|
688
|
+
return invalidateWritebackMirror(target);
|
|
643
689
|
}
|
|
644
690
|
|
|
645
691
|
function mergeVerifiedAppliedFiles(freshProject = {}, originalProject = {}, applied = {}) {
|
|
@@ -660,6 +706,8 @@
|
|
|
660
706
|
return writebackController.formatUnsupportedLocalChangeSummary(changes, getLocale());
|
|
661
707
|
}
|
|
662
708
|
|
|
709
|
+
const serverProvenSave = verification => ['overleaf-zip', 'server-receipts'].includes(verification?.source);
|
|
710
|
+
|
|
663
711
|
async function autoRecompileAfterWriteback(writtenPaths = [], saveVerification = {}, options = {}) {
|
|
664
712
|
if (options.autoRecompile === false
|
|
665
713
|
|| (options.autoRecompile === undefined && getState().autoRecompile === false)) return null;
|
|
@@ -671,7 +719,10 @@
|
|
|
671
719
|
const hasCompilableFile = writtenPaths.some(filePath => CompileAdapter.isCompilableFile(filePath));
|
|
672
720
|
if (!hasCompilableFile) return null;
|
|
673
721
|
|
|
722
|
+
const compileActivityId = 'overleaf-compile:' + Date.now().toString(36);
|
|
723
|
+
const activity = (state, output = '') => ({ v: 1, kind: 'compile', id: compileActivityId, state, target: 'Overleaf', output });
|
|
674
724
|
appendRunEvent({
|
|
725
|
+
activity: activity('running'),
|
|
675
726
|
title: saveVerification?.state !== 'verified_saved'
|
|
676
727
|
? tx(
|
|
677
728
|
'Post-write compile: Overleaf save was not verified, but Auto Compile is on. Triggering Overleaf Recompile and letting Overleaf wait for the latest save.',
|
|
@@ -687,9 +738,10 @@
|
|
|
687
738
|
try {
|
|
688
739
|
const result = await callPageBridge('triggerCompile', {
|
|
689
740
|
preferUiClick: true,
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
741
|
+
// Server-side proof (ZIP or save receipts) already settles the save; don't also demand the UI indicator.
|
|
742
|
+
waitForSaveMs: serverProvenSave(saveVerification) ? 0 : 5000,
|
|
743
|
+
requireVerifiedSave: saveVerification?.state === 'verified_saved' && !serverProvenSave(saveVerification),
|
|
744
|
+
runProjectId: options.runProjectId || getCurrentRunView()?.runProjectId || getCurrentProjectId()
|
|
693
745
|
});
|
|
694
746
|
if (result?.ok) {
|
|
695
747
|
let logResult = null;
|
|
@@ -698,79 +750,42 @@
|
|
|
698
750
|
triggerIfStale: false,
|
|
699
751
|
maxAgeMs: 30000,
|
|
700
752
|
waitForSaveMs: 0,
|
|
701
|
-
runProjectId: getCurrentRunView()?.runProjectId || getCurrentProjectId()
|
|
753
|
+
runProjectId: options.runProjectId || getCurrentRunView()?.runProjectId || getCurrentProjectId()
|
|
702
754
|
});
|
|
703
755
|
} catch (_error) {
|
|
704
756
|
logResult = null;
|
|
705
757
|
}
|
|
706
758
|
const compile = result.compile;
|
|
707
759
|
if (compile?.status === 'success') {
|
|
708
|
-
appendRunEvent({ title: tx('Compile succeeded.', '编译成功。'), status: 'completed'
|
|
760
|
+
appendRunEvent({ title: tx('Compile succeeded.', '编译成功。'), status: 'completed',
|
|
761
|
+
activity: activity('completed', [...(logResult?.errors || []), ...(logResult?.warnings || [])].slice(0, 5).map(CompileAdapter.formatCompileDiagnosticForSummary).join('\n')) });
|
|
709
762
|
} else if (compile?.status === 'triggered') {
|
|
710
|
-
appendRunEvent({ title: tx('Overleaf compile was triggered. The page will continue showing progress.', '已触发 Overleaf 编译;页面会继续显示编译进度。'), status: 'completed' });
|
|
763
|
+
appendRunEvent({ title: tx('Overleaf compile was triggered. The page will continue showing progress.', '已触发 Overleaf 编译;页面会继续显示编译进度。'), status: 'completed', activity: activity('triggered') });
|
|
711
764
|
} else {
|
|
712
|
-
appendRunEvent({ title: tx(`Compile finished with status: ${compile?.status || 'unknown'}`, `编译完成,状态:${compile?.status || '未知'}`), status: 'completed' });
|
|
765
|
+
appendRunEvent({ title: tx(`Compile finished with status: ${compile?.status || 'unknown'}`, `编译完成,状态:${compile?.status || '未知'}`), status: 'completed', activity: activity(compile?.status === 'failed' ? 'failed' : 'unknown') });
|
|
713
766
|
}
|
|
714
767
|
return buildPostWriteCompileSummary({ result, logResult });
|
|
715
768
|
} else {
|
|
716
|
-
const reason = result?.reason || tx('unknown reason', '未知原因');
|
|
717
|
-
appendRunEvent({ title: tx(`Post-write compile did not succeed: ${reason}`, `写后编译未成功:${reason}`), status: 'failed' });
|
|
769
|
+
const reason = CompileAdapter.localizeCompileReason(result?.reason, getLocale()) || tx('unknown reason', '未知原因');
|
|
770
|
+
appendRunEvent({ title: tx(`Post-write compile did not succeed: ${reason}`, `写后编译未成功:${reason}`), status: 'failed', activity: activity('failed', reason) });
|
|
718
771
|
return buildPostWriteCompileSummary({ result });
|
|
719
772
|
}
|
|
720
773
|
} catch (error) {
|
|
721
|
-
|
|
774
|
+
const reason = CompileAdapter.localizeCompileReason(error.message, getLocale());
|
|
775
|
+
appendRunEvent({ title: tx(`Post-write compile failed: ${reason}`, `写后编译出错:${reason}`), status: 'failed', activity: activity('failed', reason) });
|
|
722
776
|
return buildPostWriteCompileSummary({ error });
|
|
723
777
|
}
|
|
724
778
|
}
|
|
725
779
|
|
|
726
|
-
function buildPostWriteCompileSummary(
|
|
727
|
-
|
|
728
|
-
const errors = logAvailable && Array.isArray(logResult.errors)
|
|
729
|
-
? logResult.errors.slice(0, 5).map(formatCompileDiagnosticForSummary)
|
|
730
|
-
: [];
|
|
731
|
-
const warnings = logAvailable && Array.isArray(logResult.warnings)
|
|
732
|
-
? logResult.warnings.slice(0, 5).map(formatCompileDiagnosticForSummary)
|
|
733
|
-
: [];
|
|
734
|
-
if (error) {
|
|
735
|
-
return {
|
|
736
|
-
status: 'failed',
|
|
737
|
-
reason: error?.message || 'Post-write compile failed.',
|
|
738
|
-
errors,
|
|
739
|
-
warnings,
|
|
740
|
-
logAvailable
|
|
741
|
-
};
|
|
742
|
-
}
|
|
743
|
-
if (!result?.ok) {
|
|
744
|
-
return {
|
|
745
|
-
status: 'failed',
|
|
746
|
-
reason: result?.reason || 'Post-write compile did not succeed.',
|
|
747
|
-
errors,
|
|
748
|
-
warnings,
|
|
749
|
-
logAvailable
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
|
-
return {
|
|
753
|
-
status: result.compile?.status || 'triggered',
|
|
754
|
-
reason: result.reason || '',
|
|
755
|
-
errors,
|
|
756
|
-
warnings,
|
|
757
|
-
logAvailable
|
|
758
|
-
};
|
|
780
|
+
function buildPostWriteCompileSummary(input = {}) {
|
|
781
|
+
return compileAdapter.buildPostWriteCompileSummary(input);
|
|
759
782
|
}
|
|
760
783
|
|
|
761
|
-
//
|
|
762
|
-
//
|
|
784
|
+
// Use the same normalized failure selection as settlement and its UI, while
|
|
785
|
+
// preserving the selected producer's full evidence on the historical report.
|
|
763
786
|
function promoteWritebackSkippedFailure(applied) {
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
if (failure?.code) {
|
|
767
|
-
if (!failure.file && entry?.path) {
|
|
768
|
-
return { ...failure, file: entry.path };
|
|
769
|
-
}
|
|
770
|
-
return failure;
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
return null;
|
|
787
|
+
const failures = writebackSettlement.collectFailuresFromResult(applied);
|
|
788
|
+
return writebackSettlement.selectPrimaryFailure(failures);
|
|
774
789
|
}
|
|
775
790
|
|
|
776
791
|
function appendCompileSummaryToConclusion(conclusion, compileSummary) {
|
|
@@ -800,9 +815,10 @@
|
|
|
800
815
|
)
|
|
801
816
|
: tx('Post-write compile was triggered; Overleaf may still be updating the result.', '已触发写后编译;Overleaf 可能仍在更新结果。');
|
|
802
817
|
} else if (compileSummary.status === 'failed') {
|
|
818
|
+
const reason = compileAdapter.localizeCompileReason(compileSummary.reason, getLocale());
|
|
803
819
|
summary = tx(
|
|
804
|
-
`Post-write compile check failed: ${
|
|
805
|
-
`写后编译检查失败:${
|
|
820
|
+
`Post-write compile check failed: ${reason || 'unknown reason'}`,
|
|
821
|
+
`写后编译检查失败:${reason || '未知原因'}`
|
|
806
822
|
);
|
|
807
823
|
} else {
|
|
808
824
|
summary = tx(
|
|
@@ -813,10 +829,6 @@
|
|
|
813
829
|
return [conclusion, '', summary].filter(Boolean).join('\n');
|
|
814
830
|
}
|
|
815
831
|
|
|
816
|
-
function formatCompileDiagnosticForSummary(value) {
|
|
817
|
-
const text = String(value || '').replace(/\s+/g, ' ').trim();
|
|
818
|
-
return text.length > 180 ? `${text.slice(0, 179)}...` : text;
|
|
819
|
-
}
|
|
820
832
|
|
|
821
833
|
async function resolveCompileLogContext() {
|
|
822
834
|
try {
|
|
@@ -891,6 +903,8 @@
|
|
|
891
903
|
getCurrentRunView,
|
|
892
904
|
} = deps);
|
|
893
905
|
assetTransferBroker = deps.assetTransferBroker;
|
|
906
|
+
stageWritebackRecovery = deps.stageWritebackRecovery;
|
|
907
|
+
settleWritebackRecovery = deps.settleWritebackRecovery;
|
|
894
908
|
onMirrorRefreshSettled = deps.onMirrorRefreshSettled;
|
|
895
909
|
writebackSettlement = deps.writebackSettlement;
|
|
896
910
|
compileAdapter = deps.compileAdapter;
|