codex-overleaf-link 2.4.1 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +272 -314
- package/README.zh-CN.md +287 -329
- package/extension/bootstrap/background.js +47 -10
- package/extension/bootstrap/manifest.template.json +9 -4
- package/extension/bootstrap/popup.html +10 -16
- package/extension/bootstrap/update.js +25 -2
- package/extension/runtime-manifest.json +3 -1
- package/extension/src/background.js +28 -3
- package/extension/src/backgroundSharedSessions.js +380 -0
- package/extension/src/backgroundUpdateCoordinator.js +442 -379
- package/extension/src/content/activeTurnControl.js +8 -0
- package/extension/src/content/assetTransferBroker.js +186 -12
- package/extension/src/content/changeHistoryView.js +175 -0
- package/extension/src/content/composerAttachments.js +24 -22
- package/extension/src/content/composerPanel.js +23 -8
- package/extension/src/content/contentRuntime.js +507 -507
- package/extension/src/content/diagnosticsController.js +1 -2
- package/extension/src/content/diagnosticsExport.js +222 -0
- package/extension/src/content/diagnosticsPanel.js +48 -19
- package/extension/src/content/diffReviewPanel.js +8 -5
- package/extension/src/content/generated/content.bundle.js +8330 -1349
- package/extension/src/content/generated/content.bundle.meta.json +22 -3
- package/extension/src/content/legacyGlobalRegistry.js +19 -1
- package/extension/src/content/localSkillsPanel.js +42 -7
- package/extension/src/content/markdownDomRenderer.js +9 -4
- package/extension/src/content/modelPicker.js +1 -1
- package/extension/src/content/pageBridgeClient.js +18 -3
- package/extension/src/content/panelMaintenance.js +48 -121
- package/extension/src/content/panelRenderer.js +4 -0
- package/extension/src/content/pendingInputView.js +109 -76
- package/extension/src/content/providerSettingsCoordinator.js +17 -6
- package/extension/src/content/providerSettingsDialog.js +661 -108
- package/extension/src/content/recentProjects.js +10 -1
- package/extension/src/content/runActivitySummary.js +631 -0
- package/extension/src/content/runController.js +3 -1
- package/extension/src/content/runFailureNotice.js +14 -1
- package/extension/src/content/runGuidanceController.js +4 -3
- package/extension/src/content/runPresence.js +306 -0
- package/extension/src/content/runQueueScheduler.js +2 -1
- package/extension/src/content/runResultActions.js +123 -3
- package/extension/src/content/runTimelineView.js +186 -154
- package/extension/src/content/selectionContextView.js +300 -0
- package/extension/src/content/sessionPersistence.js +6 -1
- package/extension/src/content/settingsPanel.js +77 -52
- package/extension/src/content/settingsWorkbench.js +374 -0
- package/extension/src/content/sharedSessionViewSync.js +72 -0
- package/extension/src/content/subagentActivityView.js +195 -0
- package/extension/src/content/trackedChangeCaptureController.js +7 -3
- package/extension/src/content/updateNotice.js +121 -50
- package/extension/src/content/writebackController.js +257 -0
- package/extension/src/content/writebackOrchestrator.js +146 -141
- package/extension/src/content/writebackPlan.js +231 -0
- package/extension/src/content/writebackRecovery.js +122 -0
- package/extension/src/content/writingStyleSettings.js +576 -0
- package/extension/src/content/writtenChangesView.js +152 -0
- package/extension/src/page/binaryAssetUploader.js +97 -19
- package/extension/src/page/overleafProjectSnapshot.js +1 -0
- package/extension/src/page/referenceProjects.js +148 -0
- package/extension/src/page/saveState.js +14 -2
- package/extension/src/page/snapshotRouter.js +44 -13
- package/extension/src/page/textCoordinates.js +102 -0
- package/extension/src/page/textFileCreator.js +350 -59
- package/extension/src/page/trackedChangeCapture.js +42 -56
- package/extension/src/page/trackedChangeOwnership.js +198 -0
- package/extension/src/page/trackedChangeReplay.js +164 -0
- package/extension/src/page/trackedChangesLifecycle.js +135 -149
- package/extension/src/page/treeOperations.js +26 -2
- package/extension/src/page/writebackReceiptJournal.js +112 -0
- package/extension/src/page/writebackRouter.js +175 -135
- package/extension/src/pageBridge.js +56 -101
- package/extension/src/popup.js +203 -59
- package/extension/src/shared/agentTranscript.js +18 -4
- package/extension/src/shared/auditRecords.js +71 -0
- package/extension/src/shared/changeHistoryModel.js +94 -0
- package/extension/src/shared/compatibility.js +1 -1
- package/extension/src/shared/compileAdapter.js +42 -0
- package/extension/src/shared/failureReasons.js +20 -0
- package/extension/src/shared/globalPreferences.js +1 -1
- package/extension/src/shared/i18n.js +93 -25
- package/extension/src/shared/managedUpdateProjection.js +6 -3
- package/extension/src/shared/pageRpcContract.js +7 -1
- package/extension/src/shared/providerProfiles.js +109 -0
- package/extension/src/shared/runActivityModel.js +361 -0
- package/extension/src/shared/runExecutionSnapshot.js +8 -2
- package/extension/src/shared/runExecutionSnapshotCodec.js +16 -4
- package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
- package/extension/src/shared/selectionContext.js +28 -0
- package/extension/src/shared/sessionState.js +97 -6
- package/extension/src/shared/sharedSessionBridge.js +288 -0
- package/extension/src/shared/storageDb.js +22 -55
- package/extension/src/shared/storageMigration.js +3 -0
- package/extension/src/shared/storageRunActions.js +10 -4
- package/extension/src/shared/storageValuePruning.js +40 -0
- package/extension/src/shared/subagentActivityModel.js +174 -0
- package/extension/src/shared/undoOperations.js +87 -0
- package/extension/src/shared/updateConsent.js +37 -8
- package/extension/src/shared/writebackIntent.js +62 -0
- package/extension/src/shared/writebackSettlement.js +29 -10
- package/extension/src/shared/writingStyle.js +33 -0
- package/extension/styles/panel.css +1972 -384
- package/extension/styles/popup.css +110 -0
- package/native-host/src/anthropicBridgeRequest.js +2 -1
- package/native-host/src/codexModelRecovery.js +107 -0
- package/native-host/src/codexPromptAssembly.js +2 -0
- package/native-host/src/codexProviderLaunch.js +3 -3
- package/native-host/src/codexRuntimeIdentity.js +1 -0
- package/native-host/src/codexSessionRunner.js +106 -140
- package/native-host/src/codexSessionTiming.js +3 -0
- package/native-host/src/managedInstall.js +5 -4
- package/native-host/src/nativeEnvironment.js +70 -0
- package/native-host/src/nativeQuotas.js +15 -8
- package/native-host/src/overleafWorkspaceRules.js +16 -0
- package/native-host/src/processStopBarrier.js +80 -0
- package/native-host/src/providerModelCatalog.js +4 -3
- package/native-host/src/providerProfile.js +13 -1
- package/native-host/src/providerReasoning.js +9 -5
- package/native-host/src/providerStore.js +4 -0
- package/native-host/src/releaseTransport.js +14 -5
- package/native-host/src/selectionScope.js +58 -0
- package/native-host/src/skills/parallel-subagents/SKILL.md +31 -3
- package/native-host/src/skills/writing-style-builder/SKILL.md +146 -0
- package/native-host/src/subagentBroker.js +102 -98
- package/native-host/src/subagentTelemetry.js +316 -0
- package/native-host/src/subagentWorkspace.js +103 -0
- package/native-host/src/subagentWorkspacePath.js +31 -0
- package/native-host/src/taskRunnerRuntime.js +55 -5
- package/native-host/src/turnAttachments.js +113 -0
- package/native-host/src/updateManager.js +122 -12
- package/native-host/src/updateNetworkControl.js +75 -0
- package/native-host/src/updateTrust.js +21 -2
- package/native-host/src/vendor/pdfjs/LICENSE +177 -0
- package/native-host/src/vendor/pdfjs/SOURCE.txt +3 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/LICENSE +36 -0
- package/native-host/src/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/pdf.mjs +26740 -0
- package/native-host/src/vendor/pdfjs/pdf.worker.mjs +62201 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/native-host/src/writingStyleEvidence.js +102 -0
- package/native-host/src/writingStylePdfWorker.js +35 -0
- package/native-host/src/writingStyleProfile.js +165 -0
- package/native-host/src/writingStyleRuntime.js +447 -0
- package/package.json +1 -1
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
(function initStorageDb(root, factory) {
|
|
2
2
|
if (typeof module === 'object' && module.exports) {
|
|
3
3
|
module.exports = factory(require('./storageRunActions'), require('./runInputQueue'),
|
|
4
|
-
require('./settlementFacts'), require('./storageSessionClaims'), require('./sessionState'));
|
|
4
|
+
require('./settlementFacts'), require('./storageSessionClaims'), require('./sessionState'), require('./runActivityModel'), require('./sharedSessionBridge'), require('./subagentActivityModel'), require('./storageValuePruning'));
|
|
5
5
|
} else {
|
|
6
6
|
root.CodexOverleafModuleRegistry.define('StorageDb', [
|
|
7
7
|
'StorageRunActions',
|
|
8
8
|
'RunInputQueue',
|
|
9
9
|
'SettlementFacts',
|
|
10
10
|
'StorageSessionClaims',
|
|
11
|
-
'SessionState'
|
|
11
|
+
'SessionState',
|
|
12
|
+
'RunActivityModel',
|
|
13
|
+
'SharedSessionBridge',
|
|
14
|
+
'SubagentActivityModel',
|
|
15
|
+
'StorageValuePruning'
|
|
12
16
|
], factory);
|
|
13
17
|
}
|
|
14
|
-
})(typeof globalThis !== 'undefined' ? globalThis : window, function storageDbFactory(StorageRunActions, RunInputQueue, SettlementFacts, StorageSessionClaims, SessionState) {
|
|
18
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window, function storageDbFactory(StorageRunActions, RunInputQueue, SettlementFacts, StorageSessionClaims, SessionState, RunActivityModel, SharedSessionBridge, SubagentActivityModel, StorageValuePruning) {
|
|
15
19
|
'use strict';
|
|
20
|
+
const { removeEmptySummaryFields, removeEmptyFields } = StorageValuePruning;
|
|
16
21
|
if (!StorageRunActions?.compactRunsForStorage || !StorageRunActions?.compactRunActionPayload || !StorageRunActions?.compactProviderSnapshot || !StorageRunActions?.compactRunExecutionSnapshot || !StorageRunActions?.compactStructuredEventValue || !StorageRunActions?.hashString || !RunInputQueue?.compactForStorage || !SettlementFacts?.compactSettlementFacts || !StorageSessionClaims?.createSessionClaimer) {
|
|
17
22
|
throw new Error('Codex Overleaf storage run-action helpers are unavailable.');
|
|
18
23
|
}
|
|
@@ -280,6 +285,7 @@
|
|
|
280
285
|
codexThreadId: typeof input.codexThreadId === 'string' ? input.codexThreadId : '',
|
|
281
286
|
status: typeof input.status === 'string' && input.status ? input.status : 'active',
|
|
282
287
|
focusFiles: normalizePathList(input.focusFiles),
|
|
288
|
+
selectionContext: SessionState.normalizeSelectionContext(input.selectionContext),
|
|
283
289
|
projectReferenceFiles: SessionState.normalizeProjectReferenceFiles(input.projectReferenceFiles),
|
|
284
290
|
pendingInputs: RunInputQueue.compactForStorage(input.pendingInputs, {
|
|
285
291
|
normalizeField: normalizeTextField,
|
|
@@ -655,8 +661,10 @@
|
|
|
655
661
|
return StorageRunActions.compactRunsForStorage(runs, options, SESSION_STORAGE_LIMITS.maxRunsPerSession, compactRunForStorage);
|
|
656
662
|
}
|
|
657
663
|
function compactRunForStorage(run, keepActionPayload) {
|
|
664
|
+
run = SessionState.recoverRecordedRunFailure(run);
|
|
658
665
|
var actionPayload = StorageRunActions.compactRunActionPayload(run, keepActionPayload);
|
|
659
666
|
var compact = {
|
|
667
|
+
...SessionState.pickWritebackRecovery(run),
|
|
660
668
|
id: run.id,
|
|
661
669
|
task: normalizeDisplayTextForStorage(run.task || 'untitled task', SESSION_STORAGE_LIMITS.taskChars),
|
|
662
670
|
mode: typeof run.mode === 'string' ? redactSecretLikeText(run.mode) : '', ...StorageRunActions.compactProviderSnapshot(run),
|
|
@@ -664,12 +672,13 @@
|
|
|
664
672
|
model: normalizeTextField(run.model, 80),
|
|
665
673
|
reasoningEffort: typeof run.reasoningEffort === 'string' ? redactSecretLikeText(run.reasoningEffort) : '',
|
|
666
674
|
speedTier: typeof run.speedTier === 'string' ? redactSecretLikeText(run.speedTier) : '',
|
|
667
|
-
status: normalizeRunStatus(run.status),
|
|
675
|
+
status: SessionState.normalizeRunStatus(run.status, run),
|
|
668
676
|
statusText: normalizeDisplayTextForStorage(run.statusText, SESSION_STORAGE_LIMITS.statusTextChars),
|
|
669
677
|
runProjectId: normalizeProjectPrefKey(run.runProjectId),
|
|
670
678
|
startedAt: typeof run.startedAt === 'string' ? redactSecretLikeText(run.startedAt) : '',
|
|
671
679
|
finishedAt: typeof run.finishedAt === 'string' ? redactSecretLikeText(run.finishedAt) : '',
|
|
672
680
|
events: compactRunEventsForStorage(run.events),
|
|
681
|
+
...(run.subagents?.length ? { subagents: SubagentActivityModel.normalize(run.subagents, sanitizeAssistantVisibleText) } : {}),
|
|
673
682
|
attachments: compactRunAttachmentsForStorage(run.attachments),
|
|
674
683
|
appliedOperations: actionPayload.appliedOperations,
|
|
675
684
|
undoOperations: actionPayload.undoOperations,
|
|
@@ -719,6 +728,13 @@
|
|
|
719
728
|
streamKey: typeof event.streamKey === 'string' ? redactSecretLikeText(event.streamKey) : '',
|
|
720
729
|
streamRole: typeof event.streamRole === 'string' ? redactSecretLikeText(event.streamRole) : ''
|
|
721
730
|
};
|
|
731
|
+
// Persist the bounded display projection, never the raw tool payload.
|
|
732
|
+
// Hydration uses the same model; dropping this metadata demotes tools
|
|
733
|
+
// to hidden diagnostics after an otherwise successful history reload.
|
|
734
|
+
var activity = RunActivityModel.capture(event, sanitizeAssistantVisibleText);
|
|
735
|
+
if (activity) compact.activity = activity;
|
|
736
|
+
var streamPhase = RunActivityModel.normalizePhase(event.streamPhase);
|
|
737
|
+
if (streamPhase) compact.streamPhase = streamPhase;
|
|
722
738
|
if (event.subagent === true) {
|
|
723
739
|
compact.subagent = true;
|
|
724
740
|
}
|
|
@@ -914,25 +930,6 @@
|
|
|
914
930
|
.trim(), maxChars || SESSION_STORAGE_LIMITS.pathChars);
|
|
915
931
|
}
|
|
916
932
|
|
|
917
|
-
function normalizeRunStatus(status) {
|
|
918
|
-
// Welcome-panel + write-guard: the run-status
|
|
919
|
-
// enum gained three post-navigation values. The storage normalizer must
|
|
920
|
-
// accept them so a settled run round-trips intact through `buildSessionRecord`.
|
|
921
|
-
// Unknown legacy values fall through to `completed` (the historical default).
|
|
922
|
-
return [
|
|
923
|
-
'pending',
|
|
924
|
-
'running',
|
|
925
|
-
'completed',
|
|
926
|
-
'failed',
|
|
927
|
-
'background_completed',
|
|
928
|
-
'needs_review_after_navigation',
|
|
929
|
-
'abandoned_after_navigation',
|
|
930
|
-
// v1.8.1: reload-orphaned runs settle to 'interrupted' (v1.7.6); the
|
|
931
|
-
// storage round-trip must not rewrite them to a false 'completed'.
|
|
932
|
-
'interrupted'
|
|
933
|
-
].indexOf(status) !== -1 ? status : 'completed';
|
|
934
|
-
}
|
|
935
|
-
|
|
936
933
|
function normalizeEventStatus(status) {
|
|
937
934
|
return VALID_EVENT_STATUSES[status] ? status : 'info';
|
|
938
935
|
}
|
|
@@ -1106,37 +1103,7 @@
|
|
|
1106
1103
|
return 'error';
|
|
1107
1104
|
}
|
|
1108
1105
|
|
|
1109
|
-
function removeEmptySummaryFields(value) {
|
|
1110
|
-
var result = {};
|
|
1111
|
-
var keys = Object.keys(value || {});
|
|
1112
|
-
for (var i = 0; i < keys.length; i++) {
|
|
1113
|
-
var key = keys[i];
|
|
1114
|
-
var item = value[key];
|
|
1115
|
-
if (item === undefined || item === '' || item === null) {
|
|
1116
|
-
continue;
|
|
1117
|
-
}
|
|
1118
|
-
if (Array.isArray(item) && item.length === 0) {
|
|
1119
|
-
continue;
|
|
1120
|
-
}
|
|
1121
|
-
if (item && typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0) {
|
|
1122
|
-
continue;
|
|
1123
|
-
}
|
|
1124
|
-
result[key] = item;
|
|
1125
|
-
}
|
|
1126
|
-
return result;
|
|
1127
|
-
}
|
|
1128
1106
|
|
|
1129
|
-
function removeEmptyFields(value) {
|
|
1130
|
-
var result = {};
|
|
1131
|
-
var keys = Object.keys(value);
|
|
1132
|
-
for (var i = 0; i < keys.length; i++) {
|
|
1133
|
-
var key = keys[i];
|
|
1134
|
-
if (value[key] !== undefined && value[key] !== '') {
|
|
1135
|
-
result[key] = value[key];
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
return result;
|
|
1139
|
-
}
|
|
1140
1107
|
|
|
1141
1108
|
// Welcome-panel + write-guard: the Recent-projects
|
|
1142
1109
|
// dashboard variant calls `listRecentProjectsAcrossAccount` to get the
|
|
@@ -1328,7 +1295,7 @@
|
|
|
1328
1295
|
}
|
|
1329
1296
|
var hashString = StorageRunActions.hashString;
|
|
1330
1297
|
|
|
1331
|
-
return {
|
|
1298
|
+
return SharedSessionBridge.decorate({
|
|
1332
1299
|
TARGET_SCHEMA_VERSION: TARGET_SCHEMA_VERSION,
|
|
1333
1300
|
DB_NAME: DB_NAME,
|
|
1334
1301
|
STORES: STORES,
|
|
@@ -1355,5 +1322,5 @@
|
|
|
1355
1322
|
filterRecentProjectsAcrossAccount: filterRecentProjectsAcrossAccount,
|
|
1356
1323
|
derivePrimaryStatusBadge: derivePrimaryStatusBadge,
|
|
1357
1324
|
getAllSessions: getAllSessions
|
|
1358
|
-
};
|
|
1325
|
+
});
|
|
1359
1326
|
});
|
|
@@ -50,6 +50,9 @@
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function withProjectPreferenceLock(projectId, work) {
|
|
53
|
+
if (StorageDb.sharedSessionsEnabled?.()) {
|
|
54
|
+
return StorageDb.withSharedLock('preferences', { projectId: projectId }, work);
|
|
55
|
+
}
|
|
53
56
|
var lockName = 'codex-overleaf-project-prefs:' + compactScopePart(projectId);
|
|
54
57
|
var lockManager = typeof navigator !== 'undefined' && navigator && navigator.locks;
|
|
55
58
|
if (lockManager && typeof lockManager.request === 'function') {
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
(function initStorageRunActions(root, factory) {
|
|
2
2
|
if (typeof module === 'object' && module.exports) {
|
|
3
|
-
module.exports = factory();
|
|
3
|
+
module.exports = factory(require('./selectionContext'), require('./writebackIntent'), require('./writingStyle'));
|
|
4
4
|
} else {
|
|
5
|
-
root.
|
|
5
|
+
root.CodexOverleafModuleRegistry.define('StorageRunActions', ['SelectionContext', 'WritebackIntent', 'WritingStyle'], factory);
|
|
6
6
|
}
|
|
7
|
-
})(typeof globalThis !== 'undefined' ? globalThis : window, function storageRunActionsFactory() {
|
|
7
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window, function storageRunActionsFactory(SelectionContext, WritebackIntent, WritingStyle) {
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
var MAX_PERSISTED_ACTION_RUNS_PER_SESSION = 2;
|
|
11
|
-
|
|
11
|
+
// Undo/Accept need whole pre- and post-images of every written file, so one
|
|
12
|
+
// run that edits a 120 KB roadmap and creates a 100 KB chapter already needs
|
|
13
|
+
// ~560 KB. The old 320 KB cap silently dropped the whole payload and the
|
|
14
|
+
// buttons vanished after a reload. Two runs per session keep this bounded.
|
|
15
|
+
var MAX_PERSISTED_ACTION_BYTES_PER_RUN = 2 * 1024 * 1024;
|
|
12
16
|
|
|
13
17
|
function compactRunsForStorage(runs, options, maxRuns, compactRun) {
|
|
14
18
|
if (typeof compactRun !== 'function') {
|
|
@@ -126,6 +130,8 @@
|
|
|
126
130
|
compact.focusFiles = snapshot.focusFiles.slice(0, 100)
|
|
127
131
|
.filter(function (value) { return typeof value === 'string'; }).map(normalize);
|
|
128
132
|
}
|
|
133
|
+
compact.selectionContext = SelectionContext.normalize(snapshot.selectionContext);
|
|
134
|
+
compact.writingStyle = WritingStyle.normalizeSnapshot(snapshot.writingStyle);
|
|
129
135
|
return { executionSnapshot: compact };
|
|
130
136
|
}
|
|
131
137
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
(function (root, factory) {
|
|
2
|
+
if (typeof module === 'object' && module.exports) module.exports = factory();
|
|
3
|
+
else root.CodexOverleafModuleRegistry.define('StorageValuePruning', [], factory);
|
|
4
|
+
})(typeof globalThis !== 'undefined' ? globalThis : this, function () {
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
function removeEmptySummaryFields(value) {
|
|
8
|
+
var result = {};
|
|
9
|
+
var keys = Object.keys(value || {});
|
|
10
|
+
for (var i = 0; i < keys.length; i++) {
|
|
11
|
+
var key = keys[i];
|
|
12
|
+
var item = value[key];
|
|
13
|
+
if (item === undefined || item === '' || item === null) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (Array.isArray(item) && item.length === 0) {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
if (item && typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
result[key] = item;
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function removeEmptyFields(value) {
|
|
28
|
+
var result = {};
|
|
29
|
+
var keys = Object.keys(value);
|
|
30
|
+
for (var i = 0; i < keys.length; i++) {
|
|
31
|
+
var key = keys[i];
|
|
32
|
+
if (value[key] !== undefined && value[key] !== '') {
|
|
33
|
+
result[key] = value[key];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return { removeEmptySummaryFields, removeEmptyFields };
|
|
40
|
+
});
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
(function initSubagentActivityModel(root, factory) {
|
|
2
|
+
if (typeof module === 'object' && module.exports) {
|
|
3
|
+
module.exports = factory(require('./agentTranscript'), require('./runActivityModel'));
|
|
4
|
+
} else root.CodexOverleafModuleRegistry.define('SubagentActivityModel', ['AgentTranscript', 'RunActivityModel'], factory);
|
|
5
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window, function subagentActivityModelFactory(Transcript, Activity) {
|
|
6
|
+
'use strict';
|
|
7
|
+
const MAX_AGENTS = 16, MAX_EVENTS = 100, MAX_CHARS = 48000;
|
|
8
|
+
const STATES = new Set(['pending', 'running', 'completed', 'failed', 'cancelled', 'unknown']);
|
|
9
|
+
const TERMINAL = new Set(['completed', 'failed', 'cancelled']);
|
|
10
|
+
const string = value => typeof value === 'string' ? value : '';
|
|
11
|
+
function clean(value, sanitize = string, limit = 24000) {
|
|
12
|
+
return string(sanitize(string(value))).slice(0, limit);
|
|
13
|
+
}
|
|
14
|
+
function trim(agent) {
|
|
15
|
+
if (agent.events.length > MAX_EVENTS) { agent.events = agent.events.slice(-MAX_EVENTS); agent.clipped = true; }
|
|
16
|
+
while (agent.events.length > 1 && JSON.stringify(agent.events).length > MAX_CHARS) {
|
|
17
|
+
agent.events.shift(); agent.clipped = true;
|
|
18
|
+
}
|
|
19
|
+
return agent;
|
|
20
|
+
}
|
|
21
|
+
function normalize(agents, sanitize = string) {
|
|
22
|
+
const seen = new Set();
|
|
23
|
+
return (Array.isArray(agents) ? agents : []).slice(0, MAX_AGENTS).filter(agent => {
|
|
24
|
+
if (!agent || !['broker', 'codex'].includes(agent.source)) return false;
|
|
25
|
+
const id = agent.source === 'broker' ? agent.jobId : agent.threadId;
|
|
26
|
+
if (typeof id !== 'string' || !/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,159}$/.test(id)) return false;
|
|
27
|
+
const key = agent.source + ':' + id;
|
|
28
|
+
if (seen.has(key)) return false;
|
|
29
|
+
seen.add(key); return true;
|
|
30
|
+
}).map(agent => trim({
|
|
31
|
+
v: 1, source: agent.source, key: agent.source + ':' + (agent.source === 'broker' ? agent.jobId : agent.threadId),
|
|
32
|
+
jobId: clean(agent.jobId, sanitize, 160), threadId: clean(agent.threadId, sanitize, 160),
|
|
33
|
+
parentThreadId: clean(agent.parentThreadId, sanitize, 160),
|
|
34
|
+
title: clean(agent.title, sanitize, 160), task: clean(agent.task, sanitize, 4096),
|
|
35
|
+
model: clean(agent.model, sanitize, 160), reasoningEffort: clean(agent.reasoningEffort, sanitize, 32),
|
|
36
|
+
status: STATES.has(agent.status) ? agent.status : 'unknown',
|
|
37
|
+
startedAt: clean(agent.startedAt, sanitize, 64), updatedAt: clean(agent.updatedAt, sanitize, 64),
|
|
38
|
+
finishedAt: clean(agent.finishedAt, sanitize, 64),
|
|
39
|
+
lastSequence: Number.isSafeInteger(agent.lastSequence) ? agent.lastSequence : 0,
|
|
40
|
+
nativeEventSeq: Number.isSafeInteger(agent.nativeEventSeq) ? agent.nativeEventSeq : 0,
|
|
41
|
+
clipped: agent.clipped === true, historyUnavailable: agent.historyUnavailable === true,
|
|
42
|
+
events: (Array.isArray(agent.events) ? agent.events : []).filter(event => event && typeof event.title === 'string')
|
|
43
|
+
.slice(-MAX_EVENTS).map(event => ({
|
|
44
|
+
title: clean(event.title, sanitize), status: clean(event.status, sanitize, 32),
|
|
45
|
+
timestamp: clean(event.timestamp, sanitize, 64),
|
|
46
|
+
kind: event.kind === 'stream' ? 'stream' : 'activity',
|
|
47
|
+
streamKey: clean(event.streamKey, sanitize, 600), streamRole: event.streamRole === 'assistant' ? 'assistant' : '',
|
|
48
|
+
streamPhase: Activity.normalizePhase(event.streamPhase),
|
|
49
|
+
activity: Activity.normalize(event.activity, sanitize)
|
|
50
|
+
}))
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
function effectiveStatus(agent, run) {
|
|
54
|
+
if (TERMINAL.has(agent.status) || agent.status === 'unknown' || run.status === 'running') return agent.status;
|
|
55
|
+
return ['cancelled', 'rejected'].includes(run.status) ? 'cancelled' : 'unknown';
|
|
56
|
+
}
|
|
57
|
+
function terminalTime(agent, run) {
|
|
58
|
+
const terminal = [agent.finishedAt, run.status === 'running' ? '' : run.finishedAt]
|
|
59
|
+
.map(value => Date.parse(value || '')).find(Number.isFinite);
|
|
60
|
+
const evidence = [agent.startedAt, agent.updatedAt, ...(agent.events || []).map(event => event.timestamp)];
|
|
61
|
+
if (run.status !== 'running') evidence.push(run.startedAt, run.updatedAt, ...(run.events || []).map(event => event.timestamp));
|
|
62
|
+
return terminal ?? Math.max(...evidence.map(value => Date.parse(value || '')).filter(Number.isFinite));
|
|
63
|
+
}
|
|
64
|
+
function elapsedMs(agent, run, now = Date.now()) {
|
|
65
|
+
const start = Date.parse(agent.startedAt || '');
|
|
66
|
+
const live = run.status === 'running' && ['pending', 'running'].includes(effectiveStatus(agent, run));
|
|
67
|
+
return Number.isFinite(start) ? Math.max(0, (live ? now : terminalTime(agent, run)) - start) : null;
|
|
68
|
+
}
|
|
69
|
+
function append(agent, input, sanitize) {
|
|
70
|
+
const event = {
|
|
71
|
+
title: clean(input.title, sanitize), status: input.status || 'running',
|
|
72
|
+
timestamp: input.timestamp || new Date().toISOString(),
|
|
73
|
+
kind: input.kind === 'stream' ? 'stream' : 'activity',
|
|
74
|
+
streamKey: input.streamKey || '', streamRole: input.streamRole || '',
|
|
75
|
+
streamPhase: Activity.normalizePhase(input.streamPhase),
|
|
76
|
+
activity: Activity.normalize(input.activity, sanitize)
|
|
77
|
+
};
|
|
78
|
+
if (!event.title) return;
|
|
79
|
+
const key = event.kind === 'stream' ? 'stream:' + event.streamKey : event.activity?.id;
|
|
80
|
+
const previous = key && agent.events.find(old => (old.kind === 'stream' ? 'stream:' + old.streamKey : old.activity?.id) === key);
|
|
81
|
+
if (previous) {
|
|
82
|
+
if (previous.status === 'completed' && event.status === 'running' && input.appendText) return;
|
|
83
|
+
const fullText = input.appendText ? previous.title + event.title : event.title;
|
|
84
|
+
if (fullText.length > 24000) agent.clipped = true;
|
|
85
|
+
const activity = previous.activity && event.activity ? { ...previous.activity, ...event.activity,
|
|
86
|
+
command: event.activity.command || previous.activity.command,
|
|
87
|
+
output: event.activity.output || previous.activity.output,
|
|
88
|
+
paths: event.activity.paths?.length ? event.activity.paths : previous.activity.paths,
|
|
89
|
+
files: event.activity.files?.length ? event.activity.files : previous.activity.files } : event.activity || previous.activity;
|
|
90
|
+
Object.assign(previous, event, { title: fullText.slice(0, 24000), activity });
|
|
91
|
+
} else agent.events.push(event);
|
|
92
|
+
trim(agent);
|
|
93
|
+
}
|
|
94
|
+
function addAnswer(agent, answer, timestamp, sanitize) {
|
|
95
|
+
if (!answer) return;
|
|
96
|
+
const last = agent.events.filter(event => event.kind === 'stream' && event.streamRole === 'assistant').at(-1);
|
|
97
|
+
const safe = clean(answer, sanitize);
|
|
98
|
+
if (last?.title.trim() === safe.trim()) { last.status = 'completed'; return; }
|
|
99
|
+
append(agent, { kind: 'stream', streamRole: 'assistant', streamPhase: 'final_answer',
|
|
100
|
+
streamKey: last?.streamPhase === 'final_answer' ? last.streamKey : 'answer:' + agent.key,
|
|
101
|
+
title: safe, status: 'completed', timestamp }, sanitize);
|
|
102
|
+
}
|
|
103
|
+
function ingest(run, raw, options = {}) {
|
|
104
|
+
const type = string(raw?.type), detail = raw?.detail || {};
|
|
105
|
+
if (type === 'codex.subagent.drained') return true;
|
|
106
|
+
if (!['codex.subagent.queued', 'codex.subagent.started', 'codex.subagent.completed',
|
|
107
|
+
'codex.subagent.failed', 'codex.subagent.rejected', 'codex.subagent.event', 'codex.subagent.observed'].includes(type)) return false;
|
|
108
|
+
const source = detail.source === 'codex' ? 'codex' : 'broker';
|
|
109
|
+
const id = source === 'broker' ? string(detail.jobId || detail.id) : string(detail.threadId);
|
|
110
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,159}$/.test(id)) return true;
|
|
111
|
+
const sanitize = options.sanitize || string, key = source + ':' + id;
|
|
112
|
+
const agents = run.subagents || (run.subagents = []);
|
|
113
|
+
let agent = agents.find(item => item.key === key);
|
|
114
|
+
if (!agent) {
|
|
115
|
+
if (agents.length >= MAX_AGENTS) return true;
|
|
116
|
+
agent = { v: 1, source, key, jobId: source === 'broker' ? id : '', threadId: source === 'codex' ? id : '',
|
|
117
|
+
title: id, task: '', status: 'pending', events: [], nativeEventSeq: 0, lastSequence: 0 };
|
|
118
|
+
agents.push(agent);
|
|
119
|
+
}
|
|
120
|
+
const seq = Number(options.nativeEventSeq) || 0;
|
|
121
|
+
if (seq > 0 && seq <= (agent.nativeEventSeq || 0)) return true;
|
|
122
|
+
const sequence = Number(detail.sequence) || 0;
|
|
123
|
+
if (sequence > 0 && sequence <= (agent.lastSequence || 0)) return true;
|
|
124
|
+
agent.nativeEventSeq = Math.max(agent.nativeEventSeq || 0, seq);
|
|
125
|
+
agent.lastSequence = Math.max(agent.lastSequence || 0, sequence);
|
|
126
|
+
const timestamp = string(raw.timestamp) || new Date().toISOString(), at = Date.parse(string(raw.timestamp));
|
|
127
|
+
const wasTerminal = TERMINAL.has(agent.status), previousEnd = terminalTime(agent, run);
|
|
128
|
+
if (Number.isFinite(at) && at < Date.parse(agent.startedAt || '')) return true;
|
|
129
|
+
agent.updatedAt = timestamp;
|
|
130
|
+
for (const field of ['title', 'task', 'threadId', 'parentThreadId', 'model', 'reasoningEffort']) {
|
|
131
|
+
const value = detail[field] || (field === 'title' ? raw.title : '');
|
|
132
|
+
if (typeof value === 'string' && value) agent[field] = clean(value, sanitize, field === 'task' ? 4096 : 160);
|
|
133
|
+
}
|
|
134
|
+
agent.clipped ||= detail.historyClipped === true;
|
|
135
|
+
agent.historyUnavailable ||= detail.historyUnavailable === true;
|
|
136
|
+
let next = type.endsWith('.queued') ? 'pending' : type.endsWith('.started') ? 'running'
|
|
137
|
+
: type.endsWith('.completed') ? 'completed' : type.endsWith('.rejected') ? 'failed'
|
|
138
|
+
: type.endsWith('.failed') ? (detail.status === 'cancelled' ? 'cancelled' : 'failed') : detail.status;
|
|
139
|
+
const inner = type === 'codex.subagent.event' ? detail.event : null;
|
|
140
|
+
const method = inner?.detail?.method, params = inner?.detail?.params || {};
|
|
141
|
+
if (method === 'turn/started') next = 'running';
|
|
142
|
+
if (method === 'turn/completed' && source === 'codex') next = params.turn?.status === 'interrupted' ? 'cancelled' : params.turn?.status;
|
|
143
|
+
const reopening = wasTerminal && method === 'turn/started';
|
|
144
|
+
if (STATES.has(next) && (!wasTerminal || TERMINAL.has(next) || reopening)) agent.status = next;
|
|
145
|
+
if (reopening) { agent.startedAt = timestamp; agent.finishedAt = ''; }
|
|
146
|
+
if (agent.status === 'running' && !agent.startedAt) agent.startedAt = timestamp;
|
|
147
|
+
if (TERMINAL.has(agent.status) || run.status !== 'running') {
|
|
148
|
+
// Late snapshots describe the same stopped interval; only a new turn resets it.
|
|
149
|
+
const end = wasTerminal || run.status !== 'running' || !Number.isFinite(at) ? previousEnd : at;
|
|
150
|
+
if (Number.isFinite(end)) agent.finishedAt = new Date(end).toISOString();
|
|
151
|
+
}
|
|
152
|
+
if (inner) {
|
|
153
|
+
const boundThread = inner.detail?.threadId || params.threadId || params.thread?.id;
|
|
154
|
+
if (boundThread) agent.threadId = clean(boundThread, sanitize, 160);
|
|
155
|
+
if (params.thread?.model) agent.model = clean(params.thread.model, sanitize, 160);
|
|
156
|
+
const mapped = Transcript.mapAgentEventToActivity(inner, { locale: options.locale });
|
|
157
|
+
const activity = Activity.capture({ ...mapped, technicalDetail: mapped?.technicalDetail || inner }, sanitize);
|
|
158
|
+
if (mapped?.visible && mapped.kind !== 'technical' && (!mapped.streamRole || mapped.streamRole === 'assistant')) {
|
|
159
|
+
const itemId = params.item?.id || params.itemId || inner.detail?.itemId;
|
|
160
|
+
const turnId = params.turnId || inner.detail?.turnId || '';
|
|
161
|
+
append(agent, { ...mapped, timestamp, activity,
|
|
162
|
+
streamKey: mapped.kind === 'stream' ? turnId + ':' + (itemId || mapped.streamKey || 'assistant') : '' }, sanitize);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (TERMINAL.has(agent.status)) {
|
|
166
|
+
for (const event of agent.events) if (event.kind === 'stream' && event.status === 'running') event.status = 'completed';
|
|
167
|
+
addAnswer(agent, detail.summary, timestamp, sanitize);
|
|
168
|
+
if (detail.reason) append(agent, { title: clean(detail.reason, sanitize, 1200), status: 'warning', timestamp,
|
|
169
|
+
activity: { kind: 'notice', id: key + ':failure', state: agent.status === 'failed' ? 'failed' : 'warning' } }, sanitize);
|
|
170
|
+
}
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
return { normalize, ingest, effectiveStatus, elapsedMs };
|
|
174
|
+
});
|
|
@@ -130,6 +130,91 @@
|
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
// File creation has its own inverse even when text edits use Reviewing.
|
|
134
|
+
// Store post-images, never infer an empty pre-image for a missing file.
|
|
135
|
+
function buildCreatedFileUndoCheckpoint(project, appliedOperations, previous = {}) {
|
|
136
|
+
const originalPaths = new Set((project?.files || []).map(file => file?.path));
|
|
137
|
+
const priorFiles = filesListToMap(previous.undoBaseFiles);
|
|
138
|
+
const created = new Map();
|
|
139
|
+
for (const operation of previous.undoOperations || []) {
|
|
140
|
+
const proof = operation?.undoCreatedFile;
|
|
141
|
+
if (operation?.type !== 'delete' || proof?.v !== 1) continue;
|
|
142
|
+
if (proof.kind === 'text' && priorFiles.has(operation.path)) {
|
|
143
|
+
created.set(operation.path, { kind: 'text', content: priorFiles.get(operation.path) });
|
|
144
|
+
} else if (proof.kind === 'binary' && /^[a-f0-9]{64}$/i.test(proof.sha256 || '')) {
|
|
145
|
+
created.set(operation.path, { kind: 'binary', sha256: proof.sha256.toLowerCase() });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
for (const operation of appliedOperations || []) {
|
|
149
|
+
if (!operation?.path) continue;
|
|
150
|
+
const path = operation.path;
|
|
151
|
+
if (operation.type === 'create' || operation.type === 'binary-create') {
|
|
152
|
+
if (originalPaths.has(path) && !created.has(path)) continue;
|
|
153
|
+
if (operation.type === 'create' && typeof operation.content === 'string') {
|
|
154
|
+
created.set(path, { kind: 'text', content: typeof operation.verifiedContent === 'string'
|
|
155
|
+
? operation.verifiedContent : operation.content });
|
|
156
|
+
} else {
|
|
157
|
+
const hash = operation.sha256 || operation.assetRef?.sha256;
|
|
158
|
+
if (operation.previousExists !== true && /^[a-f0-9]{64}$/i.test(hash || '')) {
|
|
159
|
+
created.set(path, { kind: 'binary', sha256: hash.toLowerCase() });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
} else if (operation.type === 'edit' && created.get(path)?.kind === 'text') {
|
|
163
|
+
const files = new Map([[path, created.get(path).content]]);
|
|
164
|
+
applyOperationToFiles(files, operation);
|
|
165
|
+
created.set(path, { kind: 'text', content: files.get(path) });
|
|
166
|
+
} else if (['delete', 'rename', 'move', 'overwrite-binary'].includes(operation.type)) {
|
|
167
|
+
// Existing rename/overwrite recovery retains ownership of these cases.
|
|
168
|
+
created.delete(path);
|
|
169
|
+
if (operation.to) created.delete(operation.to);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const undoBaseFiles = [], undoOperations = [];
|
|
173
|
+
for (const [path, proof] of Array.from(created).reverse()) {
|
|
174
|
+
const undoCreatedFile = proof.kind === 'binary'
|
|
175
|
+
? { v: 1, kind: 'binary', sha256: proof.sha256 } : { v: 1, kind: 'text' };
|
|
176
|
+
undoOperations.push({ ...normalizeUndoOperation({ type: 'delete', path, reason: 'Undo create' }), undoCreatedFile });
|
|
177
|
+
if (proof.kind === 'text') undoBaseFiles.push({ path, content: proof.content });
|
|
178
|
+
}
|
|
179
|
+
return { undoOperations, undoBaseFiles };
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Consume only independently verified rollback receipts. Forward writes
|
|
183
|
+
// remain audit evidence; recovery arrays describe only unfinished work.
|
|
184
|
+
function advanceUndoCheckpoint(run = {}, result = {}, verifyText = () => false) {
|
|
185
|
+
const operations = Array.isArray(run?.undoOperations) ? run.undoOperations : [];
|
|
186
|
+
if (!operations.some(operation => operation?.undoCreatedFile?.v === 1)) return run;
|
|
187
|
+
const applied = Array.isArray(result.applied) ? result.applied : [];
|
|
188
|
+
const skipped = Array.isArray(result.skipped) ? result.skipped : [];
|
|
189
|
+
const failed = path => skipped.some(entry => {
|
|
190
|
+
const target = entry?.operation?.path || entry?.trackedChange?.path || entry?.result?.failure?.file;
|
|
191
|
+
return !target || target === path;
|
|
192
|
+
});
|
|
193
|
+
if (result.failure || result.error) return run;
|
|
194
|
+
const textPaths = new Set((run.undoExpectedFiles || [])
|
|
195
|
+
.filter(file => file?.path && typeof file.content === 'string' && !failed(file.path)
|
|
196
|
+
&& typeof verifyText === 'function' && verifyText(file) === true)
|
|
197
|
+
.map(file => file.path));
|
|
198
|
+
const deletedPaths = new Set(operations.filter(operation => operation?.type === 'delete'
|
|
199
|
+
&& operation.undoCreatedFile?.v === 1 && !failed(operation.path)
|
|
200
|
+
&& applied.some(entry => entry?.operation?.type === 'delete' && entry.operation.path === operation.path
|
|
201
|
+
&& JSON.stringify(entry.operation.undoCreatedFile) === JSON.stringify(operation.undoCreatedFile)
|
|
202
|
+
&& entry.result?.ok === true && entry.result.verified === true
|
|
203
|
+
&& entry.result.verification === 'overleaf-zip')).map(operation => operation.path));
|
|
204
|
+
if (!textPaths.size && !deletedPaths.size) return run;
|
|
205
|
+
const pending = operations.filter(operation => !(operation?.type === 'edit' && textPaths.has(operation.path))
|
|
206
|
+
&& !(operation?.type === 'delete' && operation.undoCreatedFile?.v === 1 && deletedPaths.has(operation.path)));
|
|
207
|
+
const needed = new Set(pending.flatMap(operation => [operation?.path, operation?.to]).filter(Boolean));
|
|
208
|
+
return { ...run,
|
|
209
|
+
undoOperations: pending,
|
|
210
|
+
undoBaseFiles: (run.undoBaseFiles || []).filter(file => needed.has(file?.path)
|
|
211
|
+
|| (!textPaths.has(file?.path) && !deletedPaths.has(file?.path))),
|
|
212
|
+
undoExpectedFiles: (run.undoExpectedFiles || []).filter(file => !textPaths.has(file?.path)),
|
|
213
|
+
undoTrackedChanges: (run.undoTrackedChanges || []).filter(ref => !textPaths.has(ref?.path)),
|
|
214
|
+
trackedChangeCaptures: (run.trackedChangeCaptures || []).filter(capture => !textPaths.has(capture?.path))
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
133
218
|
function buildSnapshotRestoreUndo(run = {}) {
|
|
134
219
|
const undoOperations = Array.isArray(run.undoOperations) ? run.undoOperations : [];
|
|
135
220
|
const originalByPath = buildOriginalFilesForSnapshotUndo(run, undoOperations);
|
|
@@ -370,6 +455,8 @@
|
|
|
370
455
|
|
|
371
456
|
return {
|
|
372
457
|
buildUndoCheckpoint,
|
|
458
|
+
buildCreatedFileUndoCheckpoint,
|
|
459
|
+
advanceUndoCheckpoint,
|
|
373
460
|
buildExpectedFilesAfterOperations,
|
|
374
461
|
buildUndoOperations,
|
|
375
462
|
buildSnapshotRestoreUndo
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
'idle',
|
|
14
14
|
'checking',
|
|
15
15
|
'update_available',
|
|
16
|
+
'manual_install_required',
|
|
16
17
|
'downloading',
|
|
17
18
|
'staged',
|
|
18
19
|
'waiting_for_idle',
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
idle: { value: 0, determinate: true, phase: 'idle' },
|
|
42
43
|
checking: { value: 0, determinate: false, phase: 'checking' },
|
|
43
44
|
update_available: { value: 0, determinate: true, phase: 'available' },
|
|
45
|
+
manual_install_required: { value: 0, determinate: true, phase: 'manual' },
|
|
44
46
|
downloading: { value: 35, determinate: false, phase: 'downloading' },
|
|
45
47
|
staged: { value: 65, determinate: true, phase: 'staged' },
|
|
46
48
|
waiting_for_idle: { value: 65, determinate: true, phase: 'waiting' },
|
|
@@ -66,6 +68,9 @@
|
|
|
66
68
|
blocker: blockers[0] || '',
|
|
67
69
|
blockers,
|
|
68
70
|
transactionId: safeId(value.transactionId),
|
|
71
|
+
operationId: safeId(value.operationId),
|
|
72
|
+
cancelRequested: value.cancelRequested === true,
|
|
73
|
+
recoveryPending: value.recoveryPending === true,
|
|
69
74
|
initiatedBy: ['automatic', 'manual'].includes(value.initiatedBy) ? value.initiatedBy : '',
|
|
70
75
|
lastCheckedAt: finiteNumber(value.lastCheckedAt),
|
|
71
76
|
stagedAt: finiteNumber(value.stagedAt),
|
|
@@ -74,10 +79,22 @@
|
|
|
74
79
|
heartbeatAt: finiteNumber(value.heartbeatAt),
|
|
75
80
|
postponeUntil: finiteNumber(value.postponeUntil),
|
|
76
81
|
code: safeToken(value.code),
|
|
77
|
-
message: String(value.message || '').replace(/\s+/g, ' ').trim().slice(0, 300)
|
|
82
|
+
message: String(value.message || '').replace(/\s+/g, ' ').trim().slice(0, 300),
|
|
83
|
+
manualReason: normalizeManualReason(value.manualReason)
|
|
78
84
|
};
|
|
79
85
|
}
|
|
80
86
|
|
|
87
|
+
// Signed per-locale reason a release needs a one-time reinstall.
|
|
88
|
+
function normalizeManualReason(value) {
|
|
89
|
+
if (!value || typeof value !== 'object') return {};
|
|
90
|
+
const out = {};
|
|
91
|
+
for (const locale of ['en', 'zh']) {
|
|
92
|
+
const text = String(value[locale] || '').replace(/\s+/g, ' ').trim().slice(0, 400);
|
|
93
|
+
if (text) out[locale] = text;
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
|
|
81
98
|
function normalizeConsentState(value = {}) {
|
|
82
99
|
return {
|
|
83
100
|
schemaVersion: 1,
|
|
@@ -106,6 +123,13 @@
|
|
|
106
123
|
consent.snoozedUntil > now;
|
|
107
124
|
const execution = EXECUTION_STATES.has(state.state);
|
|
108
125
|
const available = state.state === 'update_available' && newer;
|
|
126
|
+
// A newer release that only a reinstall can apply. It is shown even after
|
|
127
|
+
// an automatic check, because no Update now button can ever resolve it.
|
|
128
|
+
// Compare with the running version: after the reinstall the stored state
|
|
129
|
+
// still names the old one, and the notice must clear by itself.
|
|
130
|
+
const runningVersion = safeVersion(options.currentVersion) || state.currentVersion;
|
|
131
|
+
const manualInstall = state.state === 'manual_install_required'
|
|
132
|
+
&& compareStableVersions(state.latestVersion, runningVersion) > 0;
|
|
109
133
|
const progress = getProgressModel(state);
|
|
110
134
|
const quietFailure = state.state === 'failed' &&
|
|
111
135
|
state.initiatedBy !== 'manual' &&
|
|
@@ -124,16 +148,21 @@
|
|
|
124
148
|
},
|
|
125
149
|
progress,
|
|
126
150
|
available,
|
|
151
|
+
manualInstall,
|
|
127
152
|
snoozed,
|
|
128
153
|
execution,
|
|
129
|
-
showPanel:
|
|
130
|
-
|
|
131
|
-
|
|
154
|
+
showPanel: state.cancelRequested || state.recoveryPending
|
|
155
|
+
|| (state.state === 'checking' && state.initiatedBy === 'manual')
|
|
156
|
+
|| ((available || manualInstall) && !snoozed) || execution || state.state === 'rolled_back' || visibleFailure,
|
|
157
|
+
badge: getBadge(state, { available: available || manualInstall, snoozed }),
|
|
132
158
|
actions: {
|
|
133
|
-
check: ['idle', 'committed', 'rolled_back', 'failed'].includes(state.state),
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
159
|
+
check: !state.cancelRequested && !state.recoveryPending && ['idle', 'committed', 'rolled_back', 'failed', 'manual_install_required'].includes(state.state),
|
|
160
|
+
copyInstall: manualInstall,
|
|
161
|
+
install: available && !state.cancelRequested && !state.recoveryPending,
|
|
162
|
+
later: !state.recoveryPending && (available || manualInstall || ['staged', 'waiting_for_idle'].includes(state.state)),
|
|
163
|
+
cancel: !state.recoveryPending && (state.cancelRequested || ['checking', 'downloading', 'staged', 'waiting_for_idle'].includes(state.state)),
|
|
164
|
+
recover: state.recoveryPending,
|
|
165
|
+
retry: !state.cancelRequested && !state.recoveryPending && ['failed', 'rolled_back'].includes(state.state)
|
|
137
166
|
}
|
|
138
167
|
};
|
|
139
168
|
}
|