codex-overleaf-link 2.4.1 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +275 -305
- package/README.zh-CN.md +290 -320
- package/extension/bootstrap/background.js +99 -19
- package/extension/bootstrap/manifest.template.json +9 -4
- package/extension/bootstrap/popup.html +11 -16
- package/extension/bootstrap/popupFallback.js +55 -0
- package/extension/bootstrap/update.js +25 -2
- package/extension/bootstrap/updateStatus.js +1 -0
- package/extension/runtime-manifest.json +3 -1
- package/extension/src/background.js +234 -56
- package/extension/src/backgroundBootstrapMigration.js +181 -0
- package/extension/src/backgroundSharedSessions.js +440 -0
- package/extension/src/backgroundUpdateCoordinator.js +541 -381
- package/extension/src/backgroundUpdateSafety.js +173 -0
- package/extension/src/content/activeTurnControl.js +16 -2
- package/extension/src/content/applyResultFormatters.js +46 -73
- package/extension/src/content/assetTransferBroker.js +244 -12
- package/extension/src/content/changeHistoryView.js +175 -0
- package/extension/src/content/composerAttachments.js +117 -67
- package/extension/src/content/composerPanel.js +41 -8
- package/extension/src/content/contentRuntime.js +1084 -1099
- package/extension/src/content/diagnosticsController.js +122 -97
- package/extension/src/content/diagnosticsExport.js +236 -0
- package/extension/src/content/diagnosticsPanel.js +78 -19
- package/extension/src/content/diffReviewPanel.js +8 -5
- package/extension/src/content/directoryCleanupRecovery.js +54 -0
- package/extension/src/content/generated/content.bundle.js +14680 -3606
- package/extension/src/content/generated/content.bundle.meta.json +30 -3
- package/extension/src/content/globalPreferencesController.js +1 -1
- package/extension/src/content/legacyGlobalRegistry.js +25 -1
- package/extension/src/content/localSkillsPanel.js +141 -16
- package/extension/src/content/markdownDomRenderer.js +9 -4
- package/extension/src/content/markdownText.js +5 -6
- package/extension/src/content/modelPicker.js +8 -5
- package/extension/src/content/nativeCompatibilityController.js +45 -20
- package/extension/src/content/otWarmMirror.js +4 -5
- package/extension/src/content/otWarmMirrorController.js +17 -20
- package/extension/src/content/pageBridgeClient.js +33 -5
- package/extension/src/content/panelMaintenance.js +87 -132
- package/extension/src/content/panelRenderer.js +10 -0
- package/extension/src/content/pendingInputView.js +109 -76
- package/extension/src/content/projectProviderSelection.js +13 -4
- package/extension/src/content/projectSessionCleanup.js +109 -62
- package/extension/src/content/projectSettingsCoordinator.js +39 -2
- package/extension/src/content/providerSettingsCoordinator.js +63 -14
- package/extension/src/content/providerSettingsDialog.js +724 -113
- package/extension/src/content/recentProjects.js +21 -6
- package/extension/src/content/runActivitySummary.js +665 -0
- package/extension/src/content/runCompletionMeta.js +344 -0
- package/extension/src/content/runController.js +40 -15
- package/extension/src/content/runFailureNotice.js +34 -12
- package/extension/src/content/runGuidanceController.js +76 -30
- package/extension/src/content/runGuidanceView.js +59 -10
- package/extension/src/content/runPresence.js +306 -0
- package/extension/src/content/runQueueScheduler.js +150 -43
- package/extension/src/content/runRecoveryActions.js +146 -0
- package/extension/src/content/runResultActions.js +11 -8
- package/extension/src/content/runReviewController.js +574 -0
- package/extension/src/content/runScrollLayout.js +21 -2
- package/extension/src/content/runTimelineView.js +315 -290
- package/extension/src/content/scopedPersistencePanelState.js +51 -6
- package/extension/src/content/selectionContextView.js +300 -0
- package/extension/src/content/sensitivePreflight.js +140 -0
- package/extension/src/content/sessionForkController.js +80 -17
- package/extension/src/content/sessionManager.js +1 -1
- package/extension/src/content/sessionPersistence.js +6 -1
- package/extension/src/content/settingsPanel.js +84 -55
- package/extension/src/content/settingsWorkbench.js +379 -0
- package/extension/src/content/sharedSessionViewSync.js +109 -0
- package/extension/src/content/subagentActivityView.js +195 -0
- package/extension/src/content/trackedChangeCaptureController.js +7 -3
- package/extension/src/content/updateIdle.js +4 -1
- package/extension/src/content/updateNotice.js +179 -56
- package/extension/src/content/updateSafetyReceiver.js +58 -0
- package/extension/src/content/writebackController.js +308 -2
- package/extension/src/content/writebackOrchestrator.js +213 -199
- package/extension/src/content/writebackPlan.js +231 -0
- package/extension/src/content/writebackRecovery.js +122 -0
- package/extension/src/content/writingStyleSettings.js +600 -0
- package/extension/src/content/writtenChangesView.js +152 -0
- package/extension/src/page/binaryAssetUploader.js +223 -23
- package/extension/src/page/fileMover.js +256 -0
- package/extension/src/page/overleafProjectSnapshot.js +1 -0
- package/extension/src/page/ownedDirectoryCleanup.js +94 -0
- package/extension/src/page/referenceProjects.js +149 -0
- package/extension/src/page/reviewContext.js +113 -0
- package/extension/src/page/saveState.js +20 -6
- package/extension/src/page/snapshotRouter.js +124 -48
- package/extension/src/page/textCoordinates.js +102 -0
- package/extension/src/page/textFileCreator.js +442 -71
- package/extension/src/page/trackedChangeCapture.js +53 -57
- package/extension/src/page/trackedChangeOwnership.js +216 -0
- package/extension/src/page/trackedChangeReplay.js +184 -0
- package/extension/src/page/trackedChangesLifecycle.js +343 -339
- package/extension/src/page/treeOperations.js +33 -12
- package/extension/src/page/updateSafetyProbe.js +41 -0
- package/extension/src/page/writebackReceiptJournal.js +114 -0
- package/extension/src/page/writebackRouter.js +242 -201
- package/extension/src/pageBridge.js +73 -102
- package/extension/src/popup.js +261 -65
- package/extension/src/shared/agentTranscript.js +41 -4
- package/extension/src/shared/auditRecords.js +73 -0
- package/extension/src/shared/changeHistoryModel.js +94 -0
- package/extension/src/shared/compatibility.js +22 -6
- package/extension/src/shared/compileAdapter.js +101 -37
- package/extension/src/shared/composerAttachmentDraft.js +151 -0
- package/extension/src/shared/directoryCleanupProof.js +43 -0
- package/extension/src/shared/failureReasons.js +329 -3
- package/extension/src/shared/globalPreferences.js +31 -14
- package/extension/src/shared/governanceRules.js +4 -37
- package/extension/src/shared/i18n.js +389 -25
- package/extension/src/shared/managedUpdateProjection.js +8 -5
- package/extension/src/shared/nativeRequestIdentity.js +1 -0
- package/extension/src/shared/pageRpcContract.js +9 -2
- package/extension/src/shared/projectFiles.js +21 -44
- package/extension/src/shared/providerProfiles.js +114 -3
- package/extension/src/shared/runActivityModel.js +361 -0
- package/extension/src/shared/runExecutionSnapshot.js +8 -2
- package/extension/src/shared/runExecutionSnapshotCodec.js +16 -4
- package/extension/src/shared/runInputQueue.js +48 -5
- package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
- package/extension/src/shared/selectionContext.js +37 -0
- package/extension/src/shared/sessionState.js +166 -30
- package/extension/src/shared/settlementFacts.js +10 -2
- package/extension/src/shared/sharedSessionBridge.js +311 -0
- package/extension/src/shared/sharedSessionTransfer.js +140 -0
- package/extension/src/shared/staleGuard.js +118 -13
- package/extension/src/shared/storageDb.js +77 -78
- package/extension/src/shared/storageMigration.js +74 -111
- package/extension/src/shared/storageRunActions.js +211 -22
- package/extension/src/shared/storageValuePruning.js +40 -0
- package/extension/src/shared/subagentActivityModel.js +174 -0
- package/extension/src/shared/undoOperations.js +216 -6
- package/extension/src/shared/updateConsent.js +42 -11
- package/extension/src/shared/updateRuntimeIdentity.js +1 -1
- package/extension/src/shared/writebackIntent.js +78 -0
- package/extension/src/shared/writebackOperationEvidence.js +4 -15
- package/extension/src/shared/writebackSettlement.js +67 -48
- package/extension/src/shared/writingStyle.js +33 -0
- package/extension/styles/panel.css +1987 -385
- package/extension/styles/popup.css +110 -0
- package/native-host/src/anthropicBridgeRequest.js +6 -3
- package/native-host/src/anthropicBridgeResponse.js +6 -2
- package/native-host/src/anthropicMessagesBridge.js +24 -16
- package/native-host/src/bootstrapMigration.js +296 -0
- package/native-host/src/bootstrapMigrationContract.js +101 -0
- package/native-host/src/bootstrapUpdate.js +233 -0
- package/native-host/src/bootstrapUpdateWatchdog.js +44 -0
- package/native-host/src/chatBridgeResponse.js +10 -0
- package/native-host/src/chatCompletionsBridge.js +21 -15
- package/native-host/src/codexConfigPaths.js +106 -0
- package/native-host/src/codexHome.js +66 -73
- package/native-host/src/codexHomeScope.js +124 -0
- package/native-host/src/codexInheritedAuth.js +90 -0
- package/native-host/src/codexLocalSkills.js +301 -0
- package/native-host/src/codexModelRecovery.js +107 -0
- package/native-host/src/codexPromptAssembly.js +33 -12
- package/native-host/src/codexProviderLaunch.js +3 -3
- package/native-host/src/codexProviderTest.js +24 -26
- package/native-host/src/codexRuntimeIdentity.js +1 -0
- package/native-host/src/codexSessionRunner.js +211 -318
- package/native-host/src/codexSessionTiming.js +21 -8
- package/native-host/src/codexSkillIsolation.js +170 -0
- package/native-host/src/codexThreadFork.js +19 -3
- package/native-host/src/index.js +19 -7
- package/native-host/src/managedInstall.js +115 -39
- package/native-host/src/managedInstallRecovery.js +140 -0
- package/native-host/src/managedRuntimeEvidence.js +57 -0
- package/native-host/src/mirrorWorkspace.js +92 -22
- package/native-host/src/nativeDoctor.js +15 -0
- package/native-host/src/nativeEnvironment.js +70 -0
- package/native-host/src/nativeHelperLifecycle.js +21 -0
- package/native-host/src/nativeHostRegistration.js +33 -0
- package/native-host/src/nativeQuotas.js +15 -8
- package/native-host/src/nativeRunLifecycle.js +71 -0
- package/native-host/src/overleafWorkspaceRules.js +16 -0
- package/native-host/src/processStopBarrier.js +115 -0
- package/native-host/src/projectPathPlatform.js +30 -0
- package/native-host/src/providerHttp.js +80 -0
- package/native-host/src/providerModelCatalog.js +4 -3
- package/native-host/src/providerProfile.js +17 -3
- package/native-host/src/providerReasoning.js +10 -11
- package/native-host/src/providerRuntime.js +1 -0
- package/native-host/src/providerStore.js +76 -14
- package/native-host/src/releaseTransport.js +14 -5
- package/native-host/src/responsesPassthroughBridge.js +266 -52
- package/native-host/src/runtimeInstaller.js +21 -1
- package/native-host/src/selectionScope.js +86 -0
- package/native-host/src/skills/parallel-subagents/SKILL.md +31 -3
- package/native-host/src/skills/writing-style-builder/SKILL.md +146 -0
- package/native-host/src/subagentAdmission.js +26 -0
- package/native-host/src/subagentBroker.js +176 -159
- package/native-host/src/subagentTelemetry.js +325 -0
- package/native-host/src/subagentWorkspace.js +103 -0
- package/native-host/src/subagentWorkspacePath.js +34 -0
- package/native-host/src/taskRunnerRuntime.js +130 -57
- package/native-host/src/tomlStatements.js +140 -0
- package/native-host/src/turnAttachments.js +113 -0
- package/native-host/src/updateManager.js +406 -38
- package/native-host/src/updateNetworkControl.js +75 -0
- package/native-host/src/updateTrust.js +21 -2
- package/native-host/src/vendor/pdfjs/LICENSE +177 -0
- package/native-host/src/vendor/pdfjs/SOURCE.txt +3 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
- package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
- package/native-host/src/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/LICENSE +36 -0
- package/native-host/src/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/V.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
- package/native-host/src/vendor/pdfjs/pdf.mjs +26740 -0
- package/native-host/src/vendor/pdfjs/pdf.worker.mjs +62201 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/native-host/src/writingStyleEvidence.js +102 -0
- package/native-host/src/writingStylePdfWorker.js +35 -0
- package/native-host/src/writingStyleProfile.js +165 -0
- package/native-host/src/writingStyleRuntime.js +475 -0
- package/native-host/src/writingStyleStore.js +73 -0
- package/package.json +1 -1
- package/scripts/install-managed.mjs +1 -0
|
@@ -0,0 +1,325 @@
|
|
|
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 MAX_HISTORY_READ_FAILURES = 3;
|
|
7
|
+
const TERMINAL = new Set(['completed', 'failed', 'cancelled']);
|
|
8
|
+
const EVIDENCE = { history: 1, agent: 2, turn: 3 };
|
|
9
|
+
|
|
10
|
+
function publicText(value, limit = 4096) {
|
|
11
|
+
// Preserve the delegated task and model/tool text. The event allowlist
|
|
12
|
+
// excludes credential fields; metadataText separately hides local paths.
|
|
13
|
+
return String(value ?? '').slice(0, limit);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function fields(value, names, limit = 4096) {
|
|
17
|
+
const result = {};
|
|
18
|
+
for (const name of names) {
|
|
19
|
+
const item = value?.[name];
|
|
20
|
+
if (typeof item === 'string') result[name] = publicText(item, limit);
|
|
21
|
+
else if (typeof item === 'number' && Number.isFinite(item) || typeof item === 'boolean') result[name] = item;
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function compactEvent(event) {
|
|
27
|
+
if (!event || !['codex.session.event', 'codex.command.started', 'codex.command.completed',
|
|
28
|
+
'codex.agent.message', 'codex.agent.result', 'codex.turn.bound'].includes(event.type)) return null;
|
|
29
|
+
const source = event.detail || {};
|
|
30
|
+
const detail = fields(source, ['method', 'threadId', 'turnId', 'itemId', 'phase', 'code', 'exitCode', 'durationMs']);
|
|
31
|
+
Object.assign(detail, fields(source, ['command', 'output', 'text'], 12000));
|
|
32
|
+
if (Array.isArray(source.commandActions)) detail.commandActions = source.commandActions.slice(0, 12)
|
|
33
|
+
.map(action => fields(action, ['type', 'path', 'query', 'name'], 400));
|
|
34
|
+
if (source.params) {
|
|
35
|
+
const p = source.params;
|
|
36
|
+
// Private reasoning and raw server request payloads never enter this lane.
|
|
37
|
+
if (/reasoning|textDelta|outputDelta/.test(source.method || '') && source.method !== 'item/agentMessage/delta') return null;
|
|
38
|
+
const params = fields(p, ['threadId', 'turnId', 'itemId', 'phase', 'message', 'warning'], 1000);
|
|
39
|
+
if (typeof p.delta === 'string') params.delta = publicText(p.delta, 12000);
|
|
40
|
+
if (p.thread) params.thread = fields(p.thread, ['id', 'model'], 160);
|
|
41
|
+
if (p.turn) {
|
|
42
|
+
params.turn = fields(p.turn, ['id', 'status'], 160);
|
|
43
|
+
if (p.turn.error) params.turn.error = fields(p.turn.error, ['message'], 1200);
|
|
44
|
+
}
|
|
45
|
+
if (p.error) params.error = fields(p.error, ['message'], 1200);
|
|
46
|
+
if (Array.isArray(p.plan)) params.plan = p.plan.slice(0, 16).map(step => fields(step, ['step', 'status'], 600));
|
|
47
|
+
const changes = input => (Array.isArray(input) ? input : []).slice(0, 12).map(change => ({
|
|
48
|
+
...fields(change, ['path'], 320),
|
|
49
|
+
kind: publicText(typeof change?.kind === 'object' ? change.kind.type : change?.kind, 32),
|
|
50
|
+
diff: publicText(change?.diff, 1800)
|
|
51
|
+
}));
|
|
52
|
+
if (Array.isArray(p.changes)) params.changes = changes(p.changes);
|
|
53
|
+
if (p.item) {
|
|
54
|
+
const item = p.item;
|
|
55
|
+
if (item.type === 'reasoning') return null;
|
|
56
|
+
params.item = {
|
|
57
|
+
...fields(item, ['id', 'type', 'status', 'phase', 'tool', 'server', 'exitCode', 'durationMs', 'success'], 400),
|
|
58
|
+
...fields(item, ['command'], 1000),
|
|
59
|
+
...fields(item, ['text'], 24000),
|
|
60
|
+
...fields(item, ['aggregatedOutput'], 1600)
|
|
61
|
+
};
|
|
62
|
+
if (Array.isArray(item.commandActions)) params.item.commandActions = item.commandActions.slice(0, 12)
|
|
63
|
+
.map(action => fields(action, ['type', 'path', 'query', 'name'], 400));
|
|
64
|
+
if (Array.isArray(item.changes)) params.item.changes = changes(item.changes);
|
|
65
|
+
if (item.error) params.item.error = fields(item.error, ['message'], 1200);
|
|
66
|
+
}
|
|
67
|
+
detail.params = params;
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
type: event.type, title: publicText(event.title, 24000),
|
|
71
|
+
status: publicText(event.status, 32),
|
|
72
|
+
timestamp: publicText(event.timestamp || new Date().toISOString(), 64), detail
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Metadata has a narrower exposure policy than already-compacted tool events.
|
|
77
|
+
function metadataText(value, limit) {
|
|
78
|
+
if (typeof value !== 'string') return '';
|
|
79
|
+
return publicText(value, 16384)
|
|
80
|
+
.replace(/(["'\x60])(?:file:\/\/|~\/|\/(?!\/)|[a-zA-Z]:[\\/]|\\\\)[\s\S]*?\1/g, '$1[local path]$1')
|
|
81
|
+
.replace(/\bfile:\/\/[^\s<>"'\x60]+/gi, '[local path]')
|
|
82
|
+
.replace(/(^|[\s([{"'=,:])(?:[a-zA-Z]:[\\/]|\\\\)[^\s<>"'\x60)\]}]+/g, '$1[local path]')
|
|
83
|
+
.replace(/(^|[\s([{"'=,:])(?:~\/|\/(?!\/))[^\s<>"'\x60)\]}]*/g, '$1[local path]')
|
|
84
|
+
.slice(0, limit);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function agentTitle(id, item) {
|
|
88
|
+
// agentPath is a logical namespace only for this exact, single-name shape.
|
|
89
|
+
// Never turn an arbitrary filesystem path into a display name.
|
|
90
|
+
const match = typeof item.agentPath === 'string'
|
|
91
|
+
&& /^\/root\/([a-zA-Z0-9][a-zA-Z0-9_-]{0,79})$/.exec(item.agentPath);
|
|
92
|
+
if (match) {
|
|
93
|
+
const name = match[1].replace(/[_-]+/g, ' ').trim();
|
|
94
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
95
|
+
}
|
|
96
|
+
const role = metadataText(item.agentRole, 120).trim();
|
|
97
|
+
return role && !role.includes('[local path]') ? role : 'Agent ' + id.slice(0, 8);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function taskText(value) {
|
|
101
|
+
if (typeof value !== 'string') return '';
|
|
102
|
+
const text = value.trim();
|
|
103
|
+
if (!text || /^gAAAA[A-Za-z0-9_-]{20,}={0,2}$/.test(text)
|
|
104
|
+
|| /^<(?:environment_context|user_instructions|developer_instructions|system_instructions|permissions|collaboration_mode)\b/i.test(text)
|
|
105
|
+
|| /^Same Codex Overleaf session context:/.test(text)
|
|
106
|
+
|| /^Message Type:\s*NEW_TASK\b/.test(text)) return '';
|
|
107
|
+
return metadataText(text, 4096);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function taskFromItems(items) {
|
|
111
|
+
for (const item of items.slice(0, 100)) {
|
|
112
|
+
if (item?.type !== 'userMessage' || !Array.isArray(item.content)
|
|
113
|
+
|| item.content.some(part => part?.type === 'encrypted_content')) continue;
|
|
114
|
+
const text = item.content.filter(part => part?.type === 'text')
|
|
115
|
+
.map(part => taskText(part.text)).filter(Boolean).join('\n').slice(0, 4096);
|
|
116
|
+
if (text) return text;
|
|
117
|
+
}
|
|
118
|
+
return '';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function createNativeSubagentObserver({ emit, request, getRoot, ownsParent, isStopped }) {
|
|
122
|
+
const children = new Map();
|
|
123
|
+
let closed = false;
|
|
124
|
+
const active = () => !closed && !isStopped();
|
|
125
|
+
function publish(child, event, extra = {}) {
|
|
126
|
+
if (!active()) return;
|
|
127
|
+
emit({
|
|
128
|
+
type: event ? 'codex.subagent.event' : 'codex.subagent.observed',
|
|
129
|
+
title: child.title, timestamp: new Date().toISOString(), status: child.status,
|
|
130
|
+
detail: {
|
|
131
|
+
source: 'codex', threadId: child.id, parentThreadId: child.parentThreadId,
|
|
132
|
+
title: child.title, task: child.task, status: child.status,
|
|
133
|
+
sequence: ++child.sequence, ...extra,
|
|
134
|
+
...(event ? { event: compactEvent(event) } : {})
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function status(value) {
|
|
139
|
+
return ({ pendingInit: 'pending', running: 'running', completed: 'completed',
|
|
140
|
+
errored: 'failed', interrupted: 'cancelled', notFound: 'unknown' })[value];
|
|
141
|
+
}
|
|
142
|
+
function setStatus(child, next, evidence) {
|
|
143
|
+
if (!next) return false;
|
|
144
|
+
if (TERMINAL.has(child.status)) {
|
|
145
|
+
if (!TERMINAL.has(next) || evidence < child.statusEvidence
|
|
146
|
+
|| next !== child.status && evidence === child.statusEvidence) return false;
|
|
147
|
+
}
|
|
148
|
+
const changed = child.status !== next;
|
|
149
|
+
child.status = next;
|
|
150
|
+
if (TERMINAL.has(next)) child.statusEvidence = evidence;
|
|
151
|
+
return changed;
|
|
152
|
+
}
|
|
153
|
+
function rememberTask(child, items) {
|
|
154
|
+
if (child.task) return false;
|
|
155
|
+
const text = taskFromItems(items);
|
|
156
|
+
if (!text) return false;
|
|
157
|
+
child.task = text;
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
function register(id, item) {
|
|
161
|
+
if (typeof id !== 'string' || !CHILD_ID.test(id) || id === getRoot().threadId) return null;
|
|
162
|
+
let child = children.get(id);
|
|
163
|
+
if (!child) {
|
|
164
|
+
if (children.size >= MAX_CHILDREN) return null;
|
|
165
|
+
child = { id, title: agentTitle(id, item),
|
|
166
|
+
task: taskText(item.prompt), parentThreadId: getRoot().threadId,
|
|
167
|
+
status: 'pending', statusEvidence: 0, turnId: '', generation: 0, retiredTurns: new Set(),
|
|
168
|
+
interruptionObserved: false, sequence: 0, items: new Map(), activities: new Set(), lastRead: -Infinity };
|
|
169
|
+
children.set(id, child);
|
|
170
|
+
} else {
|
|
171
|
+
if (child.title === 'Agent ' + id.slice(0, 8)) child.title = agentTitle(id, item);
|
|
172
|
+
if (!child.task) child.task = taskText(item.prompt);
|
|
173
|
+
}
|
|
174
|
+
return child;
|
|
175
|
+
}
|
|
176
|
+
function duplicateActivity(child, item) {
|
|
177
|
+
if (typeof item.id !== 'string' || !item.id) return false;
|
|
178
|
+
// The same lifecycle item can arrive as both item/started and item/completed.
|
|
179
|
+
// Its kind, not the outer notification method, identifies the child activity.
|
|
180
|
+
const key = JSON.stringify([item.id.slice(0, 160), item.kind]);
|
|
181
|
+
if (child.activities.has(key)) return true;
|
|
182
|
+
child.activities.add(key);
|
|
183
|
+
if (child.activities.size > 100) child.activities.delete(child.activities.values().next().value);
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
function snapshot(child, terminal = false) {
|
|
187
|
+
if (!active() || child.readDisabled || (child.readFailures || 0) >= MAX_HISTORY_READ_FAILURES) return;
|
|
188
|
+
if (child.reading) { child.readAgain ||= terminal; return; }
|
|
189
|
+
if (!terminal && Date.now() - child.lastRead < 2000) return;
|
|
190
|
+
child.reading = true; child.lastRead = Date.now();
|
|
191
|
+
const generation = child.generation, interruptionObserved = child.interruptionObserved;
|
|
192
|
+
// Read only on real lifecycle/activity notifications. Polling would keep
|
|
193
|
+
// the parent's idle watchdog alive and change execution semantics.
|
|
194
|
+
Promise.resolve().then(() => active()
|
|
195
|
+
? request('thread/read', { threadId: child.id, includeTurns: true }) : null)
|
|
196
|
+
.then(result => {
|
|
197
|
+
if (!active() || child.generation !== generation || result?.thread?.id !== child.id
|
|
198
|
+
|| result.thread.parentThreadId && result.thread.parentThreadId !== child.parentThreadId) return;
|
|
199
|
+
const turns = Array.isArray(result.thread.turns) ? result.thread.turns : [];
|
|
200
|
+
const turn = turns.at(-1);
|
|
201
|
+
// A fork can include its parent's context; do not replay that as work
|
|
202
|
+
// produced by this child.
|
|
203
|
+
if (!turn?.id || turn.id === getRoot().turnId
|
|
204
|
+
|| child.turnId && child.turnId !== turn.id) return;
|
|
205
|
+
child.historyTurnId = turn.id;
|
|
206
|
+
child.readFailures = 0;
|
|
207
|
+
if (child.historyUnavailable) {
|
|
208
|
+
child.historyUnavailable = false;
|
|
209
|
+
publish(child, null, { historyUnavailable: false });
|
|
210
|
+
}
|
|
211
|
+
const items = Array.isArray(turn.items) ? turn.items : [];
|
|
212
|
+
// Recover real child input before compactEvent drops user content.
|
|
213
|
+
// A fork's parent context and encrypted delegation are not task text.
|
|
214
|
+
if (rememberTask(child, items)) publish(child, null);
|
|
215
|
+
for (const item of items.slice(-100)) {
|
|
216
|
+
const event = compactEvent({
|
|
217
|
+
type: 'codex.session.event', status: item.status === 'inProgress' ? 'running' : 'completed',
|
|
218
|
+
detail: {
|
|
219
|
+
method: item.status === 'inProgress' ? 'item/started' : 'item/completed',
|
|
220
|
+
params: { threadId: child.id, turnId: turn.id, item }
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
if (!event) continue;
|
|
224
|
+
const signature = JSON.stringify(event.detail);
|
|
225
|
+
const key = turn.id + ':' + item.id;
|
|
226
|
+
if (child.items.get(key) === signature) continue;
|
|
227
|
+
child.items.set(key, signature);
|
|
228
|
+
if (child.items.size > 100) child.items.delete(child.items.keys().next().value);
|
|
229
|
+
publish(child, event, { historyClipped: items.length > 100 });
|
|
230
|
+
}
|
|
231
|
+
if (['completed', 'failed', 'interrupted'].includes(turn.status)) {
|
|
232
|
+
// A persisted, still-active turn can look interrupted. Require an
|
|
233
|
+
// explicit interruption observation before trusting that snapshot.
|
|
234
|
+
const next = turn.status === 'interrupted'
|
|
235
|
+
? (interruptionObserved ? 'cancelled' : undefined) : turn.status;
|
|
236
|
+
if (setStatus(child, next, EVIDENCE.history)) publish(child, null);
|
|
237
|
+
}
|
|
238
|
+
}).catch(error => {
|
|
239
|
+
if (!active() || child.generation !== generation) return;
|
|
240
|
+
// Unsupported history stays disabled; other errors get a bounded retry
|
|
241
|
+
// only on later activity. Observation never interrupts or resumes work.
|
|
242
|
+
child.readDisabled = error?.code === -32601 || error?.code === '-32601'
|
|
243
|
+
|| /(?:thread[ /]read.*(?:unsupported|not supported)|method (?:not found|not supported))/i.test(String(error?.message || ''));
|
|
244
|
+
child.readFailures = (child.readFailures || 0) + 1;
|
|
245
|
+
child.historyUnavailable = true;
|
|
246
|
+
publish(child, null, { historyUnavailable: true });
|
|
247
|
+
}).finally(() => {
|
|
248
|
+
child.reading = false;
|
|
249
|
+
if (child.readAgain) { child.readAgain = false; snapshot(child, true); }
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
function observe(message) {
|
|
253
|
+
if (!active()) return false;
|
|
254
|
+
const p = message.params || {};
|
|
255
|
+
const threadId = p.threadId || p.thread?.id;
|
|
256
|
+
const known = children.get(threadId);
|
|
257
|
+
if (known) {
|
|
258
|
+
const turnId = p.turnId || p.turn?.id || '';
|
|
259
|
+
if (message.method === 'turn/started') {
|
|
260
|
+
if (!turnId || known.retiredTurns.has(turnId)
|
|
261
|
+
|| (known.turnId === turnId || !known.turnId && known.historyTurnId === turnId)
|
|
262
|
+
&& TERMINAL.has(known.status)) return true;
|
|
263
|
+
if (known.turnId !== turnId) {
|
|
264
|
+
if (known.turnId) known.retiredTurns.add(known.turnId);
|
|
265
|
+
if (known.retiredTurns.size > 100) known.retiredTurns.delete(known.retiredTurns.values().next().value);
|
|
266
|
+
known.turnId = turnId;
|
|
267
|
+
known.generation += 1;
|
|
268
|
+
known.readFailures = 0;
|
|
269
|
+
known.lastRead = -Infinity;
|
|
270
|
+
known.statusEvidence = 0;
|
|
271
|
+
known.interruptionObserved = false;
|
|
272
|
+
}
|
|
273
|
+
known.status = 'running';
|
|
274
|
+
} else if (turnId && known.turnId && turnId !== known.turnId) {
|
|
275
|
+
return true;
|
|
276
|
+
} else if (turnId) {
|
|
277
|
+
known.turnId = turnId;
|
|
278
|
+
}
|
|
279
|
+
if (message.method === 'turn/completed') {
|
|
280
|
+
const next = p.turn?.status === 'interrupted' ? 'cancelled'
|
|
281
|
+
: ['completed', 'failed'].includes(p.turn?.status) ? p.turn.status : undefined;
|
|
282
|
+
const changed = setStatus(known, next, EVIDENCE.turn);
|
|
283
|
+
// Do not forward rejected terminal evidence: the frontend also reads
|
|
284
|
+
// params.turn.status and must not reapply a weaker/conflicting outcome.
|
|
285
|
+
if (next && !changed && next !== known.status) return true;
|
|
286
|
+
}
|
|
287
|
+
if (turnId && turnId !== getRoot().turnId && rememberTask(known, [p.item])) publish(known, null);
|
|
288
|
+
const event = compactEvent({ type: 'codex.session.event', title: message.method,
|
|
289
|
+
detail: { method: message.method, params: p }, status: /completed/.test(message.method) ? 'completed' : 'running' });
|
|
290
|
+
if (event) publish(known, event);
|
|
291
|
+
return true; // Child errors/completions cannot settle the parent.
|
|
292
|
+
}
|
|
293
|
+
if (!ownsParent(p)) return false;
|
|
294
|
+
const item = p.item || {};
|
|
295
|
+
if (item.type === 'subAgentActivity') {
|
|
296
|
+
if (!['started', 'interacted', 'interrupted', 'completed'].includes(item.kind)) return false;
|
|
297
|
+
const child = register(item.agentThreadId, item);
|
|
298
|
+
if (!child || duplicateActivity(child, item)) return false;
|
|
299
|
+
if (item.kind === 'started' && ['pending', 'unknown'].includes(child.status)) child.status = 'running';
|
|
300
|
+
if (item.kind === 'interrupted') child.interruptionObserved = true;
|
|
301
|
+
publish(child, null);
|
|
302
|
+
// A lifecycle completion wakes the final read; it does not establish
|
|
303
|
+
// success. Only the child's own turn/status evidence can do that.
|
|
304
|
+
snapshot(child, item.kind === 'completed' || item.kind === 'interrupted');
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
if (item.type !== 'collabAgentToolCall') return false;
|
|
308
|
+
const states = item.agentsStates && typeof item.agentsStates === 'object' ? item.agentsStates : {};
|
|
309
|
+
const ids = [...new Set([...(Array.isArray(item.receiverThreadIds) ? item.receiverThreadIds : []), ...Object.keys(states)])];
|
|
310
|
+
for (const id of ids.slice(0, MAX_CHILDREN)) {
|
|
311
|
+
const child = register(id, item);
|
|
312
|
+
if (!child) continue;
|
|
313
|
+
const next = status(states[id]?.status);
|
|
314
|
+
setStatus(child, next, EVIDENCE.agent);
|
|
315
|
+
const terminal = ['completed', 'failed', 'cancelled'].includes(child.status);
|
|
316
|
+
publish(child, null, { summary: next === child.status && TERMINAL.has(next)
|
|
317
|
+
? publicText(states[id]?.message, 24000) : '' });
|
|
318
|
+
snapshot(child, terminal);
|
|
319
|
+
}
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
return { observe, close() { closed = true; children.clear(); } };
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
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,34 @@
|
|
|
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, '/');
|
|
11
|
+
if (!normalized || path.isAbsolute(normalized)) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
let segments = normalized.split('/');
|
|
15
|
+
if (segments.some(segment => segment === '..' || segment === '')) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
// All consumers use the same identity, including control guards and locks.
|
|
19
|
+
segments = segments.filter(segment => segment !== '.');
|
|
20
|
+
if (!segments.length) return null;
|
|
21
|
+
if (segments[0] === SUBAGENT_QUEUE_DIR) {
|
|
22
|
+
// The queue control plane (jobs/results/logs/broker.json) is never
|
|
23
|
+
// ownable — but the work/ scratch zone IS: single-file fan-out slices
|
|
24
|
+
// live there (v1.6.1 scatter-gather), excluded from writeback by the
|
|
25
|
+
// mirror-scan rule yet fully owned/hashed like any other job file.
|
|
26
|
+
if (segments[1] === 'work' && segments.length >= 3) {
|
|
27
|
+
return segments.join('/');
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return segments.join('/');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = { safeWorkspaceRelativePath };
|