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
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { REFERENCE_LIMITS } = require('../../extension/src/shared/writingStyle');
|
|
4
|
+
const WRITING_STYLE_ATTACHMENT_QUOTAS = Object.freeze({
|
|
5
|
+
maxAttachmentCount: REFERENCE_LIMITS.maxSources,
|
|
6
|
+
maxAttachmentBytes: REFERENCE_LIMITS.maxPdfBytes,
|
|
7
|
+
maxAttachmentTotalBytes: REFERENCE_LIMITS.maxAttachmentTotalBytes
|
|
8
|
+
});
|
|
9
|
+
|
|
3
10
|
const NATIVE_REQUEST_QUOTAS = Object.freeze({
|
|
4
11
|
maxProjectFiles: 1000,
|
|
5
12
|
maxProjectTextBytes: 32 * 1024 * 1024,
|
|
@@ -21,7 +28,7 @@ function validateNativeRequestQuotas(request = {}) {
|
|
|
21
28
|
validateOperationListQuota(params.fileOverlays, 'fileOverlays'),
|
|
22
29
|
validateFilePayloadQuota(params.fileOverlays, 'fileOverlays'),
|
|
23
30
|
validateCompileLogQuota(params),
|
|
24
|
-
validateAttachmentQuota(params.attachments),
|
|
31
|
+
validateAttachmentQuota(params.attachments, params.writingStyleBuild ? WRITING_STYLE_ATTACHMENT_QUOTAS : NATIVE_REQUEST_QUOTAS),
|
|
25
32
|
validateSkillContentQuota(params.skillContent)
|
|
26
33
|
]);
|
|
27
34
|
case 'mirror.sync':
|
|
@@ -211,27 +218,27 @@ function validateCompileLogQuota(params = {}) {
|
|
|
211
218
|
: null;
|
|
212
219
|
}
|
|
213
220
|
|
|
214
|
-
function validateAttachmentQuota(attachments) {
|
|
221
|
+
function validateAttachmentQuota(attachments, quotas = NATIVE_REQUEST_QUOTAS) {
|
|
215
222
|
const items = Array.isArray(attachments) ? attachments : [];
|
|
216
|
-
if (items.length >
|
|
217
|
-
return quotaViolation('attachments',
|
|
223
|
+
if (items.length > quotas.maxAttachmentCount) {
|
|
224
|
+
return quotaViolation('attachments', quotas.maxAttachmentCount, items.length, 'too many attachments');
|
|
218
225
|
}
|
|
219
226
|
|
|
220
227
|
let totalBytes = 0;
|
|
221
228
|
for (const item of items) {
|
|
222
229
|
const bytes = getDeclaredOrEstimatedBinaryBytes(item);
|
|
223
|
-
if (bytes >
|
|
230
|
+
if (bytes > quotas.maxAttachmentBytes) {
|
|
224
231
|
return quotaViolation(
|
|
225
232
|
'attachments.contentBase64',
|
|
226
|
-
|
|
233
|
+
quotas.maxAttachmentBytes,
|
|
227
234
|
bytes,
|
|
228
235
|
'attachment payload is too large'
|
|
229
236
|
);
|
|
230
237
|
}
|
|
231
238
|
totalBytes += bytes;
|
|
232
239
|
}
|
|
233
|
-
return totalBytes >
|
|
234
|
-
? quotaViolation('attachments',
|
|
240
|
+
return totalBytes > quotas.maxAttachmentTotalBytes
|
|
241
|
+
? quotaViolation('attachments', quotas.maxAttachmentTotalBytes, totalBytes, 'attachment payload is too large')
|
|
235
242
|
: null;
|
|
236
243
|
}
|
|
237
244
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const processStopBarrier = require('./processStopBarrier');
|
|
4
|
+
const { logDebug } = require('./debugLog');
|
|
5
|
+
const active = new Set();
|
|
6
|
+
let closingError;
|
|
7
|
+
|
|
8
|
+
// Shutdown ownership is independent of RPC ids: absent/reused ids must not
|
|
9
|
+
// hide a live run from transport shutdown or its durable quarantine.
|
|
10
|
+
function register({ controller, projectKey, rootDir }) {
|
|
11
|
+
let resolveDone;
|
|
12
|
+
const entry = { controller, projectKey, rootDir, processes: [], done: new Promise(resolve => { resolveDone = resolve; }) };
|
|
13
|
+
active.add(entry);
|
|
14
|
+
if (closingError) controller.abort(closingError);
|
|
15
|
+
return {
|
|
16
|
+
trackProcess(identity) {
|
|
17
|
+
if (!Number.isInteger(identity?.processId) || identity.processId <= 0) return;
|
|
18
|
+
entry.processes.push(identity);
|
|
19
|
+
if (closingError) quarantine(entry, identity);
|
|
20
|
+
},
|
|
21
|
+
complete() {
|
|
22
|
+
active.delete(entry);
|
|
23
|
+
try {
|
|
24
|
+
if (entry.processes.some(identity => identity.quarantined)) processStopBarrier.isBlocked(projectKey, rootDir);
|
|
25
|
+
} catch (error) { logDebug('native_transport.quarantine_cleanup_failed', { projectKey, message: error.message }); }
|
|
26
|
+
finally { resolveDone(); }
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function abortAllActiveOperations(reason = 'Native messaging transport disconnected.') {
|
|
32
|
+
closingError = new Error(String(reason || 'Native messaging transport disconnected.'));
|
|
33
|
+
closingError.code = 'native_transport_closed';
|
|
34
|
+
const entries = Array.from(active);
|
|
35
|
+
for (const entry of entries) {
|
|
36
|
+
if (!entry.controller.signal.aborted) entry.controller.abort(closingError);
|
|
37
|
+
}
|
|
38
|
+
return Promise.all(entries.map(entry => entry.done));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function quarantineActiveOperations() {
|
|
42
|
+
const failures = [];
|
|
43
|
+
for (const entry of active) {
|
|
44
|
+
// A preparing run has no process to quarantine. Its aborted signal is
|
|
45
|
+
// checked again after provider preparation and immediately before spawn.
|
|
46
|
+
for (const identity of entry.processes) {
|
|
47
|
+
const failure = quarantine(entry, identity);
|
|
48
|
+
if (failure) failures.push(failure);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return failures;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function quarantine(entry, identity) {
|
|
55
|
+
if (identity.quarantined) return null;
|
|
56
|
+
const error = Object.assign(new Error('Native transport closed before run settlement.'), identity, {
|
|
57
|
+
code: 'codex_process_stop_unconfirmed'
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
processStopBarrier.record(entry.projectKey, entry.rootDir, error);
|
|
61
|
+
if (error.stopBarrierPersistenceError) throw new Error(error.stopBarrierPersistenceError);
|
|
62
|
+
identity.quarantined = true;
|
|
63
|
+
return null;
|
|
64
|
+
} catch (failure) {
|
|
65
|
+
const detail = { projectKey: entry.projectKey, message: failure.message };
|
|
66
|
+
logDebug('native_transport.quarantine_failed', detail);
|
|
67
|
+
return detail;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = { register, abortAllActiveOperations, quarantineActiveOperations };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Shared by project turns and broker workers. Skill-install turns run outside
|
|
4
|
+
// the project mirror and retain their existing installer command policy.
|
|
5
|
+
function formatOverleafWorkspaceRules() {
|
|
6
|
+
return [
|
|
7
|
+
'Overleaf workspace rules (also apply to delegated subagents):',
|
|
8
|
+
'- This directory is a synchronized Overleaf project mirror without .git metadata.',
|
|
9
|
+
'- Do not run Git commands in this mirror, including git status, git diff, git rev-parse, or git init. Do not create .git metadata or search parent directories for a repository.',
|
|
10
|
+
'- Verify changes through direct file reads and searches. Run compilation checks only when needed and permitted by the current task and mode; never compile solely to replace an unavailable Git check.',
|
|
11
|
+
'- The plugin compares the workspace against its synchronized baseline, collects file changes, and handles writeback to Overleaf. No Git-based diff, staging, or commit is required.',
|
|
12
|
+
'- Include these workspace rules in every delegated subagent task so workers follow the same constraints.'
|
|
13
|
+
].join('\n');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = { formatOverleafWorkspaceRules };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// A stop acknowledgement is not proof of process exit. This quarantine survives
|
|
4
|
+
// Native Host restarts and only permits work after positive exit evidence.
|
|
5
|
+
const fs = require('node:fs');
|
|
6
|
+
const path = require('node:path');
|
|
7
|
+
const { getProjectMirror, getDefaultMirrorRoot } = require('./mirrorWorkspace');
|
|
8
|
+
const pending = new Map();
|
|
9
|
+
|
|
10
|
+
function location(projectId, rootDir) {
|
|
11
|
+
const mirror = getProjectMirror(projectId, { rootDir });
|
|
12
|
+
return path.join(path.dirname(mirror.workspacePath), '.codex-stop-barrier.json');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function load(file) {
|
|
16
|
+
let records = [];
|
|
17
|
+
try {
|
|
18
|
+
if (fs.statSync(file).size > 65536) throw new Error('Oversized stop barrier');
|
|
19
|
+
const value = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
20
|
+
if (!Array.isArray(value) || value.length > 64) throw new Error('Invalid stop barrier');
|
|
21
|
+
records = value.map(record => record && typeof record === 'object' ? record : { unknown: true });
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (error.code !== 'ENOENT') records = [{ unknown: true }];
|
|
24
|
+
}
|
|
25
|
+
// Other Hosts can publish a barrier while this Host is already alive. Keep
|
|
26
|
+
// in-memory callbacks and failed writes, but never cache an empty disk read.
|
|
27
|
+
const key = ({ isStopped, ...record }) => JSON.stringify(record);
|
|
28
|
+
const merged = new Map(records.map(record => [key(record), record]));
|
|
29
|
+
for (const record of pending.get(file) || []) {
|
|
30
|
+
if (typeof record.isStopped === 'function' || record.persistenceFailed) merged.set(key(record), record);
|
|
31
|
+
}
|
|
32
|
+
records = Array.from(merged.values());
|
|
33
|
+
pending.set(file, records);
|
|
34
|
+
return records;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function persist(file, records) {
|
|
38
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
39
|
+
const temp = file + '.' + process.pid + '.tmp';
|
|
40
|
+
const fd = fs.openSync(temp, 'w', 0o600);
|
|
41
|
+
try {
|
|
42
|
+
fs.writeFileSync(fd, JSON.stringify(records.map(({ isStopped, ...record }) => record)));
|
|
43
|
+
fs.fsyncSync(fd);
|
|
44
|
+
} finally { fs.closeSync(fd); }
|
|
45
|
+
fs.renameSync(temp, file);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function stopped(record) {
|
|
49
|
+
if (typeof record.isStopped === 'function') {
|
|
50
|
+
try { return record.isStopped() === true; } catch (_) { return false; }
|
|
51
|
+
}
|
|
52
|
+
// Recovered POSIX process-group identities can be checked without signalling
|
|
53
|
+
// or killing anything. Unknown/Windows trees remain quarantined.
|
|
54
|
+
if (record.processGroup !== true || record.platform !== process.platform
|
|
55
|
+
|| !Number.isInteger(record.processId) || record.processId <= 0) return false;
|
|
56
|
+
try { process.kill(-record.processId, 0); return false; }
|
|
57
|
+
catch (error) { return error.code === 'ESRCH'; }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function record(projectId, rootDir, error) {
|
|
61
|
+
const file = location(projectId, rootDir);
|
|
62
|
+
const records = load(file);
|
|
63
|
+
const entry = {
|
|
64
|
+
processId: error.processId, processGroup: error.processGroup === true,
|
|
65
|
+
platform: process.platform, createdAt: new Date().toISOString(),
|
|
66
|
+
isStopped: error.isStopped
|
|
67
|
+
};
|
|
68
|
+
records.push(entry);
|
|
69
|
+
try { persist(file, records); }
|
|
70
|
+
catch (failure) {
|
|
71
|
+
Object.defineProperty(entry, 'persistenceFailed', { value: true });
|
|
72
|
+
error.stopBarrierPersistenceError = failure.message;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function isBlocked(projectId, rootDir) {
|
|
77
|
+
const file = location(projectId, rootDir);
|
|
78
|
+
const records = load(file);
|
|
79
|
+
if (!records.length) return false;
|
|
80
|
+
const remaining = records.filter(value => !stopped(value));
|
|
81
|
+
if (remaining.length !== records.length) {
|
|
82
|
+
try {
|
|
83
|
+
persist(file, remaining);
|
|
84
|
+
pending.set(file, remaining);
|
|
85
|
+
} catch (_) { return true; }
|
|
86
|
+
}
|
|
87
|
+
return remaining.length > 0;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Update safety observes the existing project quarantine. It neither searches
|
|
91
|
+
// unrelated OS processes nor mutates a project's recovery records.
|
|
92
|
+
function getBlockedProjectCount(rootDir, options = {}) {
|
|
93
|
+
const root = path.resolve(rootDir || getDefaultMirrorRoot(options));
|
|
94
|
+
const files = new Set();
|
|
95
|
+
let unknown = 0;
|
|
96
|
+
try {
|
|
97
|
+
for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
|
|
98
|
+
if (entry.isDirectory()) files.add(path.join(root, entry.name, '.codex-stop-barrier.json'));
|
|
99
|
+
else if (entry.isSymbolicLink()) unknown += 1;
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
if (error.code !== 'ENOENT') unknown += 1;
|
|
103
|
+
}
|
|
104
|
+
// Include failed persistence owned by this Host, even if its directory was
|
|
105
|
+
// never created. A disk inventory alone cannot release that quarantine.
|
|
106
|
+
for (const file of pending.keys()) {
|
|
107
|
+
if (path.dirname(path.dirname(file)) === root) files.add(file);
|
|
108
|
+
}
|
|
109
|
+
for (const file of files) {
|
|
110
|
+
if (load(file).some(value => !stopped(value))) unknown += 1;
|
|
111
|
+
}
|
|
112
|
+
return unknown;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = { record, isBlocked, getBlockedProjectCount };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Canonical project names stay literal. Reject names the local filesystem would
|
|
4
|
+
// reinterpret instead of attempting to escape, trim or rename them.
|
|
5
|
+
function isRepresentableProjectPath(value, platform = process.platform) {
|
|
6
|
+
if (typeof value !== 'string' || !value) return false;
|
|
7
|
+
if (platform !== 'win32') return true;
|
|
8
|
+
return value.split('/').every(part => part && part !== '.' && part !== '..'
|
|
9
|
+
&& part.length <= 255 && !/[<>:"\\|?*\u0000-\u001f]/.test(part) && !/[ .]$/.test(part)
|
|
10
|
+
&& !/^(?:con|prn|aux|nul|conin\$|conout\$|com[1-9¹²³]|lpt[1-9¹²³])(?:\.|$)/i.test(part));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function assertProjectPathsForPlatform(paths, platform = process.platform) {
|
|
14
|
+
const identities = new Map();
|
|
15
|
+
for (const value of paths) {
|
|
16
|
+
let valid = isRepresentableProjectPath(value, platform);
|
|
17
|
+
if (valid && platform === 'win32') {
|
|
18
|
+
const parts = value.split('/');
|
|
19
|
+
for (let index = 1; index <= parts.length; index += 1) {
|
|
20
|
+
const literal = parts.slice(0, index).join('/'), key = literal.toLowerCase();
|
|
21
|
+
if (identities.has(key) && identities.get(key) !== literal) valid = false;
|
|
22
|
+
identities.set(key, literal);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (!valid) throw Object.assign(new Error(`Project path cannot be represented faithfully on ${platform}: ${value}`),
|
|
26
|
+
{ code: 'project_path_unrepresentable', path: value });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = { isRepresentableProjectPath, assertProjectPathsForPlatform };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { providerError } = require('./providerProfile');
|
|
4
|
+
const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
|
|
5
|
+
const BODY_HEADERS = ['content-encoding', 'content-language', 'content-location', 'content-type', 'content-length'];
|
|
6
|
+
|
|
7
|
+
function carriesEndpointCredentials(headers, launch) {
|
|
8
|
+
const namedHeader = String(launch.apiKeyHeaderName || '').toLowerCase();
|
|
9
|
+
return [...headers].some(([name, value]) => value && (
|
|
10
|
+
name === namedHeader
|
|
11
|
+
|| /(?:^|[-_])(?:authorization|auth|api[-_]?key|token|secret|cookie|credential|password|signature)(?:$|[-_])/i.test(name)
|
|
12
|
+
|| launch.apiKey && value.includes(launch.apiKey)
|
|
13
|
+
));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Fetch's method/body redirect rules remain intact. Credentials configured for
|
|
17
|
+
// this endpoint never authorize a request to a different origin.
|
|
18
|
+
async function fetchProvider(url, options, launch = {}) {
|
|
19
|
+
let current = new URL(url);
|
|
20
|
+
let method = String(options.method || 'GET').toUpperCase();
|
|
21
|
+
let body = options.body;
|
|
22
|
+
const headers = new Headers(options.headers);
|
|
23
|
+
const credentialed = carriesEndpointCredentials(headers, launch);
|
|
24
|
+
for (let redirects = 0; ; redirects += 1) {
|
|
25
|
+
const response = await fetch(current, { ...options, method, body, headers, redirect: 'manual' });
|
|
26
|
+
const location = response.headers.get('location');
|
|
27
|
+
if (!REDIRECT_STATUSES.has(response.status) || location === null) return response;
|
|
28
|
+
await response.body?.cancel().catch(() => {});
|
|
29
|
+
if (redirects >= 20) throw providerError('provider_upstream_error', 'The provider exceeded the redirect limit.');
|
|
30
|
+
let next;
|
|
31
|
+
try { next = new URL(location, current); }
|
|
32
|
+
catch (_) { throw providerError('provider_upstream_error', 'The provider returned an invalid redirect.'); }
|
|
33
|
+
if (!['http:', 'https:'].includes(next.protocol) || next.username || next.password) {
|
|
34
|
+
throw providerError('provider_upstream_error', 'The provider returned an unsupported redirect.');
|
|
35
|
+
}
|
|
36
|
+
if (credentialed && next.origin !== current.origin) {
|
|
37
|
+
throw providerError('provider_upstream_error', 'The provider redirected to a different origin; endpoint credentials were not forwarded.');
|
|
38
|
+
}
|
|
39
|
+
if ((response.status === 301 || response.status === 302) && method === 'POST'
|
|
40
|
+
|| response.status === 303 && method !== 'GET' && method !== 'HEAD') {
|
|
41
|
+
method = 'GET';
|
|
42
|
+
body = undefined;
|
|
43
|
+
for (const name of BODY_HEADERS) headers.delete(name);
|
|
44
|
+
}
|
|
45
|
+
current = next;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Preserve ordinary Response.text()/json() capacity and UTF-8 semantics while
|
|
50
|
+
// reporting each body chunk to the existing idle lifecycle. Compact/SSE limits
|
|
51
|
+
// remain in their own readers; this does not introduce a new response cap.
|
|
52
|
+
async function readProviderText(response, onActivity = () => {}) {
|
|
53
|
+
if (!response.body) return '';
|
|
54
|
+
const reader = response.body.getReader();
|
|
55
|
+
const decoder = new TextDecoder();
|
|
56
|
+
const chunks = [];
|
|
57
|
+
let complete = false;
|
|
58
|
+
try {
|
|
59
|
+
while (true) {
|
|
60
|
+
const { done, value } = await reader.read();
|
|
61
|
+
if (done) break;
|
|
62
|
+
onActivity();
|
|
63
|
+
chunks.push(decoder.decode(value, { stream: true }));
|
|
64
|
+
}
|
|
65
|
+
complete = true;
|
|
66
|
+
chunks.push(decoder.decode());
|
|
67
|
+
return chunks.join('');
|
|
68
|
+
} finally {
|
|
69
|
+
if (!complete) await reader.cancel().catch(() => {});
|
|
70
|
+
reader.releaseLock();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function readProviderJson(response, onActivity) {
|
|
75
|
+
const text = await readProviderText(response, onActivity);
|
|
76
|
+
try { return JSON.parse(text); }
|
|
77
|
+
catch (_) { throw providerError('provider_response_invalid', 'The provider returned an invalid JSON response.'); }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = { fetchProvider, readProviderText, readProviderJson };
|
|
@@ -79,9 +79,10 @@ function buildModelEntry(model, launch, index) {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function normalizeEfforts(...values) {
|
|
82
|
-
const allowed = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh']);
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
const allowed = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']);
|
|
83
|
+
// Explicit model capabilities must not inherit the selected model's levels.
|
|
84
|
+
const configured = values.find(value => Array.isArray(value) && value.length) || [];
|
|
85
|
+
const normalized = configured
|
|
85
86
|
.map(value => String(value || '').trim().toLowerCase())
|
|
86
87
|
.filter(value => allowed.has(value));
|
|
87
88
|
return Array.from(new Set(normalized.length ? normalized : ['none']));
|
|
@@ -7,7 +7,7 @@ const {
|
|
|
7
7
|
} = require('./providerReasoning');
|
|
8
8
|
|
|
9
9
|
const ALLOWED_WIRE_APIS = new Set(['auto', 'responses', 'chat', 'anthropic']);
|
|
10
|
-
const ALLOWED_REASONING_EFFORTS = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh']);
|
|
10
|
+
const ALLOWED_REASONING_EFFORTS = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']);
|
|
11
11
|
const ALLOWED_UPSTREAM_RESPONSE_MODES = new Set(['auto', 'streaming', 'buffered']);
|
|
12
12
|
const ALLOWED_AUTH_MODES = new Set(['bearer', 'x-api-key', 'api-key', 'custom', 'none']);
|
|
13
13
|
const ALLOWED_INPUT_MODALITIES = new Set(['text', 'image']);
|
|
@@ -65,7 +65,8 @@ function normalizeProviderDraft(value = {}) {
|
|
|
65
65
|
anthropicThinkingMode: normalizeAnthropicThinkingMode(value.anthropicThinkingMode),
|
|
66
66
|
anthropicPromptCaching: value.anthropicPromptCaching === true,
|
|
67
67
|
impersonateClaudeCode: value.impersonateClaudeCode === true,
|
|
68
|
-
maxOutputTokens: normalizeMaxOutputTokens(value.maxOutputTokens)
|
|
68
|
+
maxOutputTokens: normalizeMaxOutputTokens(value.maxOutputTokens),
|
|
69
|
+
outputBudgetVersion: 1
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
72
|
|
|
@@ -93,6 +94,9 @@ function normalizeModels(values) {
|
|
|
93
94
|
upstreamResponseMode: normalizeUpstreamResponseMode(value?.upstreamResponseMode, true),
|
|
94
95
|
resolvedUpstreamResponseMode: normalizeUpstreamResponseMode(value?.resolvedUpstreamResponseMode, false),
|
|
95
96
|
contextWindow: normalizeContextWindow(value?.contextWindow),
|
|
97
|
+
maxOutputTokens: normalizeModelOutputTokens(value?.maxOutputTokens),
|
|
98
|
+
reasoningAdapter: value?.reasoningAdapter ? normalizeReasoningAdapter(value.reasoningAdapter) : '',
|
|
99
|
+
reasoningCapability: value?.reasoningCapability ? normalizeReasoningCapability(value.reasoningCapability) : '',
|
|
96
100
|
supportsParallelToolCalls: value?.supportsParallelToolCalls === true,
|
|
97
101
|
inputModalities: normalizeInputModalities(value?.inputModalities),
|
|
98
102
|
baseInstructions: normalizeOptionalText(value?.baseInstructions, 8000)
|
|
@@ -101,6 +105,15 @@ function normalizeModels(values) {
|
|
|
101
105
|
return result;
|
|
102
106
|
}
|
|
103
107
|
|
|
108
|
+
function normalizeModelOutputTokens(value) {
|
|
109
|
+
if (value === undefined || value === null || value === '') return null;
|
|
110
|
+
const number = Number(value);
|
|
111
|
+
if (!Number.isSafeInteger(number) || number < 256 || number > 65536) {
|
|
112
|
+
throw providerError('provider_configuration_invalid', 'Model output limit must be an integer between 256 and 65536.');
|
|
113
|
+
}
|
|
114
|
+
return number;
|
|
115
|
+
}
|
|
116
|
+
|
|
104
117
|
function normalizeBaseUrl(value) {
|
|
105
118
|
const text = normalizeRequiredText(value, 'provider_base_url_invalid', 'Base URL is required.', 2048);
|
|
106
119
|
let parsed;
|
|
@@ -233,6 +246,7 @@ function sanitizeProfile(profile, hasSecret) {
|
|
|
233
246
|
anthropicPromptCaching: profile.anthropicPromptCaching === true,
|
|
234
247
|
impersonateClaudeCode: profile.impersonateClaudeCode === true,
|
|
235
248
|
maxOutputTokens: normalizeMaxOutputTokens(profile.maxOutputTokens),
|
|
249
|
+
outputBudgetVersion: 1,
|
|
236
250
|
hasSecret: Boolean(hasSecret),
|
|
237
251
|
secretUpdatedAt: profile.secretUpdatedAt || 0,
|
|
238
252
|
endpointDisclosureHost: profile.endpointDisclosureHost || '',
|
|
@@ -407,7 +421,7 @@ function normalizeUpstreamResponseMode(value, allowAuto) {
|
|
|
407
421
|
|
|
408
422
|
function normalizeMaxOutputTokens(value) {
|
|
409
423
|
const number = Number(value);
|
|
410
|
-
if (!Number.isFinite(number)
|
|
424
|
+
if (!Number.isFinite(number)) return 65536;
|
|
411
425
|
return Math.min(65536, Math.max(256, Math.floor(number)));
|
|
412
426
|
}
|
|
413
427
|
|
|
@@ -12,8 +12,7 @@ const REASONING_ADAPTERS = new Set([
|
|
|
12
12
|
'reasoning_split'
|
|
13
13
|
]);
|
|
14
14
|
const REASONING_CAPABILITIES = new Set(['auto', 'none', 'toggle', 'effort']);
|
|
15
|
-
const REASONING_EFFORTS = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh']);
|
|
16
|
-
const DEEPSEEK_MAX_REASONING_OUTPUT_TOKENS = 65536;
|
|
15
|
+
const REASONING_EFFORTS = new Set(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']);
|
|
17
16
|
|
|
18
17
|
function normalizeReasoningAdapter(value) {
|
|
19
18
|
const normalized = String(value || '').trim().toLowerCase();
|
|
@@ -67,6 +66,10 @@ function getSupportedReasoningEfforts(profile = {}, model = {}) {
|
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
function getReasoningControl(profile = {}, model = {}) {
|
|
69
|
+
profile = { ...profile,
|
|
70
|
+
reasoningAdapter: model.reasoningAdapter || profile.reasoningAdapter,
|
|
71
|
+
reasoningCapability: model.reasoningCapability || profile.reasoningCapability
|
|
72
|
+
};
|
|
70
73
|
const explicit = Array.isArray(model.reasoningEfforts)
|
|
71
74
|
? model.reasoningEfforts.map(normalizeEffort).filter(Boolean)
|
|
72
75
|
: [];
|
|
@@ -85,7 +88,7 @@ function getReasoningControl(profile = {}, model = {}) {
|
|
|
85
88
|
}
|
|
86
89
|
if (adapter === 'deepseek') {
|
|
87
90
|
return {
|
|
88
|
-
efforts: ['none', 'high', '
|
|
91
|
+
efforts: ['none', 'high', 'max'],
|
|
89
92
|
defaultEffort: 'high',
|
|
90
93
|
presentation: 'deepseek'
|
|
91
94
|
};
|
|
@@ -134,11 +137,11 @@ function applyReasoningControl(chatBody, responsesRequest = {}, launch = {}) {
|
|
|
134
137
|
if (adapter === 'deepseek') {
|
|
135
138
|
chatBody.thinking = { type: enabled ? 'enabled' : 'disabled' };
|
|
136
139
|
if (enabled) {
|
|
137
|
-
chatBody.reasoning_effort =
|
|
140
|
+
chatBody.reasoning_effort = ['xhigh', 'max'].includes(requested) ? 'max' : 'high';
|
|
138
141
|
}
|
|
139
142
|
} else if (adapter === 'reasoning_effort') {
|
|
140
143
|
if (enabled) {
|
|
141
|
-
chatBody.reasoning_effort = clampEffort(requested,
|
|
144
|
+
chatBody.reasoning_effort = clampEffort(requested, true);
|
|
142
145
|
}
|
|
143
146
|
} else if (adapter === 'openrouter') {
|
|
144
147
|
chatBody.reasoning = { effort: clampEffort(requested, true) };
|
|
@@ -161,12 +164,8 @@ function resolveReasoningMaxOutputTokens(value, responsesRequest = {}, launch =
|
|
|
161
164
|
if (!Number.isFinite(number)) {
|
|
162
165
|
return value;
|
|
163
166
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const adapter = resolveReasoningAdapter(launch, modelId || launch.modelId);
|
|
167
|
-
return adapter === 'deepseek' && effort === 'xhigh'
|
|
168
|
-
? Math.max(normalized, DEEPSEEK_MAX_REASONING_OUTPUT_TOKENS)
|
|
169
|
-
: normalized;
|
|
167
|
+
// Reasoning effort cannot silently increase the configured output maximum.
|
|
168
|
+
return Math.max(1, Math.floor(number));
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
function requiresReasoningContentReplay(launch = {}, modelId = '') {
|
|
@@ -92,6 +92,7 @@ async function testProvider(params, env, emit = () => {}, externalSignal = null)
|
|
|
92
92
|
}, totalBudgetMs);
|
|
93
93
|
const onExternalAbort = () => controller.abort();
|
|
94
94
|
externalSignal?.addEventListener?.('abort', onExternalAbort, { once: true });
|
|
95
|
+
if (externalSignal?.aborted) onExternalAbort();
|
|
95
96
|
activeTests.get(operationId)?.abort?.();
|
|
96
97
|
activeTests.set(operationId, controller);
|
|
97
98
|
const protocols = draft.wireApiPreference === 'auto'
|