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
|
@@ -6,12 +6,16 @@ const path = require('node:path');
|
|
|
6
6
|
const { version: PACKAGE_VERSION } = require('../../package.json');
|
|
7
7
|
const { SUBAGENT_QUEUE_DIR, collectMirrorChangesDetailed, getProjectMirror, markMirrorDirty, syncOverleafToMirror } = require('./mirrorWorkspace');
|
|
8
8
|
const { computeLineDiff } = require('./diffEngine');
|
|
9
|
+
const { prepareSelectionScope, filterSelectionChanges } = require('./selectionScope');
|
|
10
|
+
const { normalizeSafeProjectPath } = require('../../extension/src/shared/projectFiles');
|
|
11
|
+
const WritingStyleRuntime = require('./writingStyleRuntime');
|
|
12
|
+
const { createRecoveringStyleRunner } = require('./codexModelRecovery');
|
|
9
13
|
const { computeTextPatches } = require('./textPatch');
|
|
10
14
|
const { buildCodexHomeEnv } = require('./codexHome');
|
|
15
|
+
const { applyCodexSkillIsolation } = require('./codexSkillIsolation');
|
|
11
16
|
const { buildCodexSpeedArgs } = require('./codexArgs');
|
|
12
17
|
const { truncateText } = require('./debugLog');
|
|
13
18
|
const {
|
|
14
|
-
estimateBase64DecodedBytes,
|
|
15
19
|
reduceTaskResult
|
|
16
20
|
} = require('./nativeTransportEnvelope');
|
|
17
21
|
const { buildCodexTurnPrompt: buildCodexPromptParts } = require('./codexPromptAssembly');
|
|
@@ -22,12 +26,14 @@ const {
|
|
|
22
26
|
loadSelectedProjectSkills
|
|
23
27
|
} = require('./localSkills');
|
|
24
28
|
const { createSubagentBroker } = require('./subagentBroker');
|
|
29
|
+
const { createNativeSubagentObserver } = require('./subagentTelemetry');
|
|
25
30
|
const { prepareBinaryAssetChanges } = require('./nativeAssetTransfer');
|
|
26
31
|
const { resolveCodexCommand, shouldUseShellForCommand } = require('./codexCommand');
|
|
27
32
|
const { applyProviderEnvironment, buildProviderConfigArgs, prepareProviderLaunch } = require('./codexProviderLaunch');
|
|
28
33
|
const { buildReadProgressRules, createReadProgressController, createRunEventScope } = require('./readProgressGuard');
|
|
29
34
|
const {
|
|
30
35
|
createCodexIdleWatchdog,
|
|
36
|
+
createProcessStopIdentity,
|
|
31
37
|
createOptionalTimeout,
|
|
32
38
|
getAbortReason,
|
|
33
39
|
parseOptionalPositiveInteger,
|
|
@@ -38,16 +44,25 @@ const {
|
|
|
38
44
|
|
|
39
45
|
const PARALLEL_SUBAGENTS_SKILL_ID = 'parallel-subagents';
|
|
40
46
|
|
|
41
|
-
const
|
|
42
|
-
const MAX_TURN_ATTACHMENT_BYTES = 12 * 1024 * 1024;
|
|
43
|
-
const MAX_TURN_ATTACHMENTS = 8;
|
|
44
|
-
const MAX_TURN_ATTACHMENT_TOTAL_BYTES = MAX_TURN_ATTACHMENT_BYTES * MAX_TURN_ATTACHMENTS;
|
|
47
|
+
const { materializeTurnAttachments } = require('./turnAttachments');
|
|
45
48
|
|
|
46
|
-
async function runCodexSession({ params = {}, env = process.env, emit = () => {}, rootDir, executeCodex, providerLaunch, signal, onControlReady } = {}) {
|
|
49
|
+
async function runCodexSession({ params = {}, env = process.env, emit = () => {}, rootDir, executeCodex, providerLaunch, signal, onControlReady, onStopUnconfirmed, onProcessStarted } = {}) {
|
|
47
50
|
throwIfAborted(signal);
|
|
51
|
+
if (params.writingStyleBuild) {
|
|
52
|
+
return WritingStyleRuntime.build({
|
|
53
|
+
params, env, signal, providerLaunch, onControlReady, onStopUnconfirmed,
|
|
54
|
+
execute: createRecoveringStyleRunner({
|
|
55
|
+
execute: input => (executeCodex || runCodexAppServerSession)({ ...input, onProcessStarted }),
|
|
56
|
+
env, emit, locale: params.locale
|
|
57
|
+
})
|
|
58
|
+
});
|
|
59
|
+
}
|
|
48
60
|
const projectId = params.projectId || params.project?.projectId || params.project?.id || params.project?.url || 'overleaf-project';
|
|
49
61
|
const skillInvocation = normalizeSkillInvocation(params.skillInvocation);
|
|
50
62
|
const skillInstallTurn = isSkillInstallerInvocation(skillInvocation);
|
|
63
|
+
const writingStyleContext = skillInstallTurn ? '' : await WritingStyleRuntime.forRun(
|
|
64
|
+
params.writingStyle, { ...params, projectId }, env
|
|
65
|
+
);
|
|
51
66
|
if (skillInstallTurn && Array.isArray(params.attachments) && params.attachments.length) {
|
|
52
67
|
throw new Error('Skill installer turns do not accept attachments');
|
|
53
68
|
}
|
|
@@ -69,13 +84,20 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
69
84
|
});
|
|
70
85
|
throwIfAborted(signal);
|
|
71
86
|
|
|
72
|
-
emitCodexEvent(emit, 'overleaf.sync.completed',
|
|
87
|
+
emitCodexEvent(emit, 'overleaf.sync.completed', mirror.skippedFiles?.length
|
|
88
|
+
? 'Readable Overleaf files synced; some asset contents are unavailable'
|
|
89
|
+
: 'Overleaf project synced to local workspace', {
|
|
73
90
|
projectId: mirror.projectKey,
|
|
74
91
|
workspacePath: mirror.workspacePath,
|
|
75
|
-
fileCount: mirror.fileCount
|
|
92
|
+
fileCount: mirror.fileCount,
|
|
93
|
+
contentComplete: mirror.contentComplete !== false,
|
|
94
|
+
skippedFiles: mirror.skippedFiles || []
|
|
76
95
|
}, 'completed');
|
|
77
96
|
}
|
|
78
|
-
|
|
97
|
+
if (skillInstallTurn && params.selectionContext) throw new Error('Remove the selected text before installing skills.');
|
|
98
|
+
const selectionScope = prepareSelectionScope(params.selectionContext, mirror.workspacePath, projectId);
|
|
99
|
+
if (selectionScope?.rebased) emitCodexEvent(emit, 'overleaf.selection.rebased', 'The unchanged selection was mapped to the current document.',
|
|
100
|
+
{ path: selectionScope.selection.path, from: selectionScope.selection.from, to: selectionScope.selection.to, original: selectionScope.original }, 'info');
|
|
79
101
|
const projectLocalSkills = loadProjectLocalSkillsContext(params, mirror);
|
|
80
102
|
if (projectLocalSkills.missing.length) {
|
|
81
103
|
emitCodexEvent(emit, 'codex.local_skills.missing', 'Selected project-local skills were missing', {
|
|
@@ -85,12 +107,15 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
85
107
|
const turnAttachments = materializeTurnAttachments(params.attachments, mirror.workspacePath);
|
|
86
108
|
const settings = buildCodexSettings(params);
|
|
87
109
|
const skillLoading = normalizeSkillLoadingSettings(params);
|
|
88
|
-
const codexSkillInvocationContext = loadCodexSkillInvocationContext({
|
|
110
|
+
const codexSkillInvocationContext = await loadCodexSkillInvocationContext({
|
|
89
111
|
skillInvocation,
|
|
112
|
+
loadCodexLocalSkills: skillLoading.loadCodexLocalSkills,
|
|
113
|
+
enabledCodexLocalSkillIds: params.enabledCodexLocalSkillIds,
|
|
90
114
|
loadCodexOverleafSkills: skillLoading.loadCodexOverleafSkills,
|
|
91
115
|
enabledCodexOverleafSkillIds: params.enabledCodexOverleafSkillIds,
|
|
92
116
|
env,
|
|
93
|
-
emit
|
|
117
|
+
emit,
|
|
118
|
+
signal
|
|
94
119
|
});
|
|
95
120
|
const effectiveSkillInvocation = getEffectiveSkillInvocation(codexSkillInvocationContext);
|
|
96
121
|
const runnerWorkspacePath = skillInstallTurn
|
|
@@ -99,12 +124,24 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
99
124
|
if (skillInstallTurn) {
|
|
100
125
|
fs.mkdirSync(runnerWorkspacePath, { recursive: true });
|
|
101
126
|
}
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
127
|
+
const execute = executeCodex || runCodexAppServerSession;
|
|
128
|
+
let unconfirmedStopError = null;
|
|
129
|
+
const runner = async input => {
|
|
130
|
+
try { return await execute({ ...input, onProcessStarted }); }
|
|
131
|
+
catch (error) {
|
|
132
|
+
if (error?.code === 'codex_process_stop_unconfirmed') {
|
|
133
|
+
unconfirmedStopError = error;
|
|
134
|
+
onStopUnconfirmed?.(error);
|
|
135
|
+
}
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
// The file broker is available only to writable runs with the official
|
|
140
|
+
// skill enabled. Ask keeps its existing read-only sandbox. Workers are sibling Codex runs spawned by the
|
|
105
141
|
// host (fresh sandbox — never nested), confined to the same mirror; the
|
|
106
142
|
// broker enforces file ownership and wall-clock deadlines (spec §5-§7).
|
|
107
143
|
const subagentBroker = !skillInstallTurn
|
|
144
|
+
&& settings.sandboxMode === 'workspace-write'
|
|
108
145
|
&& skillLoading.loadCodexOverleafSkills !== false
|
|
109
146
|
&& Array.isArray(params.enabledCodexOverleafSkillIds)
|
|
110
147
|
&& params.enabledCodexOverleafSkillIds.includes(PARALLEL_SUBAGENTS_SKILL_ID)
|
|
@@ -113,9 +150,9 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
113
150
|
signal,
|
|
114
151
|
emit: (type, title, detail, status) => emitCodexEvent(emit, type, title, detail, status),
|
|
115
152
|
onMirrorDirty: () => markMirrorDirty({ projectId, rootDir, reason: 'subagent_run_cancelled' }),
|
|
116
|
-
runWorkerTask: ({ jobId, prompt, signal: workerSignal }) => runner({
|
|
153
|
+
runWorkerTask: ({ jobId, prompt, signal: workerSignal, onEvent }) => runner({
|
|
117
154
|
workspacePath: mirror.workspacePath,
|
|
118
|
-
task: prompt,
|
|
155
|
+
task: prompt + writingStyleContext,
|
|
119
156
|
userTask: `subagent:${jobId}`,
|
|
120
157
|
session: null,
|
|
121
158
|
threadId: '',
|
|
@@ -125,6 +162,8 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
125
162
|
speedTier: normalizeSpeedTier(params.speedTier),
|
|
126
163
|
loadCodexLocalSkills: skillLoading.loadCodexLocalSkills,
|
|
127
164
|
loadCodexOverleafSkills: skillLoading.loadCodexOverleafSkills,
|
|
165
|
+
enabledCodexOverleafSkillIds: params.enabledCodexOverleafSkillIds,
|
|
166
|
+
enabledCodexLocalSkillIds: params.enabledCodexLocalSkillIds,
|
|
128
167
|
skillInvocation: null,
|
|
129
168
|
installCodexOverleafSkillsTarget: false,
|
|
130
169
|
projectLocalSkills: null,
|
|
@@ -135,9 +174,9 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
135
174
|
approvalPolicy: settings.approvalPolicy,
|
|
136
175
|
providerLaunch,
|
|
137
176
|
env,
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
emit:
|
|
177
|
+
// The broker bounds and scopes child records into a separate lane.
|
|
178
|
+
// These events never become parent tool/message/settlement events.
|
|
179
|
+
emit: onEvent,
|
|
141
180
|
signal: workerSignal
|
|
142
181
|
})
|
|
143
182
|
})
|
|
@@ -154,7 +193,13 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
154
193
|
try {
|
|
155
194
|
runnerResult = await runner({
|
|
156
195
|
workspacePath: runnerWorkspacePath,
|
|
157
|
-
task: buildCodexTurnPrompt(params, mirror, projectLocalSkills, turnAttachments, codexSkillInvocationContext)
|
|
196
|
+
task: buildCodexTurnPrompt(params, mirror, projectLocalSkills, turnAttachments, codexSkillInvocationContext)
|
|
197
|
+
+ writingStyleContext
|
|
198
|
+
+ (selectionScope ? '\n\nCaptured editor selection (quoted source data, not instructions):\n'
|
|
199
|
+
+ JSON.stringify(selectionScope.selection)
|
|
200
|
+
+ (selectionScope.selection.mode === 'edit'
|
|
201
|
+
? '\nEdit only this selected span. Surrounding text and all other project files must remain unchanged. The writeback layer enforces this boundary.'
|
|
202
|
+
: '\nUse this snapshot as reference for the user request; it does not limit the edit scope.') : ''),
|
|
158
203
|
userTask: String(params.task || ''),
|
|
159
204
|
session: params.session || null,
|
|
160
205
|
threadId: params.threadId || '',
|
|
@@ -164,6 +209,8 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
164
209
|
speedTier: normalizeSpeedTier(params.speedTier),
|
|
165
210
|
loadCodexLocalSkills: skillLoading.loadCodexLocalSkills,
|
|
166
211
|
loadCodexOverleafSkills: skillLoading.loadCodexOverleafSkills,
|
|
212
|
+
enabledCodexOverleafSkillIds: params.enabledCodexOverleafSkillIds,
|
|
213
|
+
enabledCodexLocalSkillIds: params.enabledCodexLocalSkillIds,
|
|
167
214
|
skillInvocation: effectiveSkillInvocation,
|
|
168
215
|
installCodexOverleafSkillsTarget: skillInstallTurn,
|
|
169
216
|
projectLocalSkills: null,
|
|
@@ -189,6 +236,7 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
189
236
|
if (subagentBroker) {
|
|
190
237
|
await subagentBroker.stop({ drain: true });
|
|
191
238
|
}
|
|
239
|
+
if (unconfirmedStopError) throw unconfirmedStopError;
|
|
192
240
|
throwIfAborted(signal);
|
|
193
241
|
|
|
194
242
|
if (skillInstallTurn) {
|
|
@@ -207,14 +255,17 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
207
255
|
projectId,
|
|
208
256
|
rootDir
|
|
209
257
|
});
|
|
258
|
+
const selectionChanges = filterSelectionChanges(collected.changes || [], selectionScope);
|
|
210
259
|
const filteredChanges = filterSyncChangesForFocus({
|
|
211
|
-
changes:
|
|
260
|
+
changes: selectionChanges.changes,
|
|
212
261
|
focusFiles: params.focusFiles || params.session?.focusFiles,
|
|
262
|
+
focusFilesAreLiteral: params.focusFilesAreLiteral === true,
|
|
213
263
|
restrictToFocusFiles: params.restrictToFocusFiles
|
|
214
264
|
});
|
|
215
265
|
let rawSyncChanges = filteredChanges.changes;
|
|
216
266
|
const unsupportedChanges = [
|
|
217
267
|
...(collected.unsupportedChanges || []),
|
|
268
|
+
...selectionChanges.unsupportedChanges,
|
|
218
269
|
...filteredChanges.unsupportedChanges
|
|
219
270
|
];
|
|
220
271
|
// Spec S8: ownership violations hard-block writeback. Changes on violated
|
|
@@ -223,13 +274,14 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
223
274
|
// syncChanges would write directly.
|
|
224
275
|
const subagentViolationPaths = subagentBroker ? subagentBroker.getViolationPaths() : null;
|
|
225
276
|
if (subagentViolationPaths && subagentViolationPaths.size) {
|
|
226
|
-
const
|
|
227
|
-
|
|
277
|
+
const violatedPath = change => [change.path, change.to].find(file => file && subagentViolationPaths.has(file));
|
|
278
|
+
const blocked = rawSyncChanges.filter(change => violatedPath(change));
|
|
279
|
+
rawSyncChanges = rawSyncChanges.filter(change => !violatedPath(change));
|
|
228
280
|
for (const change of blocked) {
|
|
229
281
|
unsupportedChanges.push({
|
|
230
282
|
type: 'unsupported-local-file',
|
|
231
283
|
path: change.path,
|
|
232
|
-
reason:
|
|
284
|
+
reason: subagentBroker.getBlockedReason(violatedPath(change))
|
|
233
285
|
});
|
|
234
286
|
}
|
|
235
287
|
}
|
|
@@ -290,7 +342,7 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
290
342
|
files: response.syncChanges.map(change => change.path),
|
|
291
343
|
unsupportedCount: response.unsupportedChanges.length,
|
|
292
344
|
unsupportedFiles: response.unsupportedChanges.map(change => change.path)
|
|
293
|
-
}, 'completed');
|
|
345
|
+
}, response.unsupportedChanges.length ? 'warning' : 'completed');
|
|
294
346
|
|
|
295
347
|
return response;
|
|
296
348
|
}
|
|
@@ -306,112 +358,15 @@ function buildCodexTurnPrompt(params = {}, mirror = {}, projectLocalSkills, turn
|
|
|
306
358
|
return [prompt.systemPrompt, buildReadProgressRules(), prompt.userPrompt].filter(Boolean).join('\n\n');
|
|
307
359
|
}
|
|
308
360
|
|
|
309
|
-
function materializeTurnAttachments(attachments = [], workspacePath = '') {
|
|
310
|
-
if (!workspacePath) {
|
|
311
|
-
return [];
|
|
312
|
-
}
|
|
313
|
-
const attachmentDir = path.join(workspacePath, TURN_ATTACHMENTS_DIR);
|
|
314
|
-
fs.rmSync(attachmentDir, { recursive: true, force: true });
|
|
315
|
-
|
|
316
|
-
const normalized = normalizeTurnAttachments(attachments);
|
|
317
|
-
if (!normalized.length) {
|
|
318
|
-
return [];
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
fs.mkdirSync(attachmentDir, { recursive: true });
|
|
322
|
-
const usedNames = new Set();
|
|
323
|
-
return normalized.map(attachment => {
|
|
324
|
-
const fileName = dedupeAttachmentFileName(attachment.name, usedNames);
|
|
325
|
-
const target = path.join(attachmentDir, fileName);
|
|
326
|
-
const resolvedTarget = path.resolve(target);
|
|
327
|
-
const resolvedDir = path.resolve(attachmentDir);
|
|
328
|
-
if (!resolvedTarget.startsWith(resolvedDir + path.sep)) {
|
|
329
|
-
throw new Error('Unsafe attachment path');
|
|
330
|
-
}
|
|
331
|
-
fs.writeFileSync(target, attachment.bytes);
|
|
332
|
-
return {
|
|
333
|
-
name: fileName,
|
|
334
|
-
path: `${TURN_ATTACHMENTS_DIR}/${fileName}`,
|
|
335
|
-
mimeType: attachment.mimeType,
|
|
336
|
-
size: attachment.bytes.length
|
|
337
|
-
};
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
361
|
|
|
341
|
-
function normalizeTurnAttachments(value) {
|
|
342
|
-
const input = Array.isArray(value) ? value : [];
|
|
343
|
-
if (input.length > MAX_TURN_ATTACHMENTS) {
|
|
344
|
-
throw new Error(`Too many attachments (${input.length}/${MAX_TURN_ATTACHMENTS})`);
|
|
345
|
-
}
|
|
346
|
-
const result = [];
|
|
347
|
-
let totalBytes = 0;
|
|
348
|
-
for (const item of input) {
|
|
349
|
-
const name = sanitizeAttachmentFileName(item?.name);
|
|
350
|
-
const contentBase64 = String(item?.contentBase64 || '').replace(/\s+/g, '');
|
|
351
|
-
if (!name || !contentBase64) {
|
|
352
|
-
continue;
|
|
353
|
-
}
|
|
354
|
-
const declared = Number(item?.size);
|
|
355
|
-
const estimatedBytes = Math.max(
|
|
356
|
-
Number.isFinite(declared) && declared > 0 ? declared : 0,
|
|
357
|
-
estimateBase64DecodedBytes(contentBase64)
|
|
358
|
-
);
|
|
359
|
-
if (estimatedBytes > MAX_TURN_ATTACHMENT_BYTES) {
|
|
360
|
-
throw new Error(`Attachment is too large: ${name}`);
|
|
361
|
-
}
|
|
362
|
-
const bytes = Buffer.from(contentBase64, 'base64');
|
|
363
|
-
if (!bytes.length) {
|
|
364
|
-
continue;
|
|
365
|
-
}
|
|
366
|
-
if (bytes.length > MAX_TURN_ATTACHMENT_BYTES) {
|
|
367
|
-
throw new Error(`Attachment is too large: ${name}`);
|
|
368
|
-
}
|
|
369
|
-
totalBytes += Math.max(estimatedBytes, bytes.length);
|
|
370
|
-
if (totalBytes > MAX_TURN_ATTACHMENT_TOTAL_BYTES) {
|
|
371
|
-
throw new Error(`Attachments are too large (${totalBytes}/${MAX_TURN_ATTACHMENT_TOTAL_BYTES} bytes)`);
|
|
372
|
-
}
|
|
373
|
-
result.push({
|
|
374
|
-
name,
|
|
375
|
-
mimeType: String(item?.mimeType || '').trim().slice(0, 120),
|
|
376
|
-
bytes
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
return result;
|
|
380
|
-
}
|
|
381
362
|
|
|
382
|
-
function sanitizeAttachmentFileName(value) {
|
|
383
|
-
const basename = String(value || '')
|
|
384
|
-
.replace(/\0/g, '')
|
|
385
|
-
.replace(/\\/g, '/')
|
|
386
|
-
.split('/')
|
|
387
|
-
.filter(Boolean)
|
|
388
|
-
.pop()
|
|
389
|
-
?.trim()
|
|
390
|
-
.slice(0, 180) || '';
|
|
391
|
-
return basename.replace(/[/:]/g, '-');
|
|
392
|
-
}
|
|
393
363
|
|
|
394
|
-
function dedupeAttachmentFileName(name, usedNames) {
|
|
395
|
-
let candidate = name || 'attachment';
|
|
396
|
-
if (!usedNames.has(candidate)) {
|
|
397
|
-
usedNames.add(candidate);
|
|
398
|
-
return candidate;
|
|
399
|
-
}
|
|
400
|
-
const parsed = path.parse(candidate);
|
|
401
|
-
let index = 2;
|
|
402
|
-
do {
|
|
403
|
-
candidate = `${parsed.name}-${index}${parsed.ext}`;
|
|
404
|
-
index += 1;
|
|
405
|
-
} while (usedNames.has(candidate));
|
|
406
|
-
usedNames.add(candidate);
|
|
407
|
-
return candidate;
|
|
408
|
-
}
|
|
409
364
|
|
|
410
|
-
function normalizeFocusFiles(value) {
|
|
365
|
+
function normalizeFocusFiles(value, literal = false) {
|
|
411
366
|
const seen = new Set();
|
|
412
367
|
const files = [];
|
|
413
368
|
for (const item of Array.isArray(value) ? value : []) {
|
|
414
|
-
const filePath = normalizeProjectPath(item);
|
|
369
|
+
const filePath = literal ? normalizeSafeProjectPath(item) : normalizeProjectPath(item);
|
|
415
370
|
if (!filePath || seen.has(filePath)) {
|
|
416
371
|
continue;
|
|
417
372
|
}
|
|
@@ -423,20 +378,20 @@ function normalizeFocusFiles(value) {
|
|
|
423
378
|
}
|
|
424
379
|
return files;
|
|
425
380
|
}
|
|
426
|
-
|
|
427
|
-
function filterSyncChangesForFocus({ changes = [], focusFiles = [], restrictToFocusFiles = false } = {}) {
|
|
381
|
+
function filterSyncChangesForFocus({ changes = [], focusFiles = [], restrictToFocusFiles = false, focusFilesAreLiteral = false } = {}) {
|
|
428
382
|
if (!restrictToFocusFiles) {
|
|
429
383
|
return { changes, unsupportedChanges: [] };
|
|
430
384
|
}
|
|
431
|
-
const focusSet = new Set(normalizeFocusFiles(focusFiles));
|
|
432
|
-
if (!focusSet.size) {
|
|
385
|
+
const focusSet = new Set(normalizeFocusFiles(focusFiles, focusFilesAreLiteral === true));
|
|
386
|
+
if (!focusSet.size && focusFilesAreLiteral !== true) {
|
|
433
387
|
return { changes, unsupportedChanges: [] };
|
|
434
388
|
}
|
|
435
389
|
|
|
436
390
|
const accepted = [];
|
|
437
391
|
const rejected = [];
|
|
438
392
|
for (const change of changes || []) {
|
|
439
|
-
if (focusSet.has(
|
|
393
|
+
if (focusSet.has(normalizeSafeProjectPath(change?.path))
|
|
394
|
+
&& (!change?.to || focusSet.has(normalizeSafeProjectPath(change.to)))) {
|
|
440
395
|
accepted.push(change);
|
|
441
396
|
} else if (change?.path) {
|
|
442
397
|
rejected.push({
|
|
@@ -451,7 +406,6 @@ function filterSyncChangesForFocus({ changes = [], focusFiles = [], restrictToFo
|
|
|
451
406
|
unsupportedChanges: rejected
|
|
452
407
|
};
|
|
453
408
|
}
|
|
454
|
-
|
|
455
409
|
function normalizeProjectPath(value) {
|
|
456
410
|
return String(value || '')
|
|
457
411
|
.replace(/^@file:/i, '')
|
|
@@ -481,12 +435,15 @@ function normalizeSkillLoadingSettings(params = {}) {
|
|
|
481
435
|
};
|
|
482
436
|
}
|
|
483
437
|
|
|
484
|
-
function loadCodexSkillInvocationContext({
|
|
438
|
+
async function loadCodexSkillInvocationContext({
|
|
485
439
|
skillInvocation,
|
|
440
|
+
loadCodexLocalSkills = true,
|
|
441
|
+
enabledCodexLocalSkillIds,
|
|
486
442
|
loadCodexOverleafSkills = true,
|
|
487
443
|
enabledCodexOverleafSkillIds,
|
|
488
444
|
env = process.env,
|
|
489
|
-
emit = () => {}
|
|
445
|
+
emit = () => {},
|
|
446
|
+
signal
|
|
490
447
|
} = {}) {
|
|
491
448
|
const invocation = normalizeSkillInvocation(skillInvocation);
|
|
492
449
|
if (!invocation) {
|
|
@@ -496,19 +453,37 @@ function loadCodexSkillInvocationContext({
|
|
|
496
453
|
return { invocation, skill: null, missing: [], ignored: [] };
|
|
497
454
|
}
|
|
498
455
|
|
|
499
|
-
const
|
|
456
|
+
const local = invocation.scope === 'codex-local';
|
|
457
|
+
const result = local ? await require('./codexLocalSkills').loadSelectedCodexLocalSkill({
|
|
458
|
+
skillId: invocation.id,
|
|
459
|
+
loadCodexLocalSkills,
|
|
460
|
+
enabledCodexLocalSkillIds,
|
|
461
|
+
env,
|
|
462
|
+
signal
|
|
463
|
+
}).catch(error => {
|
|
464
|
+
if (signal?.aborted || (!String(error?.code || '').startsWith('codex_local_skills_')
|
|
465
|
+
&& error?.code !== 'codex_not_found')) throw error;
|
|
466
|
+
throw Object.assign(new Error('The selected local Codex skill is unavailable. Refresh the skill list and select it again.'),
|
|
467
|
+
{ code: 'codex_local_skill_unavailable', cause: error });
|
|
468
|
+
}) : loadSelectedCodexOverleafSkill({
|
|
500
469
|
skillId: invocation.id,
|
|
501
470
|
loadCodexOverleafSkills,
|
|
502
471
|
enabledCodexOverleafSkillIds,
|
|
503
472
|
env
|
|
504
473
|
});
|
|
474
|
+
if (local && !result.skill) {
|
|
475
|
+
throw Object.assign(new Error('The selected local Codex skill is unavailable. Refresh the skill list and select it again.'),
|
|
476
|
+
{ code: 'codex_local_skill_unavailable' });
|
|
477
|
+
}
|
|
505
478
|
if (result.missing.length) {
|
|
506
|
-
emitCodexEvent(emit, 'codex.
|
|
479
|
+
emitCodexEvent(emit, local ? 'codex.local_skills.missing' : 'codex.overleaf_skills.missing',
|
|
480
|
+
local ? 'Selected local Codex skill was missing' : 'Selected Codex Overleaf skill was missing', {
|
|
507
481
|
missingSkillIds: result.missing
|
|
508
482
|
}, 'failed');
|
|
509
483
|
}
|
|
510
484
|
if (result.ignored.length) {
|
|
511
|
-
emitCodexEvent(emit, 'codex.
|
|
485
|
+
emitCodexEvent(emit, local ? 'codex.local_skill_invocation.ignored' : 'codex.overleaf_skill_invocation.ignored',
|
|
486
|
+
local ? 'Selected local Codex skill was ignored' : 'Selected Codex Overleaf skill was ignored', {
|
|
512
487
|
ignoredSkillIds: result.ignored.map(item => item.id),
|
|
513
488
|
reason: result.ignored[0]?.reason || 'ignored'
|
|
514
489
|
}, 'warning');
|
|
@@ -539,17 +514,18 @@ function normalizeSkillInvocation(value) {
|
|
|
539
514
|
return null;
|
|
540
515
|
}
|
|
541
516
|
const title = String(value?.title || 'Skill Installer').trim().slice(0, 80) || 'Skill Installer';
|
|
542
|
-
if (id === 'skill-installer') {
|
|
517
|
+
if (id === 'skill-installer' && (!value?.scope || value.scope === 'builtin')) {
|
|
543
518
|
return { id, title };
|
|
544
519
|
}
|
|
545
|
-
if (
|
|
520
|
+
if (!['codex-overleaf', 'codex-local'].includes(value?.scope)) {
|
|
546
521
|
return null;
|
|
547
522
|
}
|
|
548
|
-
return { id, title, scope:
|
|
523
|
+
return { id, title, scope: value.scope };
|
|
549
524
|
}
|
|
550
525
|
|
|
551
526
|
function isSkillInstallerInvocation(value) {
|
|
552
|
-
|
|
527
|
+
const invocation = normalizeSkillInvocation(value);
|
|
528
|
+
return invocation?.id === 'skill-installer' && !invocation.scope;
|
|
553
529
|
}
|
|
554
530
|
|
|
555
531
|
function isSafeSkillId(id) {
|
|
@@ -614,146 +590,6 @@ function buildCodexAppServerArgs(input = {}) {
|
|
|
614
590
|
];
|
|
615
591
|
}
|
|
616
592
|
|
|
617
|
-
async function applyCodexSkillIsolation({ input = {}, childEnv = process.env, request, emit = () => {} } = {}) {
|
|
618
|
-
if (input.loadCodexLocalSkills !== false) {
|
|
619
|
-
return { disabled: [] };
|
|
620
|
-
}
|
|
621
|
-
if (typeof request !== 'function') {
|
|
622
|
-
throw new Error('Codex skill isolation requires an app-server request function');
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
const listResult = await request('skills/list', {
|
|
626
|
-
cwd: input.workspacePath,
|
|
627
|
-
includeDisabled: true
|
|
628
|
-
});
|
|
629
|
-
const skills = flattenCodexSkillsList(listResult);
|
|
630
|
-
const disabled = [];
|
|
631
|
-
for (const skill of skills) {
|
|
632
|
-
if (skill?.enabled === false || !shouldDisableCodexSkillForIsolation(skill, input, childEnv)) {
|
|
633
|
-
continue;
|
|
634
|
-
}
|
|
635
|
-
const params = buildSkillDisableParams(skill);
|
|
636
|
-
if (!params) {
|
|
637
|
-
continue;
|
|
638
|
-
}
|
|
639
|
-
await request('skills/config/write', params);
|
|
640
|
-
disabled.push(String(skill.name || skill.path || '').trim());
|
|
641
|
-
}
|
|
642
|
-
if (disabled.length) {
|
|
643
|
-
emitCodexEvent(emit, 'codex.skill_isolation.applied', 'Disabled non-Overleaf Codex skills for this turn', {
|
|
644
|
-
disabledSkillNames: disabled.filter(Boolean)
|
|
645
|
-
}, 'completed');
|
|
646
|
-
}
|
|
647
|
-
return { disabled };
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
// Recursion guard (spec S6): disable specific Codex-Overleaf skills for one
|
|
651
|
-
// app-server child process — used to strip `parallel-subagents` from worker
|
|
652
|
-
// runs so an inheriting worker cannot discover the queue and fan out again.
|
|
653
|
-
// Skill directories are named by skill id (<root>/<id>/SKILL.md).
|
|
654
|
-
async function applyWorkerSkillStrip({ input = {}, request } = {}) {
|
|
655
|
-
const ids = Array.isArray(input.disableCodexOverleafSkillIds)
|
|
656
|
-
? input.disableCodexOverleafSkillIds.filter(Boolean)
|
|
657
|
-
: [];
|
|
658
|
-
if (!ids.length || typeof request !== 'function') {
|
|
659
|
-
return { disabled: [] };
|
|
660
|
-
}
|
|
661
|
-
const listResult = await request('skills/list', {
|
|
662
|
-
cwd: input.workspacePath,
|
|
663
|
-
includeDisabled: true
|
|
664
|
-
});
|
|
665
|
-
const disabled = [];
|
|
666
|
-
for (const skill of flattenCodexSkillsList(listResult)) {
|
|
667
|
-
if (skill?.enabled === false) {
|
|
668
|
-
continue;
|
|
669
|
-
}
|
|
670
|
-
const skillDirName = path.basename(path.dirname(String(skill?.path || '')));
|
|
671
|
-
if (!ids.includes(skillDirName)) {
|
|
672
|
-
continue;
|
|
673
|
-
}
|
|
674
|
-
const params = buildSkillDisableParams(skill);
|
|
675
|
-
if (!params) {
|
|
676
|
-
continue;
|
|
677
|
-
}
|
|
678
|
-
await request('skills/config/write', params);
|
|
679
|
-
disabled.push(skillDirName);
|
|
680
|
-
}
|
|
681
|
-
return { disabled };
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
function flattenCodexSkillsList(listResult = {}) {
|
|
685
|
-
const data = Array.isArray(listResult?.data) ? listResult.data : [];
|
|
686
|
-
return data.flatMap(entry => Array.isArray(entry?.skills) ? entry.skills : []);
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
function shouldDisableCodexSkillForIsolation(skill = {}, input = {}, childEnv = process.env) {
|
|
690
|
-
if (isCodexSystemSkill(skill)) {
|
|
691
|
-
return !isAllowedSystemSkillForIsolation(skill, input);
|
|
692
|
-
}
|
|
693
|
-
return !isAllowedCodexOverleafSkillPath(skill.path, input, childEnv);
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
function isCodexSystemSkill(skill = {}) {
|
|
697
|
-
return String(skill.scope || '') === 'system' || isSystemSkillPath(skill.path);
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
function isAllowedSystemSkillForIsolation(skill = {}, input = {}) {
|
|
701
|
-
return input.installCodexOverleafSkillsTarget === true && String(skill.name || '') === 'skill-installer';
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
function isAllowedCodexOverleafSkillPath(skillPath, input = {}, childEnv = process.env) {
|
|
705
|
-
if (input.loadCodexOverleafSkills === false && input.installCodexOverleafSkillsTarget !== true) {
|
|
706
|
-
return false;
|
|
707
|
-
}
|
|
708
|
-
const pathText = String(skillPath || '');
|
|
709
|
-
if (!pathText || !path.isAbsolute(pathText) || isSystemSkillPath(pathText)) {
|
|
710
|
-
return false;
|
|
711
|
-
}
|
|
712
|
-
const roots = [
|
|
713
|
-
path.join(String(childEnv.CODEX_HOME || ''), 'skills'),
|
|
714
|
-
getCodexOverleafSkillsRoot({ env: childEnv })
|
|
715
|
-
].filter(Boolean);
|
|
716
|
-
return roots.some(root => isInsideOrSamePath(pathText, root));
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
function isSystemSkillPath(skillPath) {
|
|
720
|
-
return String(skillPath || '').split(path.sep).includes('.system');
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
function buildSkillDisableParams(skill = {}) {
|
|
724
|
-
const name = String(skill.name || '').trim();
|
|
725
|
-
if (isCodexSystemSkill(skill) && name) {
|
|
726
|
-
return { name, enabled: false };
|
|
727
|
-
}
|
|
728
|
-
const skillPath = String(skill.path || '').trim();
|
|
729
|
-
if (path.isAbsolute(skillPath)) {
|
|
730
|
-
return { path: skillPath, enabled: false };
|
|
731
|
-
}
|
|
732
|
-
if (name) {
|
|
733
|
-
return { name, enabled: false };
|
|
734
|
-
}
|
|
735
|
-
return null;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
function isInsideOrSamePath(target, root) {
|
|
739
|
-
const targetPaths = comparablePaths(target);
|
|
740
|
-
const rootPaths = comparablePaths(root);
|
|
741
|
-
return targetPaths.some(targetPath => rootPaths.some(rootPath => (
|
|
742
|
-
targetPath === rootPath || targetPath.startsWith(rootPath + path.sep)
|
|
743
|
-
)));
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
function comparablePaths(value) {
|
|
747
|
-
const resolved = path.resolve(String(value || ''));
|
|
748
|
-
const candidates = [resolved];
|
|
749
|
-
try {
|
|
750
|
-
candidates.push(fs.realpathSync.native(resolved));
|
|
751
|
-
} catch (_) {
|
|
752
|
-
// Fall back to the lexical path when the file is not present yet.
|
|
753
|
-
}
|
|
754
|
-
return Array.from(new Set(candidates));
|
|
755
|
-
}
|
|
756
|
-
|
|
757
593
|
function buildTurnStartParams(input = {}, threadId = input.threadId || '') {
|
|
758
594
|
const params = {
|
|
759
595
|
threadId,
|
|
@@ -794,6 +630,10 @@ function runCodexAppServerProcess(input) {
|
|
|
794
630
|
return;
|
|
795
631
|
}
|
|
796
632
|
const childEnv = applyProviderEnvironment(buildCodexHomeEnv(input.env || process.env, {
|
|
633
|
+
isolateRuntimeHome: true,
|
|
634
|
+
enabledCodexOverleafSkillIds: input.enabledCodexOverleafSkillIds,
|
|
635
|
+
enabledCodexLocalSkillIds: input.enabledCodexLocalSkillIds,
|
|
636
|
+
disableCodexOverleafSkillIds: input.disableCodexOverleafSkillIds,
|
|
797
637
|
loadCodexLocalSkills: input.loadCodexLocalSkills !== false,
|
|
798
638
|
loadCodexOverleafSkills: input.loadCodexOverleafSkills !== false,
|
|
799
639
|
installCodexOverleafSkillsTarget: input.installCodexOverleafSkillsTarget === true,
|
|
@@ -821,6 +661,12 @@ function runCodexAppServerProcess(input) {
|
|
|
821
661
|
const assistantMessages = new Map();
|
|
822
662
|
const assistantMessageOrder = [];
|
|
823
663
|
const eventScope = createRunEventScope(() => ({ threadId: activeThreadId, turnId: activeTurnId }));
|
|
664
|
+
const subagentObserver = createNativeSubagentObserver({
|
|
665
|
+
emit: input.emit, request,
|
|
666
|
+
getRoot: () => ({ threadId: activeThreadId, turnId: activeTurnId }),
|
|
667
|
+
ownsParent: params => eventScope.owns(params),
|
|
668
|
+
isStopped: () => settled || stopping
|
|
669
|
+
});
|
|
824
670
|
const readProgressController = createReadProgressController({
|
|
825
671
|
input, request, fail,
|
|
826
672
|
getTurn: () => ({ threadId: activeThreadId, turnId: activeTurnId }),
|
|
@@ -881,6 +727,8 @@ function runCodexAppServerProcess(input) {
|
|
|
881
727
|
fail(new Error(stderr || `codex app-server exited before turn completed with code ${code}`));
|
|
882
728
|
});
|
|
883
729
|
|
|
730
|
+
try { input.onProcessStarted?.(createProcessStopIdentity(child, { processGroup: process.platform !== 'win32' })); }
|
|
731
|
+
catch (error) { fail(error); return; }
|
|
884
732
|
start().catch(fail);
|
|
885
733
|
|
|
886
734
|
async function start() {
|
|
@@ -898,10 +746,6 @@ function runCodexAppServerProcess(input) {
|
|
|
898
746
|
request,
|
|
899
747
|
emit: input.emit
|
|
900
748
|
});
|
|
901
|
-
await applyWorkerSkillStrip({
|
|
902
|
-
input,
|
|
903
|
-
request
|
|
904
|
-
});
|
|
905
749
|
|
|
906
750
|
if (input.threadId) {
|
|
907
751
|
try {
|
|
@@ -991,7 +835,9 @@ function runCodexAppServerProcess(input) {
|
|
|
991
835
|
}
|
|
992
836
|
pending.delete(message.id);
|
|
993
837
|
if (message.error) {
|
|
994
|
-
|
|
838
|
+
const error = new Error(message.error.message || JSON.stringify(message.error));
|
|
839
|
+
if (typeof message.error.code === 'number' || typeof message.error.code === 'string') error.code = message.error.code;
|
|
840
|
+
pendingRequest.reject(error);
|
|
995
841
|
} else {
|
|
996
842
|
if (pendingRequest.method === 'thread/start' || pendingRequest.method === 'thread/resume') {
|
|
997
843
|
activeThreadId = message.result?.thread?.id || message.result?.threadId || pendingRequest.params?.threadId || activeThreadId;
|
|
@@ -1009,7 +855,9 @@ function runCodexAppServerProcess(input) {
|
|
|
1009
855
|
}
|
|
1010
856
|
|
|
1011
857
|
if (message.method) {
|
|
1012
|
-
if (stopping
|
|
858
|
+
if (stopping) return;
|
|
859
|
+
if (subagentObserver.observe(message)) return;
|
|
860
|
+
if (!eventScope.accepts(message.params)) return;
|
|
1013
861
|
if (message.method === 'turn/started') {
|
|
1014
862
|
const threadId = message.params?.thread?.id || message.params?.threadId;
|
|
1015
863
|
if (!activeTurnId && threadId === activeThreadId) activeTurnId = message.params?.turn?.id || message.params?.turnId || '';
|
|
@@ -1029,7 +877,10 @@ function runCodexAppServerProcess(input) {
|
|
|
1029
877
|
if (message.method === 'item/completed' && eventScope.owns(message.params) &&
|
|
1030
878
|
!readProgressController.observe(message.params?.item || {})) return;
|
|
1031
879
|
if (message.method === 'turn/completed' && activeTurnId && (message.params?.turn?.id === activeTurnId || message.params?.turnId === activeTurnId)) {
|
|
1032
|
-
|
|
880
|
+
const turn = message.params?.turn || {};
|
|
881
|
+
const terminalError = getTurnCompletionError(turn);
|
|
882
|
+
if (terminalError) fail(terminalError);
|
|
883
|
+
else succeed(turn);
|
|
1033
884
|
}
|
|
1034
885
|
if (message.method === 'error' && isTransientCodexAppServerError(message.params)) {
|
|
1035
886
|
return;
|
|
@@ -1073,21 +924,31 @@ function runCodexAppServerProcess(input) {
|
|
|
1073
924
|
const item = params.item || {};
|
|
1074
925
|
if (method === 'item/agentMessage/delta') {
|
|
1075
926
|
const itemId = String(params.itemId || item.id || 'current');
|
|
1076
|
-
const
|
|
1077
|
-
|
|
927
|
+
const previous = assistantMessages.get(itemId);
|
|
928
|
+
if (previous?.completed) return;
|
|
929
|
+
setAssistantMessage(itemId, { text: `${previous?.text || ''}${String(params.delta || '')}` });
|
|
1078
930
|
return;
|
|
1079
931
|
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
932
|
+
const terminal = method === 'turn/completed';
|
|
933
|
+
if (terminal && params.turn?.status && params.turn.status !== 'completed') return;
|
|
934
|
+
const items = terminal ? (Array.isArray(params.turn?.items) ? params.turn.items : []) : [item];
|
|
935
|
+
for (const candidate of items) {
|
|
936
|
+
if (candidate?.type !== 'agentMessage' || typeof candidate.text !== 'string') continue;
|
|
937
|
+
setAssistantMessage(String(candidate.id || params.itemId || 'current'), {
|
|
938
|
+
text: candidate.text,
|
|
939
|
+
...(typeof candidate.phase === 'string' ? { phase: candidate.phase } : {}),
|
|
940
|
+
completed: terminal || method === 'item/completed',
|
|
941
|
+
...(terminal ? { authoritative: true } : {})
|
|
942
|
+
});
|
|
1083
943
|
}
|
|
1084
944
|
}
|
|
1085
945
|
|
|
1086
|
-
function setAssistantMessage(itemId,
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
946
|
+
function setAssistantMessage(itemId, update) {
|
|
947
|
+
const previous = assistantMessages.get(itemId);
|
|
948
|
+
// Late deltas or started snapshots cannot overwrite a completed answer.
|
|
949
|
+
if (previous?.completed && update.completed !== true) return;
|
|
950
|
+
if (!previous) assistantMessageOrder.push(itemId);
|
|
951
|
+
assistantMessages.set(itemId, { text: '', phase: '', completed: false, ...previous, ...update });
|
|
1091
952
|
}
|
|
1092
953
|
|
|
1093
954
|
function publishActiveTurnControl() {
|
|
@@ -1124,19 +985,27 @@ function runCodexAppServerProcess(input) {
|
|
|
1124
985
|
});
|
|
1125
986
|
}
|
|
1126
987
|
|
|
1127
|
-
function succeed() {
|
|
988
|
+
function succeed(turn = {}) {
|
|
1128
989
|
if (settled || stopping) {
|
|
1129
990
|
return;
|
|
1130
991
|
}
|
|
1131
|
-
|
|
992
|
+
stopping = true;
|
|
1132
993
|
const turnEndedError = new Error('Codex turn ended before the pending app-server request completed.');
|
|
1133
994
|
turnEndedError.code = 'codex_turn_ended';
|
|
1134
995
|
rejectPendingRequests(pending, turnEndedError);
|
|
1135
996
|
cleanup();
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
997
|
+
const result = {
|
|
998
|
+
assistantMessage: buildFinalAssistantMessage(assistantMessages, assistantMessageOrder, {
|
|
999
|
+
turnCompleted: turn.status === undefined || turn.status === 'completed'
|
|
1000
|
+
}),
|
|
1139
1001
|
threadId: activeThreadId
|
|
1002
|
+
};
|
|
1003
|
+
return stopCodexAppServer(child, { processGroup: process.platform !== 'win32' }).then(() => {
|
|
1004
|
+
settled = true;
|
|
1005
|
+
resolve(result);
|
|
1006
|
+
}, error => {
|
|
1007
|
+
settled = true;
|
|
1008
|
+
reject(error);
|
|
1140
1009
|
});
|
|
1141
1010
|
}
|
|
1142
1011
|
|
|
@@ -1155,6 +1024,7 @@ function runCodexAppServerProcess(input) {
|
|
|
1155
1024
|
}
|
|
1156
1025
|
|
|
1157
1026
|
function cleanup() {
|
|
1027
|
+
subagentObserver.close();
|
|
1158
1028
|
timeout.cancel();
|
|
1159
1029
|
idleWatchdog.cancel();
|
|
1160
1030
|
input.signal?.removeEventListener('abort', onAbort);
|
|
@@ -1402,21 +1272,29 @@ function tokenizeShellCommand(command) {
|
|
|
1402
1272
|
return tokens;
|
|
1403
1273
|
}
|
|
1404
1274
|
|
|
1405
|
-
function buildFinalAssistantMessage(messages = new Map(), order = []) {
|
|
1275
|
+
function buildFinalAssistantMessage(messages = new Map(), order = [], options = {}) {
|
|
1276
|
+
const ids = [...new Set([...order, ...messages.keys()])];
|
|
1277
|
+
const records = ids.map(id => messages.get(id)).filter(value => value !== undefined);
|
|
1278
|
+
if (records.some(value => value && typeof value === 'object')) {
|
|
1279
|
+
const completed = records.filter(value => value?.completed === true);
|
|
1280
|
+
const authoritative = completed.filter(value => value.authoritative === true);
|
|
1281
|
+
const candidates = authoritative.length ? authoritative : completed;
|
|
1282
|
+
// Never join independent messages: an abandoned math/code delimiter in
|
|
1283
|
+
// one item must not consume the following final answer.
|
|
1284
|
+
const final = candidates.filter(value => value.phase === 'final_answer').at(-1);
|
|
1285
|
+
const compatible = candidates.filter(value => !value.phase && cleanAssistantMessage(value.text)).at(-1);
|
|
1286
|
+
if (final || compatible) return cleanAssistantMessage((final || compatible).text);
|
|
1287
|
+
// Older app-servers may emit only deltas followed by turn/completed.
|
|
1288
|
+
// A successful turn can finalize its last legacy item, never concatenate
|
|
1289
|
+
// earlier fragments or promote an explicitly phased unfinished message.
|
|
1290
|
+
const legacy = options.turnCompleted === true && completed.length === 0
|
|
1291
|
+
&& records.every(value => !value?.phase)
|
|
1292
|
+
? records.filter(value => cleanAssistantMessage(value?.text)).at(-1) : null;
|
|
1293
|
+
return cleanAssistantMessage(legacy?.text);
|
|
1294
|
+
}
|
|
1295
|
+
// Preserve the exported helper's legacy string-only input contract.
|
|
1406
1296
|
const values = [];
|
|
1407
|
-
const
|
|
1408
|
-
const ids = order.length ? order : Array.from(messages.keys());
|
|
1409
|
-
|
|
1410
|
-
for (const id of ids) {
|
|
1411
|
-
seenIds.add(id);
|
|
1412
|
-
addAssistantMessage(values, messages.get(id));
|
|
1413
|
-
}
|
|
1414
|
-
for (const [id, value] of messages) {
|
|
1415
|
-
if (!seenIds.has(id)) {
|
|
1416
|
-
addAssistantMessage(values, value);
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
|
|
1297
|
+
for (const value of records) addAssistantMessage(values, value);
|
|
1420
1298
|
return values.join('\n\n');
|
|
1421
1299
|
}
|
|
1422
1300
|
|
|
@@ -1438,6 +1316,10 @@ function emitCodexEvent(emit, type, title, detail = {}, status = 'running') {
|
|
|
1438
1316
|
}
|
|
1439
1317
|
|
|
1440
1318
|
function inferNotificationStatus(message) {
|
|
1319
|
+
if (message.method === 'turn/completed') {
|
|
1320
|
+
const error = getTurnCompletionError(message.params?.turn || {});
|
|
1321
|
+
if (error) return error.code === 'codex_cancelled' ? 'cancelled' : 'failed';
|
|
1322
|
+
}
|
|
1441
1323
|
if (message.method === 'error' && isTransientCodexAppServerError(message.params)) {
|
|
1442
1324
|
return 'warning';
|
|
1443
1325
|
}
|
|
@@ -1447,6 +1329,19 @@ function inferNotificationStatus(message) {
|
|
|
1447
1329
|
return 'running';
|
|
1448
1330
|
}
|
|
1449
1331
|
|
|
1332
|
+
function getTurnCompletionError(turn) {
|
|
1333
|
+
const status = turn.status;
|
|
1334
|
+
// Older peers omit status; explicit error evidence still prevents success.
|
|
1335
|
+
if ((status === undefined || status === 'completed') && turn.error == null) return null;
|
|
1336
|
+
const interrupted = status === 'interrupted';
|
|
1337
|
+
const invalid = status !== undefined && !['completed', 'failed', 'interrupted'].includes(status);
|
|
1338
|
+
const error = new Error(extractCodexAppServerErrorMessage(turn) || (interrupted
|
|
1339
|
+
? 'Codex turn was interrupted.' : invalid ? 'Codex turn ended with an invalid terminal status.' : 'Codex turn failed.'));
|
|
1340
|
+
error.code = interrupted ? 'codex_cancelled' : invalid ? 'codex_turn_status_invalid' : 'codex_turn_failed';
|
|
1341
|
+
error.turnStatus = status;
|
|
1342
|
+
return error;
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1450
1345
|
function isTransientCodexAppServerError(params = {}) {
|
|
1451
1346
|
const message = extractCodexAppServerErrorMessage(params);
|
|
1452
1347
|
return /^Reconnecting(?:\.\.\.|…)?\s+\d+\s*\/\s*\d+\.?$/i.test(message);
|
|
@@ -1480,9 +1375,7 @@ function isUnsupportedReasoningSummaryError(error) {
|
|
|
1480
1375
|
return /unsupported_parameter/i.test(message) && /reasoning\.summary|summary/i.test(message);
|
|
1481
1376
|
}
|
|
1482
1377
|
|
|
1483
|
-
|
|
1484
|
-
return String(value || '').trim();
|
|
1485
|
-
}
|
|
1378
|
+
const cleanAssistantMessage = value => String(value || '').trim();
|
|
1486
1379
|
|
|
1487
1380
|
module.exports = {
|
|
1488
1381
|
applyCodexSkillIsolation,
|