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
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
(function (root, factory) {
|
|
2
|
+
if (typeof module === 'object' && module.exports) module.exports = factory(require('../shared/failureReasons'), require('../shared/i18n'), require('../shared/agentTranscript'));
|
|
3
|
+
else root.CodexOverleafModuleRegistry.define('RunCompletionMeta', ['FailureReasons', 'I18n', 'AgentTranscript'], factory);
|
|
4
|
+
})(typeof window !== 'undefined' ? window : globalThis, function (FailureReasons, I18n, AgentTranscript) {
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const FLAT_REPORT_STATUS_SECTIONS = [
|
|
8
|
+
{ key: 'saveState', prefixes: ['Save:', '保存:'], en: 'Save', zh: '保存' },
|
|
9
|
+
{ key: 'unchangedReason', prefixes: ['Why nothing changed:', '未修改原因:'], en: 'Why nothing changed', zh: '未修改原因' },
|
|
10
|
+
{ key: 'writeResult', prefixes: ['Write result:', '写入结果:'], en: 'Write result', zh: '写入结果' },
|
|
11
|
+
{ key: 'undo', prefixes: ['Undo:', '可撤销:'], en: 'Undo', zh: '可撤销' },
|
|
12
|
+
{ key: 'nextStep', prefixes: ['Next:', '下一步:'], en: 'Next', zh: '下一步' }
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
// Reports persist the language used when the run finished. Re-project only
|
|
16
|
+
// product-owned metadata; model conclusions and custom reasons stay intact.
|
|
17
|
+
const META_COPY = {
|
|
18
|
+
unchangedReason: [
|
|
19
|
+
['This run was Ask mode.', '这轮是只问不改。'],
|
|
20
|
+
['You cancelled this change.', '你取消了这轮修改。'],
|
|
21
|
+
['No file changes need to sync back to Overleaf.', '没有产生需要同步回 Overleaf 的文件改动。'],
|
|
22
|
+
['No approved file changes remain to sync back to Overleaf.', '没有剩余已确认的文件改动需要同步回 Overleaf。']
|
|
23
|
+
],
|
|
24
|
+
undo: [['this run has no reversible writes', '本轮没有可撤销的写入']],
|
|
25
|
+
saveState: [['Saved', '已确认保存'],
|
|
26
|
+
['Pending confirmation; check save status', '待确认,可检查保存状态']],
|
|
27
|
+
nextStep: [
|
|
28
|
+
['Review the skipped items in this report, then retry after resolving them.', '请查看本轮报告中的跳过项,处理后可以重试。'],
|
|
29
|
+
['Nothing was written in this run. Review the skipped reasons, fix them, and retry.', '这轮没有任何内容写入。请查看跳过原因,处理后重试。'],
|
|
30
|
+
['Review the skipped reasons. You can use "Undo written parts" to roll back what already reached Overleaf, then fix conflicts and retry.', '请查看跳过原因。已写入的部分可以点击“撤销已写入部分”回退,处理冲突后再重试。'],
|
|
31
|
+
['Resolve the issue above, then retry.', '请处理上面的原因后重试。'],
|
|
32
|
+
['You can continue asking, or add more @context and run another check.', '可以继续追问,或加入更多 @context 后再检查。'],
|
|
33
|
+
['Review these tracked changes in Overleaf.', '请在 Overleaf 中查看这些文件的留痕修改。'],
|
|
34
|
+
['You can continue the conversation, or adjust @context and run again.', '可以继续追问,或调整 @context 后重新运行。'],
|
|
35
|
+
['The first queued follow-up will start next.', '接下来会自动启动队首的后续任务。'],
|
|
36
|
+
['Edit the task and run again.', '可以修改任务后重新运行。'],
|
|
37
|
+
['Continue the conversation, or switch to Auto to let Codex edit files.', '可以继续追问,或切换到自动写入后让 Codex 修改文件。'],
|
|
38
|
+
['Switch to Auto only when you want Codex to edit files.', '只有希望 Codex 修改文件时,才需要切换到自动写入。'],
|
|
39
|
+
['Review the synced file in Overleaf.', '请在 Overleaf 中查看同步后的文件。'],
|
|
40
|
+
['Check Overleaf manually before running again. Local mirror refresh and auto compile were skipped.', '再次运行前请先手动检查 Overleaf。本地 mirror 刷新和自动编译已跳过。'],
|
|
41
|
+
['Switch Overleaf to Reviewing/Track Changes manually and rerun, or turn off Track before writing.', '请在 Overleaf 手动切到 Reviewing/Track Changes 后重新运行,或关闭“留痕”再写入。'],
|
|
42
|
+
['The main agent must review and adopt the withheld files before syncing them.', '主代理需核对并接管未同步文件后再写回。'],
|
|
43
|
+
['Select the intended region again and request only changes within it. Valid written parts can be undone.', '请重新选择目标范围,仅请求修改该范围。已写入的合法部分可撤销。'],
|
|
44
|
+
['Reload the Overleaf project or reopen the .tex file you want to process, then retry.', '请刷新 Overleaf 项目或重新打开要处理的 .tex 文件后再试。'],
|
|
45
|
+
['Retry with an explicit target such as @file:main.tex and the exact section to edit; if this repeats, open Technical Details.', '请带上明确目标重试,例如 @file:main.tex 和具体要修改的小节;如果重复出现,请打开 Technical Details。'],
|
|
46
|
+
['Restart Codex Overleaf or start a new run if the installed skill is not visible immediately.', '如果新安装的 skill 没有立刻出现,请重启 Codex Overleaf 或开始新一轮运行。'],
|
|
47
|
+
['If files still need to be deleted, rerun and confirm deletion separately.', '如果仍需要删除文件,请重新运行并单独确认删除。'],
|
|
48
|
+
['Expand the write result, review the skipped reasons, then retry after fixing them.', '请展开写入结果查看跳过原因,处理后可以重试。'],
|
|
49
|
+
['Adjust the task description and run again.', '可以调整任务描述后重新运行。'],
|
|
50
|
+
['Continue the conversation or run the next task.', '可以继续追问,或运行下一项任务。']
|
|
51
|
+
]
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
let errorNextSteps;
|
|
55
|
+
const errorNextStepTemplates = [];
|
|
56
|
+
function localizeErrorNextStep(value, tx) {
|
|
57
|
+
if (!errorNextSteps) {
|
|
58
|
+
errorNextSteps = new Map();
|
|
59
|
+
const add = pair => {
|
|
60
|
+
if (!pair.every(text => typeof text === 'string' && text)) return;
|
|
61
|
+
if (pair.every(text => text.includes('{file}'))) {
|
|
62
|
+
for (const template of pair) {
|
|
63
|
+
const parts = template.split('{file}');
|
|
64
|
+
if (parts.length === 2) errorNextStepTemplates.push({ pair,
|
|
65
|
+
pattern: new RegExp('^' + parts.map(part => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('([^\\r\\n]*?)') + '$') });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const text of pair) if (!errorNextSteps.has(text)) errorNextSteps.set(text, pair);
|
|
69
|
+
};
|
|
70
|
+
// Reuse the producer's own bilingual copy rather than maintain another
|
|
71
|
+
// translation catalog. Only exact, known next-step prose is accepted.
|
|
72
|
+
for (const key of Object.keys(I18n?.MESSAGES?.en || {})) {
|
|
73
|
+
if (/^failureReason_.+_next$/.test(key)) add([I18n.MESSAGES.en[key], I18n.MESSAGES.zh[key]]);
|
|
74
|
+
}
|
|
75
|
+
const catalog = FailureReasons?.FAILURE_CODE_CATALOG || {};
|
|
76
|
+
for (const [code, entry] of Object.entries(catalog)) {
|
|
77
|
+
const key = `failureReason_${code}_next`;
|
|
78
|
+
const pair = [I18n?.MESSAGES?.en?.[key], I18n?.MESSAGES?.zh?.[key]];
|
|
79
|
+
if (entry.fallbackNextAction && pair.every(Boolean)) errorNextSteps.set(entry.fallbackNextAction, pair);
|
|
80
|
+
}
|
|
81
|
+
const legacyInputs = ['Mode must be "ask" or "auto"', 'Agent returned invalid JSON',
|
|
82
|
+
'Could not parse Codex output', 'timed out', 'output limit exceeded',
|
|
83
|
+
'unsupported_parameter reasoning.summary', 'quota', 'checkpoint', 'changed while Codex was working'];
|
|
84
|
+
if (AgentTranscript?.translateRawError) {
|
|
85
|
+
for (const message of [...Object.keys(catalog), ...legacyInputs]) {
|
|
86
|
+
add(['en', 'zh'].map(locale => AgentTranscript.translateRawError(message, { locale }).nextStep));
|
|
87
|
+
}
|
|
88
|
+
add(['en', 'zh'].map(locale => AgentTranscript.translateRawError('', { locale, codexReturned: true }).nextStep));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const pair = errorNextSteps.get(value);
|
|
92
|
+
if (pair) return tx(...pair);
|
|
93
|
+
for (const entry of errorNextStepTemplates) {
|
|
94
|
+
const match = entry.pattern.exec(String(value || ''));
|
|
95
|
+
if (match) return tx(...entry.pair).replace('{file}', () => match[1]);
|
|
96
|
+
}
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function localizeMetaRow(row, options) {
|
|
101
|
+
if (!row || typeof row !== 'object') return row;
|
|
102
|
+
const entry = FLAT_REPORT_STATUS_SECTIONS.find(item => item.key === row.key);
|
|
103
|
+
if (!entry) return row;
|
|
104
|
+
const { tx } = options;
|
|
105
|
+
let value = row.value;
|
|
106
|
+
const pair = (META_COPY[row.key] || []).find(values => values.includes(value));
|
|
107
|
+
if (pair) value = tx(...pair);
|
|
108
|
+
if (row.key === 'nextStep') value = localizeErrorNextStep(value, tx);
|
|
109
|
+
if (row.key === 'writeResult') {
|
|
110
|
+
const counts = /^(?:已写入 (\d+) 项,跳过 (\d+) 项|wrote (\d+) items?, skipped (\d+) items?)$/.exec(String(value || ''));
|
|
111
|
+
if (counts) {
|
|
112
|
+
const written = Number(counts[1] ?? counts[3]), skipped = Number(counts[2] ?? counts[4]);
|
|
113
|
+
value = tx(`wrote ${written} item${written === 1 ? '' : 's'}, skipped ${skipped} item${skipped === 1 ? '' : 's'}`,
|
|
114
|
+
`已写入 ${written} 项,跳过 ${skipped} 项`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (row.key === 'undo') {
|
|
118
|
+
const count = /^(?:可撤销本轮 (\d+) 项写入|this run has (\d+) reversible writes?)$/.exec(String(value || ''));
|
|
119
|
+
if (count) {
|
|
120
|
+
const n = Number(count[1] ?? count[2]);
|
|
121
|
+
value = tx(`this run has ${n} reversible write${n === 1 ? '' : 's'}`, `可撤销本轮 ${n} 项写入`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (['nextStep', 'unchangedReason'].includes(row.key) && options.getLocale && options.tr) {
|
|
125
|
+
value = FailureReasons?.localizeFailureMessage?.(value, options.getLocale(), key => {
|
|
126
|
+
const translated = options.tr(key);
|
|
127
|
+
return translated === key ? undefined : translated;
|
|
128
|
+
}) ?? value;
|
|
129
|
+
}
|
|
130
|
+
return { ...row, label: tx(entry.en, entry.zh), value };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function splitFlatCompletionReport(text, tx = value => value) {
|
|
134
|
+
const raw = typeof text === 'string' ? text : '';
|
|
135
|
+
if (!raw.trim()) return { body: raw, meta: [] };
|
|
136
|
+
const bodySections = [], meta = [];
|
|
137
|
+
for (const section of raw.split(/\n{2,}/)) {
|
|
138
|
+
const trimmed = section.trim();
|
|
139
|
+
if (!trimmed) continue;
|
|
140
|
+
const entry = trimmed.includes('\n') ? null
|
|
141
|
+
: FLAT_REPORT_STATUS_SECTIONS.find(item => item.prefixes.some(prefix => trimmed.startsWith(prefix)));
|
|
142
|
+
if (entry) {
|
|
143
|
+
const prefix = entry.prefixes.find(value => trimmed.startsWith(value));
|
|
144
|
+
const value = trimmed.slice(prefix.length).trim();
|
|
145
|
+
if (value) {
|
|
146
|
+
meta.push({ key: entry.key, label: tx(entry.en, entry.zh), value });
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
bodySections.push(trimmed);
|
|
151
|
+
}
|
|
152
|
+
return { body: bodySections.join('\n\n'), meta };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function projectCompletionBody(body, tx = value => value) {
|
|
156
|
+
if (typeof body !== 'string' || !body) return body;
|
|
157
|
+
const sections = [['Checked', '检查范围'], ['Findings', '发现'], ['Planned changes', '计划修改'],
|
|
158
|
+
['Changes', '修改'], ['Skipped', '跳过原因']];
|
|
159
|
+
let rest = body, previous = -1, language;
|
|
160
|
+
const projected = [];
|
|
161
|
+
while (rest) {
|
|
162
|
+
let found;
|
|
163
|
+
for (let index = previous + 1; index < sections.length && !found; index++) {
|
|
164
|
+
for (const locale of [0, 1]) {
|
|
165
|
+
const prefix = sections[index][locale] + (locale ? ':\n' : ':\n');
|
|
166
|
+
if ((language === undefined || locale === language) && rest.startsWith(prefix)) {
|
|
167
|
+
found = { index, locale, prefix }; break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (!found) return body;
|
|
172
|
+
language = found.locale;
|
|
173
|
+
previous = found.index;
|
|
174
|
+
rest = rest.slice(found.prefix.length);
|
|
175
|
+
const heading = tx(sections[previous][0] + ':', sections[previous][1] + ':');
|
|
176
|
+
// Skipped may contain arbitrary model/error prose. Only a complete,
|
|
177
|
+
// exact product-owned governance block can be re-projected.
|
|
178
|
+
if (previous === sections.length - 1) {
|
|
179
|
+
if (!/^- [^\r\n]+/.test(rest)) return body;
|
|
180
|
+
projected.push(heading + '\n' + projectGovernanceSkippedBody(rest, tx));
|
|
181
|
+
return projected.join('\n\n');
|
|
182
|
+
}
|
|
183
|
+
const boundary = rest.indexOf('\n\n');
|
|
184
|
+
const items = boundary < 0 ? rest : rest.slice(0, boundary);
|
|
185
|
+
if (!/^- [^\r\n]+(?:\n- [^\r\n]+)*$/.test(items)) return body;
|
|
186
|
+
projected.push(heading + '\n' + items);
|
|
187
|
+
if (boundary < 0) return projected.join('\n\n');
|
|
188
|
+
rest = rest.slice(boundary + 2);
|
|
189
|
+
if (!rest) return body;
|
|
190
|
+
}
|
|
191
|
+
return body;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function projectGovernanceSkippedBody(body, tx) {
|
|
195
|
+
const locale = tx('en', 'zh');
|
|
196
|
+
const lookup = key => I18n.t(locale, key);
|
|
197
|
+
const operationLabels = { edit: '编辑', create: '新建', delete: '删除', move: '移动', rename: '重命名' };
|
|
198
|
+
const pattern = /(^|\n)- ([^\r\n]+?)(?:: (edit|create|delete|move|rename|binary-create|overwrite-binary) was not written|:(编辑|新建|删除|移动|重命名|binary-create|overwrite-binary)没有写入)\n([ \t]*)(?:Reason|原因): ([^\r\n]+)\n\5(?:Stage|阶段): (?:unknown|preflight)\n\5(?:Code|代码): (unknown_legacy_failure|governance_blocked|governance_readonly|governance_writable_allowlist)\n\5(?:Next|下一步): ([^\r\n]+)(?=\n- |$)/g;
|
|
199
|
+
return body.replace(pattern, (block, prefix, file, enOperation, zhOperation, indent, message, code, next) => {
|
|
200
|
+
const display = FailureReasons.formatFailureReasonForDisplay({ code: 'unknown_legacy_failure', userMessage: message }, locale, lookup);
|
|
201
|
+
if (!['governance_blocked', 'governance_readonly', 'governance_writable_allowlist'].includes(display.code)) return block;
|
|
202
|
+
if (code !== 'unknown_legacy_failure' && code !== 'governance_blocked' && code !== display.code) return block;
|
|
203
|
+
const nextKeys = [display.code, 'unknown_legacy_failure'].flatMap(value => [
|
|
204
|
+
FailureReasons.FAILURE_CODE_CATALOG[value]?.fallbackNextAction,
|
|
205
|
+
I18n.t('en', `failureReason_${value}_next`), I18n.t('zh', `failureReason_${value}_next`)
|
|
206
|
+
]);
|
|
207
|
+
if (!nextKeys.includes(next)) return block;
|
|
208
|
+
const operation = enOperation || Object.keys(operationLabels).find(key => operationLabels[key] === zhOperation) || zhOperation;
|
|
209
|
+
const header = tx(`${file}: ${operation} was not written`, `${file}:${operationLabels[operation] || operation}没有写入`);
|
|
210
|
+
const failure = { code: display.code, stage: 'preflight', userMessage: display.userMessage, nextAction: display.nextAction };
|
|
211
|
+
return `${prefix}- ${header}\n${AgentTranscript.formatFailureBlock(failure, locale, indent)}`;
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function projectCompletionMeta(meta, run, options) {
|
|
216
|
+
const { tx, trackedChangeInFlight, isTrackedChangeLifecycleRun, projectRunSettlement } = options;
|
|
217
|
+
if (!Array.isArray(meta) || !run) return meta;
|
|
218
|
+
const undone = run.undoStatus === 'applied' || run.trackedChangeStatus === 'rejected';
|
|
219
|
+
const rows = (undone ? meta.filter(row => row?.key !== 'saveState') : meta).map(row => localizeMetaRow(row, options))
|
|
220
|
+
.filter(row => row?.key !== 'recoveryRetention' && row?.key !== 'directoryObservation');
|
|
221
|
+
const pending = run.pendingDirectoryCleanup;
|
|
222
|
+
if (!run.forkSnapshot && pending?.v === 1 && pending.runId === run.id
|
|
223
|
+
&& pending.projectId === run.runProjectId && pending.projectId === options.projectId
|
|
224
|
+
&& pending.accountScopeId && pending.accountScopeId === options.accountScopeId) {
|
|
225
|
+
const paths = [...new Set((Array.isArray(pending.directories) ? pending.directories : []).filter(item => item?.projectId === pending.projectId
|
|
226
|
+
&& typeof item.path === 'string' && item.path && !/^[\\/]|^[A-Za-z]:|[\u0000-\u001f\u007f]/.test(item.path)
|
|
227
|
+
&& !item.path.replace(/\\/g, '/').split('/').some(part => !part || part === '.' || part === '..')).map(item => item.path))];
|
|
228
|
+
if (paths.length) rows.push({ key: 'directoryObservation', label: tx('Folders', '文件夹'),
|
|
229
|
+
value: tx('The run recorded these folders at completion; their current status has not been rechecked: ',
|
|
230
|
+
'本轮结束时记录了以下文件夹,当前状态尚未重新核验:') + paths.join(', ') });
|
|
231
|
+
}
|
|
232
|
+
const retentionOmitted = hasOmittedRecoveryRetention(run);
|
|
233
|
+
const inFlight = trackedChangeInFlight?.get(run.id);
|
|
234
|
+
const tracked = isTrackedChangeLifecycleRun(run);
|
|
235
|
+
const pendingFileUndo = tracked && run.trackedChangeStatus === 'needs_review' && run.undoOperations?.some(operation => operation?.undoCreatedFile?.v === 1 || operation?.type === 'create');
|
|
236
|
+
let undo;
|
|
237
|
+
if (run.undoStatus === 'running' || inFlight === 'reject') {
|
|
238
|
+
undo = tx('Undoing changes...', '正在撤销修改…');
|
|
239
|
+
} else if (run.undoStatus === 'applied' || (tracked && run.trackedChangeStatus === 'rejected')) {
|
|
240
|
+
undo = tx('This run\'s changes have been undone.', '本轮修改已撤销。');
|
|
241
|
+
} else if (tracked && run.trackedChangeStatus === 'accepted') {
|
|
242
|
+
undo = tx('Changes accepted; undo is no longer available.', '修改已接受,无法再撤销。');
|
|
243
|
+
} else if (run.undoStatus === 'partial' || pendingFileUndo) {
|
|
244
|
+
undo = hasUndoProgress(run)
|
|
245
|
+
? projectRunSettlement(run).canUndo
|
|
246
|
+
? tx(pendingFileUndo ? 'Some changes were undone; retry the remaining files.' : 'Some changes were undone; remaining changes can still be undone.', pendingFileUndo ? '已撤销部分修改,可重试剩余文件。' : '已撤销部分修改,剩余修改仍可撤销。')
|
|
247
|
+
: tx('Some changes were undone.', '已撤销部分修改。')
|
|
248
|
+
: projectRunSettlement(run).canUndo
|
|
249
|
+
? tx(pendingFileUndo ? 'Undo is incomplete; retry the remaining files.' : 'Undo is incomplete; remaining changes can still be undone.', pendingFileUndo ? '撤销未完成,可重试剩余文件。' : '撤销未完成,剩余修改仍可撤销。')
|
|
250
|
+
: tx('Undo is incomplete.', '撤销未完成。');
|
|
251
|
+
}
|
|
252
|
+
if (!undo && !run.saveCheck && !run.saveConfirmedAt && !retentionOmitted) return rows;
|
|
253
|
+
const projected = rows.map(row => row?.key === 'undo' && undo
|
|
254
|
+
? { ...row, label: tx('Undo', '撤销'), value: undo }
|
|
255
|
+
: row?.key === 'saveState' && (run.saveCheck || run.saveConfirmedAt)
|
|
256
|
+
? { ...row, label: tx('Save', '保存'), value: run.saveCheck
|
|
257
|
+
? tx('Pending confirmation', '待确认') : tx('Saved', '已确认保存') }
|
|
258
|
+
: row);
|
|
259
|
+
if (retentionOmitted) {
|
|
260
|
+
const budget = ['run-budget', 'session-budget'].includes(run.recoveryRetention.reason);
|
|
261
|
+
const directory = run.recoveryRetention.directoryCleanup === true ? tx(
|
|
262
|
+
'Recorded folder observations were not retained; their current status is unknown.',
|
|
263
|
+
'文件夹历史观测记录未保留,当前状态未核验。') : '';
|
|
264
|
+
const recovery = budget
|
|
265
|
+
? tx('Persistent recovery data was not retained: local recovery budget exceeded. After reload, use Overleaf history to recover.',
|
|
266
|
+
'持久恢复材料未保留:超过本地恢复预算,刷新后请使用 Overleaf 历史恢复。')
|
|
267
|
+
: tx('Persistent recovery data was not retained. After reload, use Overleaf history to recover.',
|
|
268
|
+
'持久恢复材料未保留,刷新后请使用 Overleaf 历史恢复。');
|
|
269
|
+
projected.push({ key: 'recoveryRetention', label: tx('Recovery data', '恢复材料'),
|
|
270
|
+
value: directory && (run.recoveryRetention.coreRetained === true || undone || run.trackedChangeStatus === 'accepted')
|
|
271
|
+
? directory : [recovery, directory].filter(Boolean).join(' ') });
|
|
272
|
+
}
|
|
273
|
+
return projected;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function hasOmittedRecoveryRetention(run) {
|
|
277
|
+
return run?.recoveryRetention?.state === 'omitted' && (run.recoveryRetention.directoryCleanup === true
|
|
278
|
+
|| (run.undoStatus !== 'applied' && !['accepted', 'rejected'].includes(run.trackedChangeStatus)));
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function hasUndoProgress(run) {
|
|
282
|
+
const failures = run?.settlement?.failures || run?.settlementFacts?.failures || [];
|
|
283
|
+
return (Array.isArray(run?.events) ? run.events : []).some(event => {
|
|
284
|
+
if (!['completed', 'failed'].includes(event?.status) || event.streamRole || ['report', 'guidance', 'stream'].includes(event.kind)) return false;
|
|
285
|
+
const count = String(event.title || '').match(/^(?:Undo result: (?:undone|rejected) (\d+) (?:item\(s\)|file\(s\)|tracked change\(s\)), skipped \d+(?: item\(s\))?|撤销结果:已(?:撤销|拒绝) (\d+) (?:项|条留痕|个文件),跳过 \d+ (?:项|条))$/);
|
|
286
|
+
if (!(Number(count?.[1] || count?.[2]) > 0)) return false;
|
|
287
|
+
const detail = event.detail || {}, applied = detail.Undone || detail.Rejected || detail['已撤销'] || detail['已拒绝'];
|
|
288
|
+
const skipped = detail.Skipped || detail['跳过'], path = item => item?.File || item?.['文件'];
|
|
289
|
+
return Array.isArray(applied) && Array.isArray(skipped) && applied.some(item =>
|
|
290
|
+
typeof path(item) === 'string' && path(item).trim() && !skipped.some(other => path(other) === path(item))
|
|
291
|
+
&& !(Array.isArray(failures) && failures.some(failure => failure?.code === 'undo_not_verified'
|
|
292
|
+
&& (!failure.file || failure.file === path(item)))));
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Generic reasons say nothing beyond "no files were written", so they stay in
|
|
297
|
+
// the details. Both locales match because a report keeps its original locale.
|
|
298
|
+
const GENERIC_UNCHANGED_REASONS = new Set([
|
|
299
|
+
'No file changes need to sync back to Overleaf.', '没有产生需要同步回 Overleaf 的文件改动。',
|
|
300
|
+
'No approved file changes remain to sync back to Overleaf.', '没有剩余已确认的文件改动需要同步回 Overleaf。',
|
|
301
|
+
'This run was Ask mode.', '这轮是只问不改。'
|
|
302
|
+
]);
|
|
303
|
+
|
|
304
|
+
// One summary line for the meta rows: what was written, whether it can be
|
|
305
|
+
// undone, and a pending save. The rows themselves stay behind the disclosure,
|
|
306
|
+
// which opens by itself only when something needs the user's attention.
|
|
307
|
+
function summarizeCompletionMeta(rows, run, { tx, failed = false, unconfirmed = false } = {}) {
|
|
308
|
+
const find = key => String(rows.find(row => row?.key === key)?.value || '').trim();
|
|
309
|
+
const counts = find('writeResult').match(/wrote (\d+) items?, skipped (\d+)|已写入 (\d+) 项,跳过 (\d+) 项/);
|
|
310
|
+
const wrote = Number(counts?.[1] ?? counts?.[3] ?? 0), skipped = Number(counts?.[2] ?? counts?.[4] ?? 0);
|
|
311
|
+
const reason = find('unchangedReason');
|
|
312
|
+
const undone = run?.undoStatus === 'applied' || run?.trackedChangeStatus === 'rejected';
|
|
313
|
+
const retentionOmitted = hasOmittedRecoveryRetention(run);
|
|
314
|
+
const savePending = !undone && (Boolean(run?.saveCheck) || (!run?.saveConfirmedAt && /^(?:Pending|待确认)/.test(find('saveState'))));
|
|
315
|
+
const pendingFileUndo = run?.trackedChangeStatus === 'needs_review'
|
|
316
|
+
&& run.undoOperations?.some(operation => operation?.undoCreatedFile?.v === 1 || operation?.type === 'create');
|
|
317
|
+
const facts = [];
|
|
318
|
+
if (failed) facts.push({ key: 'write', tone: 'fail', text: unconfirmed ? tx('Write not confirmed', '写入结果未确认') : tx('Write incomplete', '写入未完成') });
|
|
319
|
+
else if (wrote) facts.push({ key: 'write', text: tx(`Wrote ${wrote} item${wrote === 1 ? '' : 's'}`, `已写入 ${wrote} 项`) });
|
|
320
|
+
else if (reason && !GENERIC_UNCHANGED_REASONS.has(reason)) facts.push({ key: 'write', text: tx('Not written: ', '未写入:') + reason.replace(/[.。]$/, '') });
|
|
321
|
+
else facts.push({ key: 'write', text: tx('No files written', '未写入文件') });
|
|
322
|
+
if (skipped) facts.push({ key: 'skip', tone: 'warn', text: tx(`${skipped} skipped`, `跳过 ${skipped} 项`) });
|
|
323
|
+
const undoable = Number(find('undo').match(/(\d+)/)?.[1] || 0);
|
|
324
|
+
const undo = run?.undoStatus === 'running' || /^(?:Undoing changes\.\.\.|正在撤销修改…)$/.test(find('undo')) ? tx('Undoing…', '正在撤销…')
|
|
325
|
+
: run?.undoStatus === 'applied' || run?.trackedChangeStatus === 'rejected' ? tx('Changes undone', '已撤销本轮修改')
|
|
326
|
+
: run?.trackedChangeStatus === 'accepted' ? tx('Changes accepted', '修改已接受')
|
|
327
|
+
: pendingFileUndo || run?.undoStatus === 'partial'
|
|
328
|
+
? (hasUndoProgress(run) ? tx('Partly undone', '已撤销部分修改') : tx('Undo incomplete', '撤销未完成'))
|
|
329
|
+
: undoable ? tx(`${undoable} undoable`, `可撤销 ${undoable} 项`)
|
|
330
|
+
: failed || retentionOmitted ? '' : tx('Nothing to undo', '无可撤销写入');
|
|
331
|
+
if (undo) facts.push({ key: 'undo', text: undo });
|
|
332
|
+
if (retentionOmitted) facts.push({ key: 'recoveryRetention', tone: 'warn',
|
|
333
|
+
text: run.recoveryRetention.coreRetained === true
|
|
334
|
+
? tx('Folder observations not retained after reload', '刷新后文件夹观测记录未保留')
|
|
335
|
+
: tx('Recovery data not retained after reload', '刷新后恢复材料未保留') });
|
|
336
|
+
if (savePending) facts.push({ key: 'save', tone: 'warn', text: tx('Save pending', '保存待确认') });
|
|
337
|
+
const attention = failed || skipped > 0 || retentionOmitted;
|
|
338
|
+
const warnKeys = new Set([...(failed || skipped > 0 ? ['writeResult', 'nextStep'] : []),
|
|
339
|
+
...(retentionOmitted ? ['recoveryRetention'] : []), ...(savePending ? ['saveState'] : [])]);
|
|
340
|
+
return { facts, open: attention, warnKeys };
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return { splitFlatCompletionReport, projectCompletionBody, projectCompletionMeta, summarizeCompletionMeta };
|
|
344
|
+
});
|
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
(function initCodexOverleafRunController(root, factory) {
|
|
2
2
|
if (typeof module === 'object' && module.exports) {
|
|
3
|
-
module.exports = factory();
|
|
3
|
+
module.exports = factory(require('../shared/projectFiles'));
|
|
4
4
|
} else {
|
|
5
|
-
root.CodexOverleafRunController = factory();
|
|
5
|
+
root.CodexOverleafRunController = factory(root.CodexOverleafProjectFiles);
|
|
6
6
|
}
|
|
7
|
-
})(typeof window !== 'undefined' ? window : globalThis, function runControllerFactory() {
|
|
7
|
+
})(typeof window !== 'undefined' ? window : globalThis, function runControllerFactory(ProjectFiles) {
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
const DEFAULT_EXPECTED_MIRROR_FRESHNESS_MS = 5 * 60 * 1000;
|
|
11
11
|
|
|
12
|
+
function captureSessionContext(state = {}) {
|
|
13
|
+
// This is the prompt projection, not the mutable visible-session alias.
|
|
14
|
+
const session = state.session;
|
|
15
|
+
return session ? JSON.parse(JSON.stringify(session)) : null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isSubmittedComposerUnchanged(submitted, current) {
|
|
19
|
+
return ['task', 'attachments', 'skillInvocation', 'selectionContext'].every(key =>
|
|
20
|
+
JSON.stringify(submitted[key] ?? null) === JSON.stringify(current[key] ?? null));
|
|
21
|
+
}
|
|
22
|
+
|
|
12
23
|
function buildCodexRunParams({
|
|
13
24
|
currentProjectId,
|
|
14
25
|
state = {},
|
|
@@ -22,6 +33,7 @@
|
|
|
22
33
|
customInstructions,
|
|
23
34
|
skillLoadingSettings,
|
|
24
35
|
enabledCodexOverleafSkillIds,
|
|
36
|
+
enabledCodexLocalSkillIds,
|
|
25
37
|
attachments,
|
|
26
38
|
skillInvocation,
|
|
27
39
|
compileLogContext,
|
|
@@ -45,6 +57,7 @@
|
|
|
45
57
|
otWarmStart: useExistingMirror && otWarmStart ? true : undefined,
|
|
46
58
|
warmStartStrategy: useExistingMirror && otWarmStart ? 'ot-warm-mirror' : undefined,
|
|
47
59
|
focusFiles,
|
|
60
|
+
focusFilesAreLiteral: true,
|
|
48
61
|
restrictToFocusFiles: restrictToFocusFiles || undefined,
|
|
49
62
|
model: state.model,
|
|
50
63
|
reasoningEffort: state.reasoningEffort,
|
|
@@ -56,6 +69,9 @@
|
|
|
56
69
|
loadCodexLocalSkills: skillLoadingSettings?.loadCodexLocalSkills !== false,
|
|
57
70
|
loadCodexOverleafSkills: skillLoadingSettings?.loadCodexOverleafSkills !== false,
|
|
58
71
|
enabledCodexOverleafSkillIds: normalizedEnabledSkillIds,
|
|
72
|
+
enabledCodexLocalSkillIds: Array.isArray(enabledCodexLocalSkillIds)
|
|
73
|
+
? [...new Set(enabledCodexLocalSkillIds.filter(id => typeof id === 'string' && isSafeSkillId(id)))]
|
|
74
|
+
: undefined,
|
|
59
75
|
skillInvocation: normalizedSkillInvocation || undefined,
|
|
60
76
|
attachments: normalizedAttachments.length ? normalizedAttachments : undefined
|
|
61
77
|
};
|
|
@@ -106,13 +122,14 @@
|
|
|
106
122
|
project = {},
|
|
107
123
|
snapshotWarnings = {},
|
|
108
124
|
focusFiles = [],
|
|
125
|
+
focusFilesAreLiteral = false,
|
|
109
126
|
isUsableProjectFileContent = defaultIsUsableProjectFileContent
|
|
110
127
|
} = {}) {
|
|
111
128
|
const blocking = Array.isArray(snapshotWarnings.blocking) ? snapshotWarnings.blocking : [];
|
|
112
129
|
if (!blocking.length || !blocking.some(isFullSnapshotWarning)) {
|
|
113
130
|
return false;
|
|
114
131
|
}
|
|
115
|
-
const normalizedFocusFiles = normalizeFocusFiles(focusFiles);
|
|
132
|
+
const normalizedFocusFiles = normalizeFocusFiles(focusFiles, focusFilesAreLiteral === true);
|
|
116
133
|
if (!normalizedFocusFiles.length) {
|
|
117
134
|
return false;
|
|
118
135
|
}
|
|
@@ -122,10 +139,10 @@
|
|
|
122
139
|
|
|
123
140
|
const textFilesByPath = new Map((project.files || [])
|
|
124
141
|
.filter(file => file && typeof file.path === 'string' && typeof file.content === 'string')
|
|
125
|
-
.map(file => [normalizeFocusPath(file.path), file]));
|
|
142
|
+
.map(file => [normalizeFocusPath(file.path, true), file]));
|
|
126
143
|
|
|
127
144
|
return normalizedFocusFiles.every(filePath => {
|
|
128
|
-
const file = textFilesByPath.get(
|
|
145
|
+
const file = textFilesByPath.get(filePath);
|
|
129
146
|
return file && isUsableProjectFileContent(file.content);
|
|
130
147
|
});
|
|
131
148
|
}
|
|
@@ -138,11 +155,11 @@
|
|
|
138
155
|
return /Full project snapshot was not captured/i.test(String(warning || ''));
|
|
139
156
|
}
|
|
140
157
|
|
|
141
|
-
function normalizeFocusFiles(value) {
|
|
158
|
+
function normalizeFocusFiles(value, literal = false) {
|
|
142
159
|
const seen = new Set();
|
|
143
160
|
const files = [];
|
|
144
161
|
for (const item of Array.isArray(value) ? value : []) {
|
|
145
|
-
const filePath = normalizeFocusPath(item);
|
|
162
|
+
const filePath = normalizeFocusPath(item, literal);
|
|
146
163
|
if (!filePath || seen.has(filePath)) {
|
|
147
164
|
continue;
|
|
148
165
|
}
|
|
@@ -152,7 +169,8 @@
|
|
|
152
169
|
return files;
|
|
153
170
|
}
|
|
154
171
|
|
|
155
|
-
function normalizeFocusPath(value) {
|
|
172
|
+
function normalizeFocusPath(value, literal = false) {
|
|
173
|
+
if (literal) return ProjectFiles.normalizeSafeProjectPath(value);
|
|
156
174
|
return String(value || '')
|
|
157
175
|
.replace(/^@file:/i, '')
|
|
158
176
|
.replace(/\\/g, '/')
|
|
@@ -187,19 +205,22 @@
|
|
|
187
205
|
if (!isSafeSkillId(id)) {
|
|
188
206
|
return null;
|
|
189
207
|
}
|
|
190
|
-
const
|
|
191
|
-
|
|
208
|
+
const installer = id === 'skill-installer' && (value?.scope == null || value.scope === 'builtin');
|
|
209
|
+
const fallbackTitle = installer ? 'Skill Installer' : id;
|
|
210
|
+
const title = String(value?.title || fallbackTitle).trim().slice(0, 80) || fallbackTitle;
|
|
211
|
+
if (installer) {
|
|
192
212
|
return { id, title };
|
|
193
213
|
}
|
|
194
|
-
if (
|
|
214
|
+
if (!['codex-overleaf', 'codex-local'].includes(value?.scope)) {
|
|
195
215
|
return null;
|
|
196
216
|
}
|
|
197
|
-
return { id, title, scope:
|
|
217
|
+
return { id, title, scope: value.scope };
|
|
198
218
|
}
|
|
199
219
|
|
|
200
220
|
function isSafeSkillId(id) {
|
|
201
221
|
return /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$/.test(String(id || ''))
|
|
202
|
-
&& !String(id || '').includes('..')
|
|
222
|
+
&& !String(id || '').includes('..')
|
|
223
|
+
&& !['__proto__', 'prototype', 'constructor'].includes(id);
|
|
203
224
|
}
|
|
204
225
|
|
|
205
226
|
function normalizeAttachmentName(value) {
|
|
@@ -232,7 +253,9 @@
|
|
|
232
253
|
}
|
|
233
254
|
|
|
234
255
|
function isRetryReplacementEligible(run = {}, projection = {}) {
|
|
235
|
-
if (
|
|
256
|
+
if (run.retryWriteback || run.saveCheck) return false;
|
|
257
|
+
if (!run.id || run.forkSnapshot === true
|
|
258
|
+
|| !['failed', 'interrupted', 'cancelled', 'rejected'].includes(run.status)) return false;
|
|
236
259
|
if (run.trackedChangeStatus || run.undoStatus) return false;
|
|
237
260
|
if (['undoOperations', 'undoTrackedChanges', 'undoExpectedFiles', 'undoBaseFiles', 'appliedOperations']
|
|
238
261
|
.some(field => Array.isArray(run[field]) && run[field].length)) return false;
|
|
@@ -264,6 +287,8 @@
|
|
|
264
287
|
}
|
|
265
288
|
|
|
266
289
|
return {
|
|
290
|
+
captureSessionContext,
|
|
291
|
+
isSubmittedComposerUnchanged,
|
|
267
292
|
buildCodexRunParams,
|
|
268
293
|
canUseFocusedPartialSnapshot,
|
|
269
294
|
shouldRestrictWritebackToFocus,
|
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
(function initRunFailureNotice(root, factory) {
|
|
2
2
|
if (typeof module === 'object' && module.exports) {
|
|
3
|
-
module.exports = factory();
|
|
3
|
+
module.exports = factory(require('../shared/failureReasons'));
|
|
4
4
|
} else {
|
|
5
|
-
root.CodexOverleafModuleRegistry.define('RunFailureNotice', [], factory);
|
|
5
|
+
root.CodexOverleafModuleRegistry.define('RunFailureNotice', ['FailureReasons'], factory);
|
|
6
6
|
}
|
|
7
|
-
})(typeof window !== 'undefined' ? window : globalThis, function runFailureNoticeFactory() {
|
|
7
|
+
})(typeof window !== 'undefined' ? window : globalThis, function runFailureNoticeFactory(FailureReasons) {
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
const REVIEW_CODES = new Set(['write_timeout', 'partial_write_needs_review']);
|
|
11
11
|
const CANCEL_CODES = new Set(['cancelled', 'user_cancelled', 'codex_cancelled']);
|
|
12
|
+
// Old attempts remain in the stored audit trail; a resolved undo must not
|
|
13
|
+
// advertise them as a current failure in the transcript or its summary.
|
|
14
|
+
function projectResolvedUndo(run) {
|
|
15
|
+
if (!run || (run.undoStatus !== 'applied' && run.trackedChangeStatus !== 'rejected')
|
|
16
|
+
|| !Array.isArray(run.events)) return run;
|
|
17
|
+
const events = run.events.filter(event => {
|
|
18
|
+
if (event?.status !== 'failed' || event.streamRole
|
|
19
|
+
|| ['report', 'guidance', 'stream'].includes(event.kind)) return true;
|
|
20
|
+
return !/^(?:Undo result:\s*(?:undone|rejected)\s+\d+\s+(?:item\(s\)|file\(s\)|tracked change\(s\)),\s*skipped\s+\d+(?:\s+item\(s\))?|撤销结果[::]\s*已(?:撤销|拒绝)\s*\d+\s*(?:项|条留痕|个文件),\s*跳过\s*\d+\s*(?:项|条))$/.test(String(event.title || '').trim());
|
|
21
|
+
});
|
|
22
|
+
return events.length === run.events.length ? run : { ...run, events };
|
|
23
|
+
}
|
|
12
24
|
|
|
13
25
|
function create({ tr, projectRunSettlement, sanitizeText = value => value,
|
|
14
26
|
document: documentRef = globalThis.document } = {}) {
|
|
@@ -20,7 +32,7 @@
|
|
|
20
32
|
const failure = projection?.primaryFailure || event.failure;
|
|
21
33
|
if (report.dataset.status === 'cancelled' || CANCEL_CODES.has(failure?.code)) return;
|
|
22
34
|
const facts = run?.settlement || run?.settlementFacts || {};
|
|
23
|
-
const unconfirmed = REVIEW_CODES.has(failure?.code)
|
|
35
|
+
const unconfirmed = projection?.requiresWriteReview === true || REVIEW_CODES.has(failure?.code)
|
|
24
36
|
|| facts.documentEffect === 'possibly-changed'
|
|
25
37
|
|| (facts.evidence?.applied === 'unknown' && facts.evidence?.settled === 'needs-review');
|
|
26
38
|
const partial = facts.evidence?.applied === 'partial' || run?.partialWriteback === true;
|
|
@@ -36,9 +48,14 @@
|
|
|
36
48
|
heading.textContent = tr(unconfirmed ? 'runFeedbackUnconfirmedTitle'
|
|
37
49
|
: partial ? 'runFeedbackPartialTitle' : 'runFeedbackFailedTitle');
|
|
38
50
|
const message = documentRef.createElement('p');
|
|
39
|
-
const detail = typeof failure?.userMessage === 'string' ? failure.userMessage : '';
|
|
40
51
|
const file = safeProjectPath(failure?.file);
|
|
41
|
-
|
|
52
|
+
// Localization is a display projection. Recovery keeps the original
|
|
53
|
+
// failure and its trusted file, even when historical text yields a path.
|
|
54
|
+
const display = FailureReasons?.formatFailureReasonForDisplay?.(failure, undefined, key => {
|
|
55
|
+
const value = tr(key);
|
|
56
|
+
return value && value !== key ? value : undefined;
|
|
57
|
+
});
|
|
58
|
+
message.textContent = sanitizeText((display?.message || [file, failure?.userMessage].filter(Boolean).join(': ')).slice(0, 1000))
|
|
42
59
|
|| tr('runFeedbackGeneric');
|
|
43
60
|
notice.append(heading, message);
|
|
44
61
|
if (unconfirmed) {
|
|
@@ -61,10 +78,15 @@
|
|
|
61
78
|
return row.value;
|
|
62
79
|
}
|
|
63
80
|
|
|
64
|
-
function
|
|
81
|
+
function getRecoveryContext(report) {
|
|
65
82
|
const info = notices.get(report);
|
|
66
|
-
|
|
67
|
-
|
|
83
|
+
return { target: info?.notice || report, failure: info?.failure, unconfirmed: info?.unconfirmed === true, file: info?.file || '' };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function prepareRecovery(report, { openFile } = {}) {
|
|
87
|
+
const info = getRecoveryContext(report);
|
|
88
|
+
const target = info.target;
|
|
89
|
+
if (!info.unconfirmed) return { target, handled: false, failure: info.failure };
|
|
68
90
|
const canOpen = Boolean(info.file && typeof openFile === 'function');
|
|
69
91
|
const button = documentRef.createElement('button');
|
|
70
92
|
button.type = 'button';
|
|
@@ -87,10 +109,10 @@
|
|
|
87
109
|
}
|
|
88
110
|
});
|
|
89
111
|
target.append(button);
|
|
90
|
-
return { target, handled: true };
|
|
112
|
+
return { target, handled: true, failure: info.failure };
|
|
91
113
|
}
|
|
92
114
|
|
|
93
|
-
return Object.freeze({ append, formatMetaValue, prepareRecovery });
|
|
115
|
+
return Object.freeze({ append, formatMetaValue, getRecoveryContext, prepareRecovery });
|
|
94
116
|
}
|
|
95
117
|
|
|
96
118
|
function safeProjectPath(value) {
|
|
@@ -100,5 +122,5 @@
|
|
|
100
122
|
&& !path.split('/').includes('..') ? path.slice(0, 300) : '';
|
|
101
123
|
}
|
|
102
124
|
|
|
103
|
-
return Object.freeze({ create });
|
|
125
|
+
return Object.freeze({ create, projectResolvedUndo });
|
|
104
126
|
});
|