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
package/extension/src/popup.js
CHANGED
|
@@ -1,75 +1,218 @@
|
|
|
1
1
|
(function initPopup() {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
// Keep only copy produced by this popup eligible for a language refresh.
|
|
5
|
+
const popupCopyPairs = new Map();
|
|
6
|
+
let newSiteCopyNodes = [];
|
|
7
|
+
|
|
8
|
+
const popupScriptUrl = document.currentScript?.src || chrome.runtime.getURL('src/popup.js');
|
|
9
|
+
ensureMinimalPopupShell();
|
|
4
10
|
const CodexOverleafCompatibility = window.CodexOverleafCompatibility;
|
|
5
|
-
const
|
|
11
|
+
const isManagedInstall = chrome.runtime.getManifest()?.background?.service_worker === 'bootstrap/background.js'
|
|
12
|
+
|| window.__CODEX_OVERLEAF_RUNTIME_PREFIX__ === 'runtime/';
|
|
13
|
+
let installIdentity = { managed: isManagedInstall };
|
|
14
|
+
const DEFAULT_INSTALL_COMMAND = isManagedInstall ? '' : CodexOverleafCompatibility?.buildInstallCommand?.(
|
|
6
15
|
undefined,
|
|
7
16
|
undefined,
|
|
8
17
|
getCurrentExtensionId()
|
|
9
18
|
) || 'curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/main/install.sh | bash -s -- --extension-id <chrome-extension-id>';
|
|
10
|
-
const
|
|
19
|
+
const launcherToggle = document.getElementById('launcher-toggle');
|
|
11
20
|
const status = document.getElementById('status');
|
|
21
|
+
const connectionToggle = document.getElementById('connection-toggle');
|
|
22
|
+
const connectionDetails = document.getElementById('connection-details');
|
|
23
|
+
const connectionLabel = document.getElementById('connection-label');
|
|
12
24
|
const compatStatusIcon = document.getElementById('compat-status-icon');
|
|
13
|
-
const
|
|
25
|
+
const extensionVersionLabel = document.getElementById('extension-version');
|
|
26
|
+
const nativeVersionLabel = document.getElementById('native-version');
|
|
14
27
|
const nativeInstall = document.getElementById('native-install');
|
|
28
|
+
const nativeStatusMessage = document.getElementById('native-status-message');
|
|
15
29
|
const installCommand = document.getElementById('install-command');
|
|
16
30
|
const copyInstallCommand = document.getElementById('copy-install-command');
|
|
31
|
+
const copyFeedback = document.getElementById('copy-feedback');
|
|
17
32
|
let activeOverleafTab = null;
|
|
18
33
|
let currentInstallCommand = DEFAULT_INSTALL_COMMAND;
|
|
34
|
+
let lastCompatibility = null;
|
|
35
|
+
let launcherVisible = false;
|
|
36
|
+
let launcherReady = false;
|
|
19
37
|
|
|
20
38
|
installCommand.textContent = currentInstallCommand;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
39
|
+
setVersionStatus({ status: 'checking', extensionVersion: getExtensionCompatibilityMetadata().version });
|
|
40
|
+
|
|
41
|
+
connectionToggle.addEventListener('click', () => {
|
|
42
|
+
connectionDetails.hidden = !connectionDetails.hidden;
|
|
43
|
+
connectionToggle.setAttribute('aria-expanded', String(!connectionDetails.hidden));
|
|
26
44
|
});
|
|
27
45
|
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
46
|
+
launcherToggle.addEventListener('change', async () => {
|
|
47
|
+
const desired = launcherToggle.checked;
|
|
48
|
+
launcherToggle.disabled = true;
|
|
49
|
+
setLauncherStatus('');
|
|
50
|
+
try {
|
|
51
|
+
const tab = await getActiveOverleafProjectTab();
|
|
52
|
+
if (!tab?.id) throw new Error(utx('Open an Overleaf project tab first.', '请先打开 Overleaf 项目页。'));
|
|
53
|
+
activeOverleafTab = tab;
|
|
54
|
+
const before = await chrome.tabs.sendMessage(tab.id, { type: 'codex-overleaf/get-panel-state' });
|
|
55
|
+
if (typeof before?.launcherVisible !== 'boolean') {
|
|
56
|
+
throw new Error(utx('Refresh the Overleaf tab, then reopen this popup.', '请刷新 Overleaf 页面,再打开此弹窗。'));
|
|
57
|
+
}
|
|
58
|
+
// Keep the existing visibility contract. Do not open or close the panel.
|
|
59
|
+
if (before.launcherVisible !== desired) {
|
|
60
|
+
const response = await chrome.tabs.sendMessage(tab.id, { type: 'codex-overleaf/toggle-launcher' });
|
|
61
|
+
if (response?.ok === false) throw new Error(response.error?.message || response.error
|
|
62
|
+
|| utx('The side button could not be changed.', '侧边入口设置未能修改。'));
|
|
63
|
+
}
|
|
64
|
+
const after = await chrome.tabs.sendMessage(tab.id, { type: 'codex-overleaf/get-panel-state' });
|
|
65
|
+
if (typeof after?.launcherVisible !== 'boolean' || after.launcherVisible !== desired) {
|
|
66
|
+
throw new Error(utx('The side button state could not be confirmed. Reopen this popup to retry.',
|
|
67
|
+
'未能确认侧边入口状态,请重新打开此弹窗后重试。'));
|
|
68
|
+
}
|
|
69
|
+
launcherVisible = after.launcherVisible;
|
|
70
|
+
launcherReady = true;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
launcherReady = false;
|
|
73
|
+
setLauncherStatus(error?.message || utx('Refresh the Overleaf tab and try again.', '请刷新 Overleaf 页面后重试。'), true);
|
|
74
|
+
} finally {
|
|
75
|
+
launcherToggle.checked = launcherVisible;
|
|
76
|
+
launcherToggle.disabled = !launcherReady;
|
|
33
77
|
}
|
|
34
|
-
|
|
35
|
-
await chrome.tabs.sendMessage(tab.id, { type: 'codex-overleaf/toggle-launcher' });
|
|
36
|
-
window.close();
|
|
37
78
|
});
|
|
38
79
|
|
|
39
80
|
copyInstallCommand.addEventListener('click', async () => {
|
|
40
|
-
|
|
41
|
-
copyInstallCommand.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
81
|
+
if (!currentInstallCommand) return;
|
|
82
|
+
copyInstallCommand.disabled = true;
|
|
83
|
+
copyFeedback.hidden = true;
|
|
84
|
+
try {
|
|
85
|
+
await navigator.clipboard.writeText(currentInstallCommand);
|
|
86
|
+
copyInstallCommand.textContent = utx('Copied', '已复制');
|
|
87
|
+
setTimeout(() => { copyInstallCommand.textContent = utx('Copy install command', '复制安装命令'); }, 1400);
|
|
88
|
+
} catch (_error) {
|
|
89
|
+
copyFeedback.textContent = utx('Copy failed. Select the command above to copy it.', '复制失败,可选中上方命令复制。');
|
|
90
|
+
copyFeedback.hidden = false;
|
|
91
|
+
} finally {
|
|
92
|
+
copyInstallCommand.disabled = !currentInstallCommand;
|
|
93
|
+
}
|
|
45
94
|
});
|
|
46
95
|
|
|
47
96
|
initPopupState();
|
|
48
97
|
scheduleConsentUpdateUi();
|
|
49
98
|
|
|
99
|
+
// Older managed installations keep their bootstrap HTML across runtime
|
|
100
|
+
// updates. Upgrade only this popup's shell, leaving runtime behavior shared.
|
|
101
|
+
function ensureMinimalPopupShell() {
|
|
102
|
+
document.documentElement.classList.add('popup-minimal-root');
|
|
103
|
+
document.body.classList.add('popup-minimal');
|
|
104
|
+
if (!document.getElementById('launcher-toggle')) {
|
|
105
|
+
const shell = document.createElement('div');
|
|
106
|
+
shell.innerHTML = "<main id=\"popup-shell\">\n <header class=\"popup-header\">\n <img id=\"brand-icon\" class=\"popup-icon\" src=\"assets/icons/icon128.png\" width=\"32\" height=\"32\" alt=\"\">\n <div class=\"popup-brand\">\n <h1>Codex Overleaf Link</h1>\n <button id=\"connection-toggle\" class=\"connection-toggle\" type=\"button\" aria-expanded=\"false\" aria-controls=\"connection-details\">\n <span id=\"compat-status-icon\" class=\"status-icon pending\" aria-hidden=\"true\"></span>\n <span id=\"connection-label\">Checking connection...</span>\n <span class=\"connection-chevron\" aria-hidden=\"true\"></span>\n </button>\n </div>\n </header>\n <section id=\"connection-details\" class=\"connection-details\" aria-label=\"Version details\" hidden>\n <dl id=\"version-pair\">\n <div><dt id=\"extension-version-label\">Extension</dt><dd id=\"extension-version\">Unknown</dd></div>\n <div><dt>Native Host</dt><dd id=\"native-version\">Checking...</dd></div>\n </dl>\n </section>\n <label class=\"launcher-setting\" for=\"launcher-toggle\">\n <span class=\"launcher-copy\">\n <strong id=\"launcher-label\">Show Codex side button</strong>\n <small id=\"launcher-description\">When the panel is closed</small>\n </span>\n <input id=\"launcher-toggle\" class=\"launcher-toggle\" type=\"checkbox\" aria-describedby=\"launcher-description\" disabled>\n </label>\n <p id=\"status\" class=\"popup-note\" role=\"status\" aria-live=\"polite\" hidden></p>\n <section id=\"native-install\" class=\"install\" aria-labelledby=\"native-install-title\" hidden>\n <strong id=\"native-install-title\">Native host attention required</strong>\n <p id=\"native-status-message\"></p>\n <code id=\"install-command\"></code>\n <button id=\"copy-install-command\" class=\"copy-command\" type=\"button\">Copy install command</button>\n <p id=\"copy-feedback\" class=\"copy-feedback\" role=\"status\" hidden></p>\n </section>\n</main>";
|
|
107
|
+
for (const element of Array.from(document.body.children)) {
|
|
108
|
+
if (element.tagName !== 'SCRIPT') element.remove();
|
|
109
|
+
}
|
|
110
|
+
document.body.prepend(shell.firstElementChild);
|
|
111
|
+
}
|
|
112
|
+
document.getElementById('brand-icon').src = chrome.runtime.getURL('assets/icons/icon128.png');
|
|
113
|
+
let stylesheet = document.getElementById('popup-styles');
|
|
114
|
+
if (!stylesheet) {
|
|
115
|
+
stylesheet = document.createElement('link');
|
|
116
|
+
stylesheet.id = 'popup-styles';
|
|
117
|
+
stylesheet.rel = 'stylesheet';
|
|
118
|
+
document.head.append(stylesheet);
|
|
119
|
+
}
|
|
120
|
+
stylesheet.href = new URL('../styles/popup.css', popupScriptUrl).href;
|
|
121
|
+
}
|
|
122
|
+
|
|
50
123
|
async function initPopupState() {
|
|
51
|
-
|
|
52
|
-
|
|
124
|
+
try {
|
|
125
|
+
const stored = await chrome.storage.local.get(['codexOverleafGlobalPrefsV1', 'codexOverleafPrefs']);
|
|
126
|
+
applyPopupPreferences(stored.codexOverleafGlobalPrefsV1?.values || stored.codexOverleafPrefs || {});
|
|
127
|
+
} catch (_error) { applyPopupPreferences({}); }
|
|
128
|
+
chrome.storage.onChanged?.addListener((changes, area) => {
|
|
129
|
+
if (area === 'local' && changes.codexOverleafGlobalPrefsV1?.newValue?.values) {
|
|
130
|
+
applyPopupPreferences(changes.codexOverleafGlobalPrefsV1.newValue.values);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
await Promise.all([checkNativeHost(), refreshPanelButtonState(), offerNewSites()]);
|
|
53
134
|
}
|
|
54
135
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (!
|
|
59
|
-
|
|
60
|
-
|
|
136
|
+
// A runtime update can list an Overleaf site the install did not grant.
|
|
137
|
+
// Chrome only grants it from a click here; nothing changes until then.
|
|
138
|
+
async function offerNewSites() {
|
|
139
|
+
if (!chrome.permissions?.contains || !chrome.permissions?.request) return;
|
|
140
|
+
let matches = [];
|
|
141
|
+
try {
|
|
142
|
+
const url = new URL('../runtime-manifest.json', popupScriptUrl).href;
|
|
143
|
+
matches = (await (await fetch(url, { cache: 'no-store' })).json()).matches || [];
|
|
144
|
+
} catch (_error) { return; }
|
|
145
|
+
const missing = [];
|
|
146
|
+
for (const value of matches) {
|
|
147
|
+
if (!/^https:\/\/(?:[a-z0-9-]+\.)*overleaf\.com\/project(?:\/\*)?$/.test(value)) continue;
|
|
148
|
+
if (!(await chrome.permissions.contains({ origins: [value] }).catch(() => true))) missing.push(value);
|
|
61
149
|
}
|
|
150
|
+
if (!missing.length) return;
|
|
151
|
+
const hosts = [...new Set(missing.map(value => new URL(value.replace(/\*$/, '')).host))];
|
|
152
|
+
const section = document.createElement('section');
|
|
153
|
+
section.className = 'install';
|
|
154
|
+
section.dataset.newSites = '';
|
|
155
|
+
const title = document.createElement('strong');
|
|
156
|
+
title.textContent = utx('This version supports another Overleaf site', '这一版支持新的 Overleaf 站点');
|
|
157
|
+
const detail = document.createElement('p');
|
|
158
|
+
detail.textContent = utx(`Allow access to ${hosts.join(', ')} to use Codex there. Chrome will ask you to confirm.`,
|
|
159
|
+
`允许访问 ${hosts.join('、')} 后即可在那里使用 Codex,Chrome 会请你确认。`);
|
|
160
|
+
const button = document.createElement('button');
|
|
161
|
+
button.type = 'button';
|
|
162
|
+
button.className = 'copy-command';
|
|
163
|
+
button.textContent = utx('Allow', '允许');
|
|
164
|
+
button.addEventListener('click', async () => {
|
|
165
|
+
const granted = await chrome.permissions.request({ origins: missing }).catch(() => false);
|
|
166
|
+
if (granted) section.remove();
|
|
167
|
+
});
|
|
168
|
+
newSiteCopyNodes = [title, detail, button];
|
|
169
|
+
section.append(title, detail, button);
|
|
170
|
+
document.getElementById('popup-shell')?.append(section);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function applyPopupPreferences(preferences) {
|
|
174
|
+
document.documentElement.lang = preferences.locale === 'zh' ? 'zh-CN' : 'en';
|
|
175
|
+
document.documentElement.dataset.popupTheme = ['light', 'dark', 'auto'].includes(preferences.theme)
|
|
176
|
+
? preferences.theme : 'dark';
|
|
177
|
+
document.getElementById('launcher-label').textContent = utx('Show Codex side button', '显示 Codex 侧边入口');
|
|
178
|
+
document.getElementById('launcher-description').textContent = utx('When the panel is closed', '面板关闭时显示');
|
|
179
|
+
document.getElementById('extension-version-label').textContent = utx('Extension', '扩展');
|
|
180
|
+
document.getElementById('native-install-title').textContent = utx('Local connection needs attention', '本地连接需要处理');
|
|
181
|
+
connectionDetails.setAttribute('aria-label', utx('Version details', '版本信息'));
|
|
182
|
+
connectionToggle.title = utx('Show or hide version details', '展开或收起版本信息');
|
|
183
|
+
copyInstallCommand.textContent = utx('Copy install command', '复制安装命令');
|
|
184
|
+
[status, copyFeedback, ...newSiteCopyNodes].forEach(refreshPopupCopy);
|
|
185
|
+
if (lastCompatibility) {
|
|
186
|
+
setVersionStatus(lastCompatibility);
|
|
187
|
+
if (!nativeInstall.hidden) showNativeInstallGuide(lastCompatibility);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function setLauncherStatus(message, failed = false) {
|
|
192
|
+
status.textContent = message;
|
|
193
|
+
status.hidden = !message;
|
|
194
|
+
status.setAttribute('role', failed ? 'alert' : 'status');
|
|
195
|
+
}
|
|
62
196
|
|
|
197
|
+
async function refreshPanelButtonState() {
|
|
198
|
+
launcherReady = false;
|
|
199
|
+
launcherToggle.disabled = true;
|
|
63
200
|
try {
|
|
201
|
+
const tab = await getActiveOverleafProjectTab();
|
|
202
|
+
activeOverleafTab = tab;
|
|
203
|
+
if (!tab?.id) {
|
|
204
|
+
setLauncherStatus(utx('Open an Overleaf project to change this preference.', '打开 Overleaf 项目页后可设置侧边入口。'));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
64
207
|
const response = await chrome.tabs.sendMessage(tab.id, { type: 'codex-overleaf/get-panel-state' });
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
208
|
+
if (typeof response?.launcherVisible !== 'boolean') throw new Error('Panel state unavailable');
|
|
209
|
+
launcherVisible = response.launcherVisible;
|
|
210
|
+
launcherReady = true;
|
|
211
|
+
launcherToggle.checked = launcherVisible;
|
|
212
|
+
launcherToggle.disabled = false;
|
|
213
|
+
setLauncherStatus('');
|
|
70
214
|
} catch (_error) {
|
|
71
|
-
|
|
72
|
-
status.textContent = 'Refresh the Overleaf tab, then show the Codex button.';
|
|
215
|
+
setLauncherStatus(utx('Refresh the Overleaf tab, then reopen this popup.', '请刷新 Overleaf 页面,再打开此弹窗。'));
|
|
73
216
|
}
|
|
74
217
|
}
|
|
75
218
|
|
|
@@ -79,10 +222,11 @@
|
|
|
79
222
|
}
|
|
80
223
|
|
|
81
224
|
function isOverleafProjectUrl(url) {
|
|
82
|
-
return /^https:\/\/(www\.)?overleaf\.com\/project\//.test(String(url || ''));
|
|
225
|
+
return /^https:\/\/(?:(?:www|cn)\.)?overleaf\.com\/project\//.test(String(url || ''));
|
|
83
226
|
}
|
|
84
227
|
|
|
85
228
|
async function checkNativeHost() {
|
|
229
|
+
await readInstallIdentity();
|
|
86
230
|
try {
|
|
87
231
|
const response = await chrome.runtime.sendMessage({
|
|
88
232
|
type: 'codex-overleaf/native-request',
|
|
@@ -96,16 +240,13 @@
|
|
|
96
240
|
setVersionStatus(compatibility);
|
|
97
241
|
if (getCompatibilityClassification(compatibility) === 'compatible') {
|
|
98
242
|
nativeInstall.hidden = true;
|
|
99
|
-
status.textContent = 'Native host connected. Open an Overleaf project tab to use Codex.';
|
|
100
243
|
return;
|
|
101
244
|
}
|
|
102
245
|
showNativeInstallGuide(compatibility);
|
|
103
246
|
} catch (_error) {
|
|
104
247
|
const compatibility = {
|
|
105
|
-
status: 'native_missing',
|
|
106
|
-
|
|
107
|
-
installCommand: DEFAULT_INSTALL_COMMAND,
|
|
108
|
-
updateCommand: DEFAULT_INSTALL_COMMAND,
|
|
248
|
+
status: 'native_missing', classification: 'incompatible',
|
|
249
|
+
installCommand: DEFAULT_INSTALL_COMMAND, updateCommand: DEFAULT_INSTALL_COMMAND,
|
|
109
250
|
extensionVersion: getExtensionCompatibilityMetadata().version
|
|
110
251
|
};
|
|
111
252
|
setVersionStatus(compatibility);
|
|
@@ -113,11 +254,29 @@
|
|
|
113
254
|
}
|
|
114
255
|
}
|
|
115
256
|
|
|
257
|
+
async function readInstallIdentity() {
|
|
258
|
+
if (!isManagedInstall) return;
|
|
259
|
+
try {
|
|
260
|
+
const response = await fetch(chrome.runtime.getURL('.codex-overleaf-managed-extension.json'));
|
|
261
|
+
const marker = response.ok ? await response.json() : null;
|
|
262
|
+
if (marker?.managedBy === 'codex-overleaf-link' && marker.kind === 'extension'
|
|
263
|
+
&& marker.installIdentity?.extensionId === getCurrentExtensionId()) {
|
|
264
|
+
installIdentity = { ...marker.installIdentity, managed: true };
|
|
265
|
+
}
|
|
266
|
+
} catch (_) { /* Older markers cannot prove the original root or browser. */ }
|
|
267
|
+
}
|
|
268
|
+
|
|
116
269
|
function showNativeInstallGuide(compatibility = {}) {
|
|
117
270
|
nativeInstall.hidden = false;
|
|
118
271
|
currentInstallCommand = getCompatibilityUpdateCommand(compatibility);
|
|
119
272
|
installCommand.textContent = currentInstallCommand;
|
|
120
|
-
|
|
273
|
+
copyInstallCommand.disabled = !currentInstallCommand;
|
|
274
|
+
nativeStatusMessage.textContent = !currentInstallCommand && isManagedInstall
|
|
275
|
+
? utx('Repair this Managed installation using its original managed root, browser and extension ID. Rerun the original install-managed command with those parameters.',
|
|
276
|
+
'修复此托管安装需要原管理根目录、浏览器和扩展 ID。请使用这些原参数重新运行 install-managed 安装命令。')
|
|
277
|
+
: getNativeStatusMessage(compatibility.status, getCompatibilityClassification(compatibility))
|
|
278
|
+
+ ((compatibility.native?.platform || installIdentity.platform) === 'win32' && isManagedInstall
|
|
279
|
+
? utx(' Run the command in PowerShell.', ' 请在 PowerShell 中运行该命令。') : '');
|
|
121
280
|
}
|
|
122
281
|
|
|
123
282
|
function evaluateNativeCompatibility(response) {
|
|
@@ -146,17 +305,25 @@
|
|
|
146
305
|
}
|
|
147
306
|
|
|
148
307
|
function setVersionStatus(compatibility = {}) {
|
|
149
|
-
|
|
308
|
+
lastCompatibility = compatibility;
|
|
309
|
+
const pending = compatibility.status === 'checking';
|
|
310
|
+
const classification = pending ? 'pending' : getCompatibilityClassification(compatibility);
|
|
150
311
|
const extensionVersion = compatibility.extensionVersion || getExtensionCompatibilityMetadata().version;
|
|
151
312
|
const nativeVersion = compatibility.currentNativeVersion || compatibility.nativeVersion || compatibility.native?.version;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if (
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
313
|
+
extensionVersionLabel.textContent = formatVersion(extensionVersion);
|
|
314
|
+
nativeVersionLabel.textContent = pending ? utx('Checking...', '正在检查...') : formatVersion(nativeVersion);
|
|
315
|
+
let label = utx('Update required', '需要更新');
|
|
316
|
+
if (pending) label = utx('Checking connection...', '正在检查连接...');
|
|
317
|
+
else if (classification === 'compatible') label = utx('Connected', '已连接');
|
|
318
|
+
else if (classification === 'update-available') label = utx('Update available', '有可用更新');
|
|
319
|
+
else if (compatibility.status === 'native_missing') label = utx('Not connected', '未连接');
|
|
320
|
+
else if (compatibility.status === 'native_unhealthy') label = utx('Needs attention', '需要处理');
|
|
321
|
+
connectionLabel.textContent = label;
|
|
322
|
+
connectionToggle.setAttribute('aria-label', label + '. ' + utx('Version details', '版本信息'));
|
|
323
|
+
compatStatusIcon.textContent = '';
|
|
324
|
+
compatStatusIcon.className = 'status-icon ' + classification;
|
|
325
|
+
compatStatusIcon.title = label;
|
|
326
|
+
compatStatusIcon.dataset.status = classification;
|
|
160
327
|
}
|
|
161
328
|
|
|
162
329
|
function getExtensionCompatibilityMetadata() {
|
|
@@ -164,7 +331,8 @@
|
|
|
164
331
|
version: CodexOverleafCompatibility?.BUILD_TARGET_VERSION ||
|
|
165
332
|
chrome.runtime.getManifest?.().version ||
|
|
166
333
|
'',
|
|
167
|
-
extensionId: getCurrentExtensionId()
|
|
334
|
+
extensionId: getCurrentExtensionId(),
|
|
335
|
+
...(isManagedInstall ? { installIdentity } : {})
|
|
168
336
|
};
|
|
169
337
|
}
|
|
170
338
|
|
|
@@ -192,8 +360,9 @@
|
|
|
192
360
|
return CodexOverleafCompatibility?.buildInstallCommand?.(
|
|
193
361
|
compatibility.recommendedVersion || CodexOverleafCompatibility.BUILD_TARGET_VERSION,
|
|
194
362
|
compatibility.native?.platform || compatibility.platform,
|
|
195
|
-
getCurrentExtensionId()
|
|
196
|
-
|
|
363
|
+
getCurrentExtensionId(),
|
|
364
|
+
installIdentity
|
|
365
|
+
) || (isManagedInstall ? '' : compatibility.updateCommand || compatibility.installCommand || DEFAULT_INSTALL_COMMAND);
|
|
197
366
|
}
|
|
198
367
|
|
|
199
368
|
function getStatusIconText(classification) {
|
|
@@ -221,28 +390,33 @@
|
|
|
221
390
|
function formatVersion(version) {
|
|
222
391
|
const value = String(version || '').trim();
|
|
223
392
|
if (!value) {
|
|
224
|
-
return '
|
|
393
|
+
return utx('Unknown', '未知');
|
|
225
394
|
}
|
|
226
395
|
return value.startsWith('v') ? value : `v${value}`;
|
|
227
396
|
}
|
|
228
397
|
|
|
229
398
|
function getNativeStatusMessage(statusValue, classification) {
|
|
230
399
|
if (classification === 'update-available') {
|
|
231
|
-
return '
|
|
400
|
+
return utx('An update is available for the local bridge. Run the command below, then reload the extension.',
|
|
401
|
+
'本地桥接程序有可用更新。运行下方命令后重新加载扩展。');
|
|
232
402
|
}
|
|
233
403
|
switch (statusValue) {
|
|
234
404
|
case 'native_too_old':
|
|
235
|
-
return '
|
|
405
|
+
return utx('Update the local bridge with the command below, then reload the extension.',
|
|
406
|
+
'运行下方命令更新本地桥接程序,然后重新加载扩展。');
|
|
236
407
|
case 'protocol_unsupported':
|
|
237
|
-
return '
|
|
408
|
+
return utx('The extension and local bridge use different protocols. Update both components together.',
|
|
409
|
+
'扩展与本地桥接程序的协议不匹配,请一并更新。');
|
|
238
410
|
case 'extension_too_old':
|
|
239
|
-
return '
|
|
411
|
+
return utx('Update the Chrome extension before running Codex.', '运行 Codex 前需要更新 Chrome 扩展。');
|
|
240
412
|
case 'native_unhealthy':
|
|
241
|
-
return '
|
|
413
|
+
return utx('The local bridge is connected, but Codex needs attention. Check diagnostics in the side panel.',
|
|
414
|
+
'本地桥接已连接,Codex 状态需要处理。请查看侧边栏中的诊断。');
|
|
242
415
|
case 'native_missing':
|
|
243
|
-
return '
|
|
416
|
+
return utx('Run this command in Terminal, then reload the extension.', '在终端运行下方命令,然后重新加载扩展。');
|
|
244
417
|
default:
|
|
245
|
-
return '
|
|
418
|
+
return utx('Update the local bridge with the command below, then reload the extension.',
|
|
419
|
+
'运行下方命令更新本地桥接程序,然后重新加载扩展。');
|
|
246
420
|
}
|
|
247
421
|
}
|
|
248
422
|
|
|
@@ -414,7 +588,7 @@ async function sendConsentAction(action) {
|
|
|
414
588
|
const summary = document.createElement('summary');
|
|
415
589
|
summary.textContent = utx('Technical details', '技术详情');
|
|
416
590
|
const code = document.createElement('code');
|
|
417
|
-
code.textContent = [state.code, state
|
|
591
|
+
code.textContent = [state.code, formatUpdateFailure(state)].filter(Boolean).join(': ');
|
|
418
592
|
details.append(summary, code);
|
|
419
593
|
card.append(details);
|
|
420
594
|
}
|
|
@@ -524,12 +698,26 @@ async function sendConsentAction(action) {
|
|
|
524
698
|
awaiting_health: [utx('Checking updated components', '正在检查更新后的组件'), latest, utx('Restarting and checking both components', '正在重启并检查两个组件')],
|
|
525
699
|
committed: [utx('Update complete', '更新完成'), latest || current, utx('Extension and Native Host are healthy.', '扩展与 Native Host 均运行正常。')],
|
|
526
700
|
rolled_back: [utx('Previous version restored', '已恢复上一版本'), current, utx('Health check failed, so the previous coordinated pair was restored.', '健康检查失败,已恢复上一组协调版本。')],
|
|
527
|
-
failed: [utx('Update could not continue', '更新无法继续'), latest, state
|
|
701
|
+
failed: [utx('Update could not continue', '更新无法继续'), latest, formatUpdateFailure(state) || utx('Check the details and retry.', '请查看详情后重试。')]
|
|
528
702
|
};
|
|
529
703
|
const value = map[state.state] || map.idle;
|
|
530
704
|
return { title: value[0], version: value[1], detail: value[2], phase: value[2] };
|
|
531
705
|
}
|
|
532
706
|
|
|
707
|
+
function formatUpdateFailure(state = {}) {
|
|
708
|
+
const code = String(state.code || '');
|
|
709
|
+
if (code === 'update_recovery_pending') return utx('The update result is being checked. Recovery has not been confirmed.', '正在确认更新结果,恢复状态尚未确认。');
|
|
710
|
+
if (['update_bootstrap_health_timeout', 'update_bootstrap_reload_failed'].includes(code)) return utx('The updated startup components did not finish restarting and confirming. Check recovery before retrying.', '更新后的启动组件未能完成重启和确认,请先检查恢复状态。');
|
|
711
|
+
if (['update_bootstrap_source_mismatch', 'update_bootstrap_source_version_mismatch'].includes(code)) return utx('The installed startup files do not match a supported update source. Check recovery before retrying.', '已安装的启动文件与支持的升级来源不一致,请先检查恢复状态。');
|
|
712
|
+
if (['update_bootstrap_record_missing', 'update_bootstrap_record_invalid', 'update_bootstrap_backup_mismatch', 'update_bootstrap_already_restoring'].includes(code)) return utx('The startup recovery material could not be confirmed. The update result remains unconfirmed.', '尚未确认启动组件的恢复材料有效,更新结果仍待确认。');
|
|
713
|
+
if (['update_bootstrap_confirmation_pending', 'update_bootstrap_native_restart_required'].includes(code)) return utx('Waiting for the updated startup components and Native Host to finish restarting and confirming.', '正在等待更新后的启动组件和本机服务完成重启及确认。');
|
|
714
|
+
if (code === 'update_bootstrap_monitor_unavailable') return utx('The update recovery monitor could not start. Check recovery before retrying.', '更新恢复监护程序未能启动,请先检查恢复状态。');
|
|
715
|
+
if (['update_bootstrap_transaction_mismatch', 'update_bootstrap_transaction_invalid'].includes(code)) return utx('The startup update transaction could not be matched. Check recovery before retrying.', '未能匹配启动组件的更新事务,请先检查恢复状态。');
|
|
716
|
+
if (code.startsWith('update_bootstrap_')) return utx('The startup update package or installed files could not be verified. Check recovery before retrying.', '无法验证启动组件更新包或已安装文件,请先检查恢复状态。');
|
|
717
|
+
if (['update_health_failed', 'update_request_failed', 'update_failed'].includes(code)) return utx('The updated components could not be confirmed. Check recovery before retrying.', '尚未确认更新后的组件正常,请先检查恢复状态。');
|
|
718
|
+
return state.message || '';
|
|
719
|
+
}
|
|
720
|
+
|
|
533
721
|
function formatBlocker(blocker) {
|
|
534
722
|
const labels = {
|
|
535
723
|
unsaved: utx('Overleaf has not confirmed that this document is saved.', 'Overleaf 尚未确认当前文档已保存。'),
|
|
@@ -544,7 +732,15 @@ async function sendConsentAction(action) {
|
|
|
544
732
|
return labels[blocker] || utx('Waiting until every Overleaf tab is saved and idle.', '正在等待所有 Overleaf 标签页完成保存并进入空闲状态。');
|
|
545
733
|
}
|
|
546
734
|
|
|
735
|
+
function refreshPopupCopy(element) {
|
|
736
|
+
const pair = popupCopyPairs.get(element?.textContent);
|
|
737
|
+
if (pair) element.textContent = utx(...pair);
|
|
738
|
+
}
|
|
739
|
+
|
|
547
740
|
function utx(english, chinese) {
|
|
741
|
+
const pair = [english, chinese];
|
|
742
|
+
popupCopyPairs.set(english, pair);
|
|
743
|
+
popupCopyPairs.set(chinese, pair);
|
|
548
744
|
const locale = document.documentElement?.lang || 'en';
|
|
549
745
|
return /^zh\b/i.test(locale) ? chinese : english;
|
|
550
746
|
}
|
|
@@ -63,6 +63,14 @@
|
|
|
63
63
|
const locale = normalizeLocale(options);
|
|
64
64
|
const type = String(event.type || '');
|
|
65
65
|
|
|
66
|
+
if (type === 'codex.local_skills.missing' || type === 'codex.local_skill_invocation.ignored') {
|
|
67
|
+
return { kind: 'activity', visible: true,
|
|
68
|
+
title: type === 'codex.local_skills.missing'
|
|
69
|
+
? textFor(locale, '所选的本地技能未能加载。', 'A selected local skill could not be loaded.')
|
|
70
|
+
: textFor(locale, '所选的本地技能已关闭或不可用。', 'A selected local skill is disabled or unavailable.'),
|
|
71
|
+
status: event.status || 'failed', technicalDetail: normalizeRawEvent(event) };
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
if (isContextCompactionEvent(event)) {
|
|
67
75
|
return formatContextCompactionCheckpoint(event, locale);
|
|
68
76
|
}
|
|
@@ -372,6 +380,7 @@
|
|
|
372
380
|
status: 'running',
|
|
373
381
|
streamKey: getCodexStreamKey(method, params),
|
|
374
382
|
streamRole: method === 'item/agentMessage/delta' ? 'assistant' : 'reasoning',
|
|
383
|
+
streamPhase: params.phase || '',
|
|
375
384
|
appendText: true
|
|
376
385
|
};
|
|
377
386
|
}
|
|
@@ -412,12 +421,13 @@
|
|
|
412
421
|
};
|
|
413
422
|
}
|
|
414
423
|
if (method === 'warning' || method === 'guardianWarning' || method === 'configWarning') {
|
|
415
|
-
const title = cleanVisibleText(params.message || params.warning || '');
|
|
424
|
+
const title = cleanVisibleText(params.message || params.warning || params.summary || '');
|
|
425
|
+
if (!title) return technicalOnly(event, locale);
|
|
416
426
|
return {
|
|
417
427
|
kind: 'activity',
|
|
418
428
|
visible: true,
|
|
419
|
-
title
|
|
420
|
-
status: '
|
|
429
|
+
title,
|
|
430
|
+
status: event.status === 'failed' ? 'failed' : method === 'guardianWarning' ? 'warning' : 'info',
|
|
421
431
|
technicalDetail: normalizeRawEvent(event)
|
|
422
432
|
};
|
|
423
433
|
}
|
|
@@ -459,6 +469,7 @@
|
|
|
459
469
|
status,
|
|
460
470
|
streamKey: getItemStreamKey('agent', item),
|
|
461
471
|
streamRole: 'assistant',
|
|
472
|
+
streamPhase: item.phase || '',
|
|
462
473
|
replaceText: true
|
|
463
474
|
};
|
|
464
475
|
}
|
|
@@ -500,6 +511,10 @@
|
|
|
500
511
|
status,
|
|
501
512
|
detail: {
|
|
502
513
|
command: item.command,
|
|
514
|
+
itemId: item.id,
|
|
515
|
+
threadId: event.detail?.params?.threadId,
|
|
516
|
+
turnId: event.detail?.params?.turnId,
|
|
517
|
+
commandActions: item.commandActions,
|
|
503
518
|
output: item.aggregatedOutput,
|
|
504
519
|
exitCode: item.exitCode
|
|
505
520
|
}
|
|
@@ -723,6 +738,21 @@
|
|
|
723
738
|
// failure data alongside the human-readable text. The string text is kept
|
|
724
739
|
// verbatim because it has mode-aware nuance (e.g. "No files were written"
|
|
725
740
|
// vs "This run did not start") the catalog's fallback strings don't capture.
|
|
741
|
+
if (context.code === 'codex_local_skill_unavailable' || /(?:The )?selected local Codex skill is unavailable/i.test(text)) {
|
|
742
|
+
return {
|
|
743
|
+
conclusion: textFor(locale, '所选 Codex 本地技能不可用或已关闭,本轮没有启动。', 'The selected local Codex skill is unavailable or disabled. This run did not start.'),
|
|
744
|
+
nextStep: textFor(locale, '请打开技能页,选择可用且已启用的技能后重新提交。', 'Open Skills, select an available enabled skill, and submit again.'),
|
|
745
|
+
failureCode: 'codex_local_skill_unavailable'
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
if (/^codex_local_skills_/.test(String(context.code || ''))
|
|
749
|
+
|| /local Codex skill discovery|Codex could not (?:list local skills|start local skill discovery)|Codex returned an invalid local skill catalog/i.test(text)) {
|
|
750
|
+
return {
|
|
751
|
+
conclusion: textFor(locale, 'Codex 本地技能未能加载,本轮没有启动。', 'Local Codex skills could not be loaded. This run did not start.'),
|
|
752
|
+
nextStep: textFor(locale, '请打开技能页重新加载本地目录,然后重新提交。', 'Open Skills to reload the local catalog, then submit again.'),
|
|
753
|
+
failureCode: 'codex_local_skills_failed'
|
|
754
|
+
};
|
|
755
|
+
}
|
|
726
756
|
const providerError = translateProviderError(text, locale);
|
|
727
757
|
if (providerError) {
|
|
728
758
|
return providerError;
|
|
@@ -863,6 +893,11 @@
|
|
|
863
893
|
: textFor(locale, '本轮没有可撤销的写入', 'this run has no reversible writes');
|
|
864
894
|
}
|
|
865
895
|
|
|
896
|
+
if (input.saveVerification && input.saveVerification.state !== 'not_checked') {
|
|
897
|
+
report.saveState = input.saveVerification.state === 'verified_saved'
|
|
898
|
+
? textFor(locale, '已确认保存', 'Saved')
|
|
899
|
+
: textFor(locale, '待确认,可检查保存状态', 'Pending confirmation; check save status');
|
|
900
|
+
}
|
|
866
901
|
const failed = input.status === 'failed' || input.status === 'blocked';
|
|
867
902
|
return {
|
|
868
903
|
title: textFor(locale, '本轮完成报告', 'Task report'),
|
|
@@ -946,6 +981,7 @@
|
|
|
946
981
|
});
|
|
947
982
|
}
|
|
948
983
|
|
|
984
|
+
if (report.saveState) meta.push({ key: 'saveState', label: textFor(locale, '保存', 'Save'), value: report.saveState });
|
|
949
985
|
return { conclusion, body: bodySections.join('\n\n'), meta };
|
|
950
986
|
}
|
|
951
987
|
|
|
@@ -976,6 +1012,7 @@
|
|
|
976
1012
|
if (nextStep) {
|
|
977
1013
|
sections.push(textFor(locale, `下一步:${nextStep}`, `Next: ${nextStep}`));
|
|
978
1014
|
}
|
|
1015
|
+
if (report.saveState) sections.push(textFor(locale, `保存:${report.saveState}`, `Save: ${report.saveState}`));
|
|
979
1016
|
return sections.join('\n\n');
|
|
980
1017
|
}
|
|
981
1018
|
|
|
@@ -1045,7 +1082,7 @@
|
|
|
1045
1082
|
if (input.mode === 'ask' || input.status === '只问不改') {
|
|
1046
1083
|
return textFor(locale, '这轮是只问不改。', 'This run was Ask mode.');
|
|
1047
1084
|
}
|
|
1048
|
-
if (input.status === 'rejected') {
|
|
1085
|
+
if (input.status === 'cancelled' || input.status === 'rejected') {
|
|
1049
1086
|
return textFor(locale, '你取消了这轮修改。', 'You cancelled this change.');
|
|
1050
1087
|
}
|
|
1051
1088
|
return '';
|