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
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Observation only: never resumes a thread, starts a turn or settles a run.
|
|
4
|
+
const CHILD_ID = /^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,159}$/;
|
|
5
|
+
const MAX_CHILDREN = 16;
|
|
6
|
+
const TERMINAL = new Set(['completed', 'failed', 'cancelled']);
|
|
7
|
+
const EVIDENCE = { history: 1, agent: 2, turn: 3 };
|
|
8
|
+
|
|
9
|
+
function publicText(value, limit = 4096) {
|
|
10
|
+
return String(value ?? '')
|
|
11
|
+
.replace(/\bsk-(?:ant-|proj-)?[A-Za-z0-9_-]{12,}/g, '[REDACTED_SECRET]')
|
|
12
|
+
.replace(/\bBearer\s+[A-Za-z0-9._~+/-]+=*/gi, 'Bearer [REDACTED_SECRET]')
|
|
13
|
+
.replace(/((?:api[_-]?key|access[_-]?token|secret|password|authorization)\s*[:=]\s*["']?)[^\s"',;]+/gi, '$1[REDACTED_SECRET]')
|
|
14
|
+
.slice(0, limit);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function fields(value, names, limit = 4096) {
|
|
18
|
+
const result = {};
|
|
19
|
+
for (const name of names) {
|
|
20
|
+
const item = value?.[name];
|
|
21
|
+
if (typeof item === 'string') result[name] = publicText(item, limit);
|
|
22
|
+
else if (typeof item === 'number' && Number.isFinite(item) || typeof item === 'boolean') result[name] = item;
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function compactEvent(event) {
|
|
28
|
+
if (!event || !['codex.session.event', 'codex.command.started', 'codex.command.completed',
|
|
29
|
+
'codex.agent.message', 'codex.agent.result', 'codex.turn.bound'].includes(event.type)) return null;
|
|
30
|
+
const source = event.detail || {};
|
|
31
|
+
const detail = fields(source, ['method', 'threadId', 'turnId', 'itemId', 'phase', 'code', 'exitCode', 'durationMs']);
|
|
32
|
+
Object.assign(detail, fields(source, ['command', 'output', 'text'], 12000));
|
|
33
|
+
if (Array.isArray(source.commandActions)) detail.commandActions = source.commandActions.slice(0, 12)
|
|
34
|
+
.map(action => fields(action, ['type', 'path', 'query', 'name'], 400));
|
|
35
|
+
if (source.params) {
|
|
36
|
+
const p = source.params;
|
|
37
|
+
// Private reasoning and raw server request payloads never enter this lane.
|
|
38
|
+
if (/reasoning|textDelta|outputDelta/.test(source.method || '') && source.method !== 'item/agentMessage/delta') return null;
|
|
39
|
+
const params = fields(p, ['threadId', 'turnId', 'itemId', 'phase', 'message', 'warning'], 1000);
|
|
40
|
+
if (typeof p.delta === 'string') params.delta = publicText(p.delta, 12000);
|
|
41
|
+
if (p.thread) params.thread = fields(p.thread, ['id', 'model'], 160);
|
|
42
|
+
if (p.turn) {
|
|
43
|
+
params.turn = fields(p.turn, ['id', 'status'], 160);
|
|
44
|
+
if (p.turn.error) params.turn.error = fields(p.turn.error, ['message'], 1200);
|
|
45
|
+
}
|
|
46
|
+
if (p.error) params.error = fields(p.error, ['message'], 1200);
|
|
47
|
+
if (Array.isArray(p.plan)) params.plan = p.plan.slice(0, 16).map(step => fields(step, ['step', 'status'], 600));
|
|
48
|
+
const changes = input => (Array.isArray(input) ? input : []).slice(0, 12).map(change => ({
|
|
49
|
+
...fields(change, ['path'], 320),
|
|
50
|
+
kind: publicText(typeof change?.kind === 'object' ? change.kind.type : change?.kind, 32),
|
|
51
|
+
diff: publicText(change?.diff, 1800)
|
|
52
|
+
}));
|
|
53
|
+
if (Array.isArray(p.changes)) params.changes = changes(p.changes);
|
|
54
|
+
if (p.item) {
|
|
55
|
+
const item = p.item;
|
|
56
|
+
if (item.type === 'reasoning') return null;
|
|
57
|
+
params.item = {
|
|
58
|
+
...fields(item, ['id', 'type', 'status', 'phase', 'tool', 'server', 'exitCode', 'durationMs', 'success'], 400),
|
|
59
|
+
...fields(item, ['command'], 1000),
|
|
60
|
+
...fields(item, ['text'], 24000),
|
|
61
|
+
...fields(item, ['aggregatedOutput'], 1600)
|
|
62
|
+
};
|
|
63
|
+
if (Array.isArray(item.commandActions)) params.item.commandActions = item.commandActions.slice(0, 12)
|
|
64
|
+
.map(action => fields(action, ['type', 'path', 'query', 'name'], 400));
|
|
65
|
+
if (Array.isArray(item.changes)) params.item.changes = changes(item.changes);
|
|
66
|
+
if (item.error) params.item.error = fields(item.error, ['message'], 1200);
|
|
67
|
+
}
|
|
68
|
+
detail.params = params;
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
type: event.type, title: publicText(event.title, 24000),
|
|
72
|
+
status: publicText(event.status, 32),
|
|
73
|
+
timestamp: publicText(event.timestamp || new Date().toISOString(), 64), detail
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Metadata has a narrower exposure policy than already-compacted tool events.
|
|
78
|
+
function metadataText(value, limit) {
|
|
79
|
+
if (typeof value !== 'string') return '';
|
|
80
|
+
return publicText(value, 16384)
|
|
81
|
+
.replace(/(["'\x60])(?:file:\/\/|~\/|\/(?!\/)|[a-zA-Z]:[\\/]|\\\\)[\s\S]*?\1/g, '$1[local path]$1')
|
|
82
|
+
.replace(/\bfile:\/\/[^\s<>"'\x60]+/gi, '[local path]')
|
|
83
|
+
.replace(/(^|[\s([{"'=,:])(?:[a-zA-Z]:[\\/]|\\\\)[^\s<>"'\x60)\]}]+/g, '$1[local path]')
|
|
84
|
+
.replace(/(^|[\s([{"'=,:])(?:~\/|\/(?!\/))[^\s<>"'\x60)\]}]*/g, '$1[local path]')
|
|
85
|
+
.slice(0, limit);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function agentTitle(id, item) {
|
|
89
|
+
// agentPath is a logical namespace only for this exact, single-name shape.
|
|
90
|
+
// Never turn an arbitrary filesystem path into a display name.
|
|
91
|
+
const match = typeof item.agentPath === 'string'
|
|
92
|
+
&& /^\/root\/([a-zA-Z0-9][a-zA-Z0-9_-]{0,79})$/.exec(item.agentPath);
|
|
93
|
+
if (match) {
|
|
94
|
+
const name = match[1].replace(/[_-]+/g, ' ').trim();
|
|
95
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
96
|
+
}
|
|
97
|
+
const role = metadataText(item.agentRole, 120).trim();
|
|
98
|
+
return role && !role.includes('[local path]') ? role : 'Agent ' + id.slice(0, 8);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function taskText(value) {
|
|
102
|
+
if (typeof value !== 'string') return '';
|
|
103
|
+
const text = value.trim();
|
|
104
|
+
if (!text || /^gAAAA[A-Za-z0-9_-]{20,}={0,2}$/.test(text)
|
|
105
|
+
|| /^<(?:environment_context|user_instructions|developer_instructions|system_instructions|permissions|collaboration_mode)\b/i.test(text)
|
|
106
|
+
|| /^Same Codex Overleaf session context:/.test(text)
|
|
107
|
+
|| /^Message Type:\s*NEW_TASK\b/.test(text)) return '';
|
|
108
|
+
return metadataText(text, 4096);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function taskFromItems(items) {
|
|
112
|
+
for (const item of items.slice(0, 100)) {
|
|
113
|
+
if (item?.type !== 'userMessage' || !Array.isArray(item.content)
|
|
114
|
+
|| item.content.some(part => part?.type === 'encrypted_content')) continue;
|
|
115
|
+
const text = item.content.filter(part => part?.type === 'text')
|
|
116
|
+
.map(part => taskText(part.text)).filter(Boolean).join('\n').slice(0, 4096);
|
|
117
|
+
if (text) return text;
|
|
118
|
+
}
|
|
119
|
+
return '';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function createNativeSubagentObserver({ emit, request, getRoot, ownsParent, isStopped }) {
|
|
123
|
+
const children = new Map();
|
|
124
|
+
let closed = false;
|
|
125
|
+
const active = () => !closed && !isStopped();
|
|
126
|
+
function publish(child, event, extra = {}) {
|
|
127
|
+
if (!active()) return;
|
|
128
|
+
emit({
|
|
129
|
+
type: event ? 'codex.subagent.event' : 'codex.subagent.observed',
|
|
130
|
+
title: child.title, timestamp: new Date().toISOString(), status: child.status,
|
|
131
|
+
detail: {
|
|
132
|
+
source: 'codex', threadId: child.id, parentThreadId: child.parentThreadId,
|
|
133
|
+
title: child.title, task: child.task, status: child.status,
|
|
134
|
+
sequence: ++child.sequence, ...extra,
|
|
135
|
+
...(event ? { event: compactEvent(event) } : {})
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
function status(value) {
|
|
140
|
+
return ({ pendingInit: 'pending', running: 'running', completed: 'completed',
|
|
141
|
+
errored: 'failed', interrupted: 'cancelled', notFound: 'unknown' })[value];
|
|
142
|
+
}
|
|
143
|
+
function setStatus(child, next, evidence) {
|
|
144
|
+
if (!next) return false;
|
|
145
|
+
if (TERMINAL.has(child.status)) {
|
|
146
|
+
if (!TERMINAL.has(next) || evidence < child.statusEvidence
|
|
147
|
+
|| next !== child.status && evidence === child.statusEvidence) return false;
|
|
148
|
+
}
|
|
149
|
+
const changed = child.status !== next;
|
|
150
|
+
child.status = next;
|
|
151
|
+
if (TERMINAL.has(next)) child.statusEvidence = evidence;
|
|
152
|
+
return changed;
|
|
153
|
+
}
|
|
154
|
+
function rememberTask(child, items) {
|
|
155
|
+
if (child.task) return false;
|
|
156
|
+
const text = taskFromItems(items);
|
|
157
|
+
if (!text) return false;
|
|
158
|
+
child.task = text;
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
function register(id, item) {
|
|
162
|
+
if (typeof id !== 'string' || !CHILD_ID.test(id) || id === getRoot().threadId) return null;
|
|
163
|
+
let child = children.get(id);
|
|
164
|
+
if (!child) {
|
|
165
|
+
if (children.size >= MAX_CHILDREN) return null;
|
|
166
|
+
child = { id, title: agentTitle(id, item),
|
|
167
|
+
task: taskText(item.prompt), parentThreadId: getRoot().threadId,
|
|
168
|
+
status: 'pending', statusEvidence: 0, turnId: '', generation: 0, retiredTurns: new Set(),
|
|
169
|
+
interruptionObserved: false, sequence: 0, items: new Map(), activities: new Set(), lastRead: -Infinity };
|
|
170
|
+
children.set(id, child);
|
|
171
|
+
} else {
|
|
172
|
+
if (child.title === 'Agent ' + id.slice(0, 8)) child.title = agentTitle(id, item);
|
|
173
|
+
if (!child.task) child.task = taskText(item.prompt);
|
|
174
|
+
}
|
|
175
|
+
return child;
|
|
176
|
+
}
|
|
177
|
+
function duplicateActivity(child, item) {
|
|
178
|
+
if (typeof item.id !== 'string' || !item.id) return false;
|
|
179
|
+
// The same lifecycle item can arrive as both item/started and item/completed.
|
|
180
|
+
// Its kind, not the outer notification method, identifies the child activity.
|
|
181
|
+
const key = JSON.stringify([item.id.slice(0, 160), item.kind]);
|
|
182
|
+
if (child.activities.has(key)) return true;
|
|
183
|
+
child.activities.add(key);
|
|
184
|
+
if (child.activities.size > 100) child.activities.delete(child.activities.values().next().value);
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
function snapshot(child, terminal = false) {
|
|
188
|
+
if (!active() || child.readDisabled) return;
|
|
189
|
+
if (child.reading) { child.readAgain ||= terminal; return; }
|
|
190
|
+
if (!terminal && Date.now() - child.lastRead < 2000) return;
|
|
191
|
+
child.reading = true; child.lastRead = Date.now();
|
|
192
|
+
const generation = child.generation, interruptionObserved = child.interruptionObserved;
|
|
193
|
+
// Read only on real lifecycle/activity notifications. Polling would keep
|
|
194
|
+
// the parent's idle watchdog alive and change execution semantics.
|
|
195
|
+
Promise.resolve().then(() => active()
|
|
196
|
+
? request('thread/read', { threadId: child.id, includeTurns: true }) : null)
|
|
197
|
+
.then(result => {
|
|
198
|
+
if (!active() || child.generation !== generation || result?.thread?.id !== child.id
|
|
199
|
+
|| result.thread.parentThreadId && result.thread.parentThreadId !== child.parentThreadId) return;
|
|
200
|
+
const turns = Array.isArray(result.thread.turns) ? result.thread.turns : [];
|
|
201
|
+
const turn = turns.at(-1);
|
|
202
|
+
// A fork can include its parent's context; do not replay that as work
|
|
203
|
+
// produced by this child.
|
|
204
|
+
if (!turn?.id || turn.id === getRoot().turnId
|
|
205
|
+
|| child.turnId && child.turnId !== turn.id) return;
|
|
206
|
+
child.historyTurnId = turn.id;
|
|
207
|
+
const items = Array.isArray(turn.items) ? turn.items : [];
|
|
208
|
+
// Recover real child input before compactEvent drops user content.
|
|
209
|
+
// A fork's parent context and encrypted delegation are not task text.
|
|
210
|
+
if (rememberTask(child, items)) publish(child, null);
|
|
211
|
+
for (const item of items.slice(-100)) {
|
|
212
|
+
const event = compactEvent({
|
|
213
|
+
type: 'codex.session.event', status: item.status === 'inProgress' ? 'running' : 'completed',
|
|
214
|
+
detail: {
|
|
215
|
+
method: item.status === 'inProgress' ? 'item/started' : 'item/completed',
|
|
216
|
+
params: { threadId: child.id, turnId: turn.id, item }
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
if (!event) continue;
|
|
220
|
+
const signature = JSON.stringify(event.detail);
|
|
221
|
+
const key = turn.id + ':' + item.id;
|
|
222
|
+
if (child.items.get(key) === signature) continue;
|
|
223
|
+
child.items.set(key, signature);
|
|
224
|
+
if (child.items.size > 100) child.items.delete(child.items.keys().next().value);
|
|
225
|
+
publish(child, event, { historyClipped: items.length > 100 });
|
|
226
|
+
}
|
|
227
|
+
if (['completed', 'failed', 'interrupted'].includes(turn.status)) {
|
|
228
|
+
// A persisted, still-active turn can look interrupted. Require an
|
|
229
|
+
// explicit interruption observation before trusting that snapshot.
|
|
230
|
+
const next = turn.status === 'interrupted'
|
|
231
|
+
? (interruptionObserved ? 'cancelled' : undefined) : turn.status;
|
|
232
|
+
if (setStatus(child, next, EVIDENCE.history)) publish(child, null);
|
|
233
|
+
}
|
|
234
|
+
}).catch(() => {
|
|
235
|
+
if (!active() || child.generation !== generation) return;
|
|
236
|
+
// Older app servers may lack this capability. Keep observed records;
|
|
237
|
+
// reading history must never interrupt or resume the parent or child.
|
|
238
|
+
child.readDisabled = true;
|
|
239
|
+
publish(child, null, { historyUnavailable: true });
|
|
240
|
+
}).finally(() => {
|
|
241
|
+
child.reading = false;
|
|
242
|
+
if (child.readAgain) { child.readAgain = false; snapshot(child, true); }
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
function observe(message) {
|
|
246
|
+
if (!active()) return false;
|
|
247
|
+
const p = message.params || {};
|
|
248
|
+
const threadId = p.threadId || p.thread?.id;
|
|
249
|
+
const known = children.get(threadId);
|
|
250
|
+
if (known) {
|
|
251
|
+
const turnId = p.turnId || p.turn?.id || '';
|
|
252
|
+
if (message.method === 'turn/started') {
|
|
253
|
+
if (!turnId || known.retiredTurns.has(turnId)
|
|
254
|
+
|| (known.turnId === turnId || !known.turnId && known.historyTurnId === turnId)
|
|
255
|
+
&& TERMINAL.has(known.status)) return true;
|
|
256
|
+
if (known.turnId !== turnId) {
|
|
257
|
+
if (known.turnId) known.retiredTurns.add(known.turnId);
|
|
258
|
+
if (known.retiredTurns.size > 100) known.retiredTurns.delete(known.retiredTurns.values().next().value);
|
|
259
|
+
known.turnId = turnId;
|
|
260
|
+
known.generation += 1;
|
|
261
|
+
known.statusEvidence = 0;
|
|
262
|
+
known.interruptionObserved = false;
|
|
263
|
+
}
|
|
264
|
+
known.status = 'running';
|
|
265
|
+
} else if (turnId && known.turnId && turnId !== known.turnId) {
|
|
266
|
+
return true;
|
|
267
|
+
} else if (turnId) {
|
|
268
|
+
known.turnId = turnId;
|
|
269
|
+
}
|
|
270
|
+
if (message.method === 'turn/completed') {
|
|
271
|
+
const next = p.turn?.status === 'interrupted' ? 'cancelled'
|
|
272
|
+
: ['completed', 'failed'].includes(p.turn?.status) ? p.turn.status : undefined;
|
|
273
|
+
const changed = setStatus(known, next, EVIDENCE.turn);
|
|
274
|
+
// Do not forward rejected terminal evidence: the frontend also reads
|
|
275
|
+
// params.turn.status and must not reapply a weaker/conflicting outcome.
|
|
276
|
+
if (next && !changed && next !== known.status) return true;
|
|
277
|
+
}
|
|
278
|
+
if (turnId && turnId !== getRoot().turnId && rememberTask(known, [p.item])) publish(known, null);
|
|
279
|
+
const event = compactEvent({ type: 'codex.session.event', title: message.method,
|
|
280
|
+
detail: { method: message.method, params: p }, status: /completed/.test(message.method) ? 'completed' : 'running' });
|
|
281
|
+
if (event) publish(known, event);
|
|
282
|
+
return true; // Child errors/completions cannot settle the parent.
|
|
283
|
+
}
|
|
284
|
+
if (!ownsParent(p)) return false;
|
|
285
|
+
const item = p.item || {};
|
|
286
|
+
if (item.type === 'subAgentActivity') {
|
|
287
|
+
if (!['started', 'interacted', 'interrupted', 'completed'].includes(item.kind)) return false;
|
|
288
|
+
const child = register(item.agentThreadId, item);
|
|
289
|
+
if (!child || duplicateActivity(child, item)) return false;
|
|
290
|
+
if (item.kind === 'started' && ['pending', 'unknown'].includes(child.status)) child.status = 'running';
|
|
291
|
+
if (item.kind === 'interrupted') child.interruptionObserved = true;
|
|
292
|
+
publish(child, null);
|
|
293
|
+
// A lifecycle completion wakes the final read; it does not establish
|
|
294
|
+
// success. Only the child's own turn/status evidence can do that.
|
|
295
|
+
snapshot(child, item.kind === 'completed' || item.kind === 'interrupted');
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
if (item.type !== 'collabAgentToolCall') return false;
|
|
299
|
+
const states = item.agentsStates && typeof item.agentsStates === 'object' ? item.agentsStates : {};
|
|
300
|
+
const ids = [...new Set([...(Array.isArray(item.receiverThreadIds) ? item.receiverThreadIds : []), ...Object.keys(states)])];
|
|
301
|
+
for (const id of ids.slice(0, MAX_CHILDREN)) {
|
|
302
|
+
const child = register(id, item);
|
|
303
|
+
if (!child) continue;
|
|
304
|
+
const next = status(states[id]?.status);
|
|
305
|
+
setStatus(child, next, EVIDENCE.agent);
|
|
306
|
+
const terminal = ['completed', 'failed', 'cancelled'].includes(child.status);
|
|
307
|
+
publish(child, null, { summary: next === child.status && TERMINAL.has(next)
|
|
308
|
+
? publicText(states[id]?.message, 24000) : '' });
|
|
309
|
+
snapshot(child, terminal);
|
|
310
|
+
}
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
return { observe, close() { closed = true; children.clear(); } };
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
module.exports = { publicText, compactEvent, createNativeSubagentObserver };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const crypto = require('node:crypto');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
const { SUBAGENT_QUEUE_DIR } = require('./mirrorWorkspace');
|
|
7
|
+
const { safeWorkspaceRelativePath } = require('./subagentWorkspacePath');
|
|
8
|
+
const { formatOverleafWorkspaceRules } = require('./overleafWorkspaceRules');
|
|
9
|
+
|
|
10
|
+
// Filesystem evidence and worker context are separate from scheduling policy.
|
|
11
|
+
function createSubagentWorkspace({ workspacePath, logsDir }) {
|
|
12
|
+
function atomicWrite(target, text) {
|
|
13
|
+
const tmp = path.join(path.dirname(target), `.tmp-${crypto.randomUUID()}`);
|
|
14
|
+
fs.writeFileSync(tmp, text);
|
|
15
|
+
fs.renameSync(tmp, target);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function appendLog(jobId, text) {
|
|
19
|
+
try {
|
|
20
|
+
fs.appendFileSync(path.join(logsDir, `${jobId}.log`), `${new Date().toISOString()} ${text}\n`);
|
|
21
|
+
} catch (_error) { /* logs are best-effort */ }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function adoptionHash(file) {
|
|
25
|
+
try {
|
|
26
|
+
const safe = safeWorkspaceRelativePath(file);
|
|
27
|
+
if (!safe) return '';
|
|
28
|
+
const absolute = path.join(workspacePath, safe);
|
|
29
|
+
const stat = fs.lstatSync(absolute);
|
|
30
|
+
const relative = path.relative(fs.realpathSync(workspacePath), fs.realpathSync(absolute));
|
|
31
|
+
if (!stat.isFile() || stat.size > 32 * 1024 * 1024 || path.isAbsolute(relative)
|
|
32
|
+
|| relative === '..' || relative.startsWith('..' + path.sep)) return '';
|
|
33
|
+
return crypto.createHash('sha256').update(fs.readFileSync(absolute)).digest('hex');
|
|
34
|
+
} catch (_error) { return ''; }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function hashWorkspace() {
|
|
38
|
+
const hashes = new Map();
|
|
39
|
+
walk(workspacePath, '');
|
|
40
|
+
return hashes;
|
|
41
|
+
|
|
42
|
+
function walk(dir, prefix) {
|
|
43
|
+
let entries;
|
|
44
|
+
try {
|
|
45
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
46
|
+
} catch (_error) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
// The whole queue zone (incl. the work/ slice scratch) stays out of
|
|
51
|
+
// wave hashing: scratch can never reach Overleaf, same-wave slices
|
|
52
|
+
// are all in the owned union anyway, and a lead staggering slice
|
|
53
|
+
// creation mid-wave must not read as a violation (v1.6.1).
|
|
54
|
+
if (entry.name === '.DS_Store' || entry.name === SUBAGENT_QUEUE_DIR || entry.name === '.codex-overleaf-attachments') {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
58
|
+
const absolute = path.join(dir, entry.name);
|
|
59
|
+
if (entry.isDirectory()) {
|
|
60
|
+
walk(absolute, relative);
|
|
61
|
+
} else if (entry.isFile()) {
|
|
62
|
+
hashes.set(relative, hashFile(absolute));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function hashPaths(files) {
|
|
69
|
+
const hashes = new Map();
|
|
70
|
+
for (const file of files) {
|
|
71
|
+
hashes.set(file, hashFile(path.join(workspacePath, file)));
|
|
72
|
+
}
|
|
73
|
+
return hashes;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function hashFile(absolute) {
|
|
77
|
+
try {
|
|
78
|
+
return crypto.createHash('sha1').update(fs.readFileSync(absolute)).digest('hex');
|
|
79
|
+
} catch (_error) {
|
|
80
|
+
return 'missing';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function buildWorkerPrompt(job) {
|
|
85
|
+
const readOnly = job.readOnlyContext.length
|
|
86
|
+
? `- You may read these for context but must not modify them: ${job.readOnlyContext.join(', ')}.\n`
|
|
87
|
+
: '';
|
|
88
|
+
return [
|
|
89
|
+
'You are a subagent working on one slice of a larger task.',
|
|
90
|
+
formatOverleafWorkspaceRules(),
|
|
91
|
+
'HARD CONSTRAINTS:',
|
|
92
|
+
`- You may modify ONLY these files: ${job.files.join(', ')}.`,
|
|
93
|
+
readOnly + '- Do not modify, create, or delete any other file. Inside .codex-overleaf-subagents/ you may touch ONLY the slice files listed above (if any).',
|
|
94
|
+
'- Work fully autonomously; nobody can answer questions.',
|
|
95
|
+
'',
|
|
96
|
+
job.task
|
|
97
|
+
].join('\n');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
return { atomicWrite, appendLog, adoptionHash, hashWorkspace, hashPaths, hashFile, buildWorkerPrompt };
|
|
102
|
+
}
|
|
103
|
+
module.exports = { createSubagentWorkspace };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { SUBAGENT_QUEUE_DIR } = require('./mirrorWorkspace');
|
|
5
|
+
|
|
6
|
+
function safeWorkspaceRelativePath(value) {
|
|
7
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const normalized = value.trim().replace(/\\/g, '/').replace(/^\.\//, '');
|
|
11
|
+
if (!normalized || path.isAbsolute(normalized)) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const segments = normalized.split('/');
|
|
15
|
+
if (segments.some(segment => segment === '..' || segment === '')) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
if (segments[0] === SUBAGENT_QUEUE_DIR) {
|
|
19
|
+
// The queue control plane (jobs/results/logs/broker.json) is never
|
|
20
|
+
// ownable — but the work/ scratch zone IS: single-file fan-out slices
|
|
21
|
+
// live there (v1.6.1 scatter-gather), excluded from writeback by the
|
|
22
|
+
// mirror-scan rule yet fully owned/hashed like any other job file.
|
|
23
|
+
if (segments[1] === 'work' && segments.length >= 3) {
|
|
24
|
+
return segments.join('/');
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return segments.join('/');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = { safeWorkspaceRelativePath };
|
|
@@ -10,6 +10,7 @@ const {
|
|
|
10
10
|
SUPPORTED_NATIVE_PROTOCOL
|
|
11
11
|
} = require('../../extension/src/shared/compatibility');
|
|
12
12
|
const { runCodexSession } = require('./codexSessionRunner');
|
|
13
|
+
const WritingStyleRuntime = require('./writingStyleRuntime');
|
|
13
14
|
const { resolveCodexModels } = require('./codexModels');
|
|
14
15
|
const {
|
|
15
16
|
handleProviderRequest,
|
|
@@ -23,7 +24,8 @@ const { forkCodexThread } = require('./codexThreadFork');
|
|
|
23
24
|
const { readAssetChunk, releaseAsset } = require('./nativeAssetTransfer');
|
|
24
25
|
const { logDebug, truncateText } = require('./debugLog');
|
|
25
26
|
const { HOST_NAME } = require('./manifest');
|
|
26
|
-
const { getNativeRuntimePlatform, summarizeNativeEnvironment } = require('./nativeEnvironment');
|
|
27
|
+
const { getNativeRuntimePlatform, summarizeNativeEnvironment, refreshCodexRuntimeEnv } = require('./nativeEnvironment');
|
|
28
|
+
const { formatModelUpgradeError } = require('./codexModelRecovery');
|
|
27
29
|
const {
|
|
28
30
|
NATIVE_REQUEST_QUOTAS,
|
|
29
31
|
firstQuotaViolation,
|
|
@@ -33,6 +35,7 @@ const {
|
|
|
33
35
|
} = require('./nativeTransportEnvelope');
|
|
34
36
|
const { version: PACKAGE_VERSION } = require('../../package.json');
|
|
35
37
|
|
|
38
|
+
const processStopBarrier = require('./processStopBarrier');
|
|
36
39
|
const activeProjectLocks = new Map();
|
|
37
40
|
const activeRunControllers = new Map();
|
|
38
41
|
const activeRunEntries = new Map();
|
|
@@ -41,7 +44,7 @@ const activeRunEntries = new Map();
|
|
|
41
44
|
// Overleaf tab was reloaded — the requestId lived in content-side JS state
|
|
42
45
|
// and is gone, but the native-host-side controller is still running).
|
|
43
46
|
const activeRunByProject = new Map();
|
|
44
|
-
const CODEX_RUN_PASSTHROUGH_ERROR_CODES = new Set(['thread_resume_failed', 'codex_no_usable_result']);
|
|
47
|
+
const CODEX_RUN_PASSTHROUGH_ERROR_CODES = new Set(['thread_resume_failed', 'codex_no_usable_result', 'codex_process_stop_unconfirmed', 'selected_context_unresolved']);
|
|
45
48
|
|
|
46
49
|
async function handleRequest(request, env = process.env, emit = () => {}) {
|
|
47
50
|
if (!request || typeof request !== 'object') {
|
|
@@ -53,6 +56,10 @@ async function handleRequest(request, env = process.env, emit = () => {}) {
|
|
|
53
56
|
return quotaErrorResponse(request.id, quotaError);
|
|
54
57
|
}
|
|
55
58
|
|
|
59
|
+
if (['bridge.ping', 'codex.run', 'codex.models', 'codex.thread.fork'].includes(request.method)) {
|
|
60
|
+
env = refreshCodexRuntimeEnv(env);
|
|
61
|
+
}
|
|
62
|
+
|
|
56
63
|
if (request.method === 'bridge.ping') {
|
|
57
64
|
return okResponse(request.id, {
|
|
58
65
|
host: HOST_NAME,
|
|
@@ -66,6 +73,12 @@ async function handleRequest(request, env = process.env, emit = () => {}) {
|
|
|
66
73
|
});
|
|
67
74
|
}
|
|
68
75
|
|
|
76
|
+
if (['codex.run', 'mirror.sync', 'mirror.patchFiles', 'mirror.confirmWriteback'].includes(request.method)
|
|
77
|
+
&& processStopBarrier.isBlocked(resolveProjectKey(request.params || {}), env.CODEX_OVERLEAF_MIRROR_ROOT)) {
|
|
78
|
+
return errorResponse(request.id, 'codex_process_stop_unconfirmed',
|
|
79
|
+
'The previous Codex process has not exited. This project remains isolated until exit is confirmed.');
|
|
80
|
+
}
|
|
81
|
+
|
|
69
82
|
if (request.method === 'mirror.sync') {
|
|
70
83
|
return handleMirrorSync(request, env);
|
|
71
84
|
}
|
|
@@ -115,7 +128,7 @@ async function handleRequest(request, env = process.env, emit = () => {}) {
|
|
|
115
128
|
}
|
|
116
129
|
|
|
117
130
|
if (request.method === 'codex.cancel') {
|
|
118
|
-
return handleCodexCancel(request);
|
|
131
|
+
return handleCodexCancel(request, env);
|
|
119
132
|
}
|
|
120
133
|
|
|
121
134
|
if (request.method === 'codex.history.clearPlugin') {
|
|
@@ -142,6 +155,18 @@ async function handleRequest(request, env = process.env, emit = () => {}) {
|
|
|
142
155
|
return okResponse(request.id, releaseAsset(request.params || {}));
|
|
143
156
|
}
|
|
144
157
|
|
|
158
|
+
if (request.method === 'writing-style.get' || request.method === 'writing-style.set') {
|
|
159
|
+
try {
|
|
160
|
+
const params = request.params || {};
|
|
161
|
+
const result = request.method === 'writing-style.get'
|
|
162
|
+
? await WritingStyleRuntime.get(params, env, id => activeRunEntries.has(id))
|
|
163
|
+
: await WritingStyleRuntime.set(params, env);
|
|
164
|
+
return okResponse(request.id, result);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
return errorResponse(request.id, error.code || 'writing_style_failed', error.message);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
145
170
|
if (request.method === 'skills.list') {
|
|
146
171
|
return handleSkillsList(request, env);
|
|
147
172
|
}
|
|
@@ -180,6 +205,19 @@ function quotaErrorResponse(id, violation) {
|
|
|
180
205
|
|
|
181
206
|
async function handleCodexRun(request, env, emit) {
|
|
182
207
|
let params = request.params || {};
|
|
208
|
+
if (params.writingStyleBuild != null) {
|
|
209
|
+
if (typeof params.writingStyleBuild !== 'object' || Array.isArray(params.writingStyleBuild)) {
|
|
210
|
+
return errorResponse(request.id, 'writing_style_invalid_build', 'Writing style build settings must be an object.');
|
|
211
|
+
}
|
|
212
|
+
params = {
|
|
213
|
+
...params,
|
|
214
|
+
mode: 'ask',
|
|
215
|
+
useExistingMirror: false,
|
|
216
|
+
fileOverlays: [],
|
|
217
|
+
writingStyle: null,
|
|
218
|
+
writingStyleBuild: { ...params.writingStyleBuild, requestId: String(request.id || '') }
|
|
219
|
+
};
|
|
220
|
+
}
|
|
183
221
|
if (isCodexMissing(env)) {
|
|
184
222
|
return errorResponse(
|
|
185
223
|
request.id,
|
|
@@ -253,7 +291,7 @@ async function handleCodexRun(request, env, emit) {
|
|
|
253
291
|
if (Array.isArray(params.fileOverlays) && params.fileOverlays.length) {
|
|
254
292
|
await applyFileOverlays({ projectId: projectKey, overlays: params.fileOverlays, rootDir });
|
|
255
293
|
}
|
|
256
|
-
} else if (!isSnapshotlessSkillInstallerRun(params) && !hasRunnableProjectSnapshotEvidence(params)) {
|
|
294
|
+
} else if (!params.writingStyleBuild && !isSnapshotlessSkillInstallerRun(params) && !hasRunnableProjectSnapshotEvidence(params)) {
|
|
257
295
|
return errorResponse(
|
|
258
296
|
request.id,
|
|
259
297
|
'codex_run_requires_snapshot_evidence',
|
|
@@ -267,6 +305,7 @@ async function handleCodexRun(request, env, emit) {
|
|
|
267
305
|
emit,
|
|
268
306
|
rootDir: env.CODEX_OVERLEAF_MIRROR_ROOT,
|
|
269
307
|
providerLaunch: providerResolution.providerLaunch,
|
|
308
|
+
onStopUnconfirmed: error => processStopBarrier.record(projectKey, env.CODEX_OVERLEAF_MIRROR_ROOT, error),
|
|
270
309
|
onControlReady: control => {
|
|
271
310
|
activeEntry.control = control;
|
|
272
311
|
},
|
|
@@ -285,6 +324,13 @@ async function handleCodexRun(request, env, emit) {
|
|
|
285
324
|
});
|
|
286
325
|
return errorResponse(request.id, 'codex_cancelled', 'Codex run was cancelled by the user');
|
|
287
326
|
}
|
|
327
|
+
const modelUpgradeError = formatModelUpgradeError(error, env, {
|
|
328
|
+
model: params.model, locale: params.locale
|
|
329
|
+
});
|
|
330
|
+
if (modelUpgradeError) {
|
|
331
|
+
logDebug('codex.run.model_version_rejected', modelUpgradeError.details);
|
|
332
|
+
return errorResponse(request.id, modelUpgradeError.code, modelUpgradeError.message, modelUpgradeError.details);
|
|
333
|
+
}
|
|
288
334
|
if (shouldPassthroughCodexRunError(error)) {
|
|
289
335
|
logDebug('codex.run.passthrough_failed', {
|
|
290
336
|
code: error.code,
|
|
@@ -372,7 +418,7 @@ function findActiveRunEntry(params = {}) {
|
|
|
372
418
|
// the user otherwise has no way to recover short of restarting Chrome.
|
|
373
419
|
// Only fires when `force: true` is explicitly set so accidental calls
|
|
374
420
|
// can't punch through a real live run.
|
|
375
|
-
function handleCodexCancel(request) {
|
|
421
|
+
function handleCodexCancel(request, env = process.env) {
|
|
376
422
|
const params = request.params || {};
|
|
377
423
|
const targetId = params.requestId || params.id;
|
|
378
424
|
const projectKey = typeof params.projectKey === 'string' ? params.projectKey : '';
|
|
@@ -396,6 +442,10 @@ function handleCodexCancel(request) {
|
|
|
396
442
|
requestId: entry.id || ''
|
|
397
443
|
});
|
|
398
444
|
}
|
|
445
|
+
if (processStopBarrier.isBlocked(projectKey, env.CODEX_OVERLEAF_MIRROR_ROOT)) {
|
|
446
|
+
return errorResponse(request.id, 'codex_process_stop_unconfirmed',
|
|
447
|
+
'Cancellation was requested, but process exit is not yet confirmed.');
|
|
448
|
+
}
|
|
399
449
|
if (force && activeProjectLocks.has(projectKey)) {
|
|
400
450
|
activeProjectLocks.delete(projectKey);
|
|
401
451
|
activeRunByProject.delete(projectKey);
|