codex-overleaf-link 2.5.0 → 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 +38 -26
- package/README.zh-CN.md +39 -27
- package/extension/bootstrap/background.js +52 -9
- package/extension/bootstrap/manifest.template.json +1 -1
- package/extension/bootstrap/popup.html +1 -0
- package/extension/bootstrap/popupFallback.js +55 -0
- package/extension/bootstrap/updateStatus.js +1 -0
- package/extension/src/background.js +206 -53
- package/extension/src/backgroundBootstrapMigration.js +181 -0
- package/extension/src/backgroundSharedSessions.js +74 -14
- package/extension/src/backgroundUpdateCoordinator.js +118 -21
- package/extension/src/backgroundUpdateSafety.js +173 -0
- package/extension/src/content/activeTurnControl.js +8 -2
- package/extension/src/content/applyResultFormatters.js +46 -73
- package/extension/src/content/assetTransferBroker.js +72 -14
- package/extension/src/content/composerAttachments.js +93 -45
- package/extension/src/content/composerPanel.js +18 -0
- package/extension/src/content/contentRuntime.js +661 -676
- package/extension/src/content/diagnosticsController.js +122 -96
- package/extension/src/content/diagnosticsExport.js +19 -5
- package/extension/src/content/diagnosticsPanel.js +30 -0
- package/extension/src/content/directoryCleanupRecovery.js +54 -0
- package/extension/src/content/generated/content.bundle.js +6879 -2786
- package/extension/src/content/generated/content.bundle.meta.json +11 -3
- package/extension/src/content/globalPreferencesController.js +1 -1
- package/extension/src/content/legacyGlobalRegistry.js +6 -0
- package/extension/src/content/localSkillsPanel.js +102 -12
- package/extension/src/content/markdownText.js +5 -6
- package/extension/src/content/modelPicker.js +7 -4
- 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 +15 -2
- package/extension/src/content/panelMaintenance.js +40 -12
- package/extension/src/content/panelRenderer.js +6 -0
- 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 +46 -8
- package/extension/src/content/providerSettingsDialog.js +71 -13
- package/extension/src/content/recentProjects.js +11 -5
- package/extension/src/content/runActivitySummary.js +40 -6
- package/extension/src/content/runCompletionMeta.js +344 -0
- package/extension/src/content/runController.js +37 -14
- package/extension/src/content/runFailureNotice.js +21 -12
- package/extension/src/content/runGuidanceController.js +72 -27
- package/extension/src/content/runGuidanceView.js +59 -10
- package/extension/src/content/runQueueScheduler.js +148 -42
- package/extension/src/content/runRecoveryActions.js +146 -0
- package/extension/src/content/runResultActions.js +8 -125
- package/extension/src/content/runReviewController.js +574 -0
- package/extension/src/content/runScrollLayout.js +21 -2
- package/extension/src/content/runTimelineView.js +146 -153
- package/extension/src/content/scopedPersistencePanelState.js +51 -6
- package/extension/src/content/selectionContextView.js +1 -1
- 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/settingsPanel.js +7 -3
- package/extension/src/content/settingsWorkbench.js +5 -0
- package/extension/src/content/sharedSessionViewSync.js +45 -8
- package/extension/src/content/updateIdle.js +4 -1
- package/extension/src/content/updateNotice.js +60 -8
- package/extension/src/content/updateSafetyReceiver.js +58 -0
- package/extension/src/content/writebackController.js +53 -4
- package/extension/src/content/writebackOrchestrator.js +82 -73
- package/extension/src/content/writingStyleSettings.js +35 -11
- package/extension/src/page/binaryAssetUploader.js +136 -14
- package/extension/src/page/fileMover.js +256 -0
- package/extension/src/page/ownedDirectoryCleanup.js +94 -0
- package/extension/src/page/referenceProjects.js +1 -0
- package/extension/src/page/reviewContext.js +113 -0
- package/extension/src/page/saveState.js +6 -4
- package/extension/src/page/snapshotRouter.js +84 -39
- package/extension/src/page/textFileCreator.js +105 -25
- package/extension/src/page/trackedChangeCapture.js +12 -2
- package/extension/src/page/trackedChangeOwnership.js +19 -1
- package/extension/src/page/trackedChangeReplay.js +41 -21
- package/extension/src/page/trackedChangesLifecycle.js +217 -199
- package/extension/src/page/treeOperations.js +7 -10
- package/extension/src/page/updateSafetyProbe.js +41 -0
- package/extension/src/page/writebackReceiptJournal.js +2 -0
- package/extension/src/page/writebackRouter.js +80 -79
- package/extension/src/pageBridge.js +19 -3
- package/extension/src/popup.js +62 -10
- package/extension/src/shared/agentTranscript.js +23 -0
- package/extension/src/shared/auditRecords.js +2 -0
- package/extension/src/shared/compatibility.js +22 -6
- package/extension/src/shared/compileAdapter.js +79 -57
- package/extension/src/shared/composerAttachmentDraft.js +151 -0
- package/extension/src/shared/directoryCleanupProof.js +43 -0
- package/extension/src/shared/failureReasons.js +309 -3
- package/extension/src/shared/globalPreferences.js +30 -13
- package/extension/src/shared/governanceRules.js +4 -37
- package/extension/src/shared/i18n.js +298 -2
- package/extension/src/shared/managedUpdateProjection.js +2 -2
- package/extension/src/shared/nativeRequestIdentity.js +1 -0
- package/extension/src/shared/pageRpcContract.js +5 -4
- package/extension/src/shared/projectFiles.js +21 -44
- package/extension/src/shared/providerProfiles.js +5 -3
- package/extension/src/shared/runInputQueue.js +48 -5
- package/extension/src/shared/selectionContext.js +12 -3
- package/extension/src/shared/sessionState.js +72 -27
- package/extension/src/shared/settlementFacts.js +10 -2
- package/extension/src/shared/sharedSessionBridge.js +37 -14
- package/extension/src/shared/sharedSessionTransfer.js +140 -0
- package/extension/src/shared/staleGuard.js +118 -13
- package/extension/src/shared/storageDb.js +58 -26
- package/extension/src/shared/storageMigration.js +71 -111
- package/extension/src/shared/storageRunActions.js +209 -26
- package/extension/src/shared/subagentActivityModel.js +1 -1
- package/extension/src/shared/undoOperations.js +136 -13
- package/extension/src/shared/updateConsent.js +6 -4
- package/extension/src/shared/updateRuntimeIdentity.js +1 -1
- package/extension/src/shared/writebackIntent.js +16 -0
- package/extension/src/shared/writebackOperationEvidence.js +4 -15
- package/extension/src/shared/writebackSettlement.js +38 -38
- package/extension/styles/panel.css +19 -5
- package/native-host/src/anthropicBridgeRequest.js +4 -2
- 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/codexPromptAssembly.js +31 -12
- package/native-host/src/codexProviderTest.js +24 -26
- package/native-host/src/codexSessionRunner.js +110 -183
- package/native-host/src/codexSessionTiming.js +18 -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 +110 -35
- 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/nativeHelperLifecycle.js +21 -0
- package/native-host/src/nativeHostRegistration.js +33 -0
- package/native-host/src/nativeRunLifecycle.js +71 -0
- package/native-host/src/processStopBarrier.js +42 -7
- package/native-host/src/projectPathPlatform.js +30 -0
- package/native-host/src/providerHttp.js +80 -0
- package/native-host/src/providerProfile.js +4 -2
- package/native-host/src/providerReasoning.js +2 -7
- package/native-host/src/providerRuntime.js +1 -0
- package/native-host/src/providerStore.js +72 -14
- package/native-host/src/responsesPassthroughBridge.js +266 -52
- package/native-host/src/runtimeInstaller.js +21 -1
- package/native-host/src/selectionScope.js +36 -8
- package/native-host/src/subagentAdmission.js +26 -0
- package/native-host/src/subagentBroker.js +79 -66
- package/native-host/src/subagentTelemetry.js +19 -10
- package/native-host/src/subagentWorkspacePath.js +5 -2
- package/native-host/src/taskRunnerRuntime.js +77 -54
- package/native-host/src/tomlStatements.js +140 -0
- package/native-host/src/updateManager.js +297 -39
- package/native-host/src/writingStyleRuntime.js +57 -29
- package/native-host/src/writingStyleStore.js +73 -0
- package/package.json +1 -1
- package/scripts/install-managed.mjs +1 -0
|
@@ -7,10 +7,12 @@ 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
9
|
const { prepareSelectionScope, filterSelectionChanges } = require('./selectionScope');
|
|
10
|
+
const { normalizeSafeProjectPath } = require('../../extension/src/shared/projectFiles');
|
|
10
11
|
const WritingStyleRuntime = require('./writingStyleRuntime');
|
|
11
12
|
const { createRecoveringStyleRunner } = require('./codexModelRecovery');
|
|
12
13
|
const { computeTextPatches } = require('./textPatch');
|
|
13
14
|
const { buildCodexHomeEnv } = require('./codexHome');
|
|
15
|
+
const { applyCodexSkillIsolation } = require('./codexSkillIsolation');
|
|
14
16
|
const { buildCodexSpeedArgs } = require('./codexArgs');
|
|
15
17
|
const { truncateText } = require('./debugLog');
|
|
16
18
|
const {
|
|
@@ -31,6 +33,7 @@ const { applyProviderEnvironment, buildProviderConfigArgs, prepareProviderLaunch
|
|
|
31
33
|
const { buildReadProgressRules, createReadProgressController, createRunEventScope } = require('./readProgressGuard');
|
|
32
34
|
const {
|
|
33
35
|
createCodexIdleWatchdog,
|
|
36
|
+
createProcessStopIdentity,
|
|
34
37
|
createOptionalTimeout,
|
|
35
38
|
getAbortReason,
|
|
36
39
|
parseOptionalPositiveInteger,
|
|
@@ -43,13 +46,13 @@ const PARALLEL_SUBAGENTS_SKILL_ID = 'parallel-subagents';
|
|
|
43
46
|
|
|
44
47
|
const { materializeTurnAttachments } = require('./turnAttachments');
|
|
45
48
|
|
|
46
|
-
async function runCodexSession({ params = {}, env = process.env, emit = () => {}, rootDir, executeCodex, providerLaunch, signal, onControlReady, onStopUnconfirmed } = {}) {
|
|
49
|
+
async function runCodexSession({ params = {}, env = process.env, emit = () => {}, rootDir, executeCodex, providerLaunch, signal, onControlReady, onStopUnconfirmed, onProcessStarted } = {}) {
|
|
47
50
|
throwIfAborted(signal);
|
|
48
51
|
if (params.writingStyleBuild) {
|
|
49
52
|
return WritingStyleRuntime.build({
|
|
50
53
|
params, env, signal, providerLaunch, onControlReady, onStopUnconfirmed,
|
|
51
54
|
execute: createRecoveringStyleRunner({
|
|
52
|
-
execute: executeCodex || runCodexAppServerSession,
|
|
55
|
+
execute: input => (executeCodex || runCodexAppServerSession)({ ...input, onProcessStarted }),
|
|
53
56
|
env, emit, locale: params.locale
|
|
54
57
|
})
|
|
55
58
|
});
|
|
@@ -81,15 +84,20 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
81
84
|
});
|
|
82
85
|
throwIfAborted(signal);
|
|
83
86
|
|
|
84
|
-
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', {
|
|
85
90
|
projectId: mirror.projectKey,
|
|
86
91
|
workspacePath: mirror.workspacePath,
|
|
87
|
-
fileCount: mirror.fileCount
|
|
92
|
+
fileCount: mirror.fileCount,
|
|
93
|
+
contentComplete: mirror.contentComplete !== false,
|
|
94
|
+
skippedFiles: mirror.skippedFiles || []
|
|
88
95
|
}, 'completed');
|
|
89
96
|
}
|
|
90
|
-
|
|
91
97
|
if (skillInstallTurn && params.selectionContext) throw new Error('Remove the selected text before installing skills.');
|
|
92
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');
|
|
93
101
|
const projectLocalSkills = loadProjectLocalSkillsContext(params, mirror);
|
|
94
102
|
if (projectLocalSkills.missing.length) {
|
|
95
103
|
emitCodexEvent(emit, 'codex.local_skills.missing', 'Selected project-local skills were missing', {
|
|
@@ -99,12 +107,15 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
99
107
|
const turnAttachments = materializeTurnAttachments(params.attachments, mirror.workspacePath);
|
|
100
108
|
const settings = buildCodexSettings(params);
|
|
101
109
|
const skillLoading = normalizeSkillLoadingSettings(params);
|
|
102
|
-
const codexSkillInvocationContext = loadCodexSkillInvocationContext({
|
|
110
|
+
const codexSkillInvocationContext = await loadCodexSkillInvocationContext({
|
|
103
111
|
skillInvocation,
|
|
112
|
+
loadCodexLocalSkills: skillLoading.loadCodexLocalSkills,
|
|
113
|
+
enabledCodexLocalSkillIds: params.enabledCodexLocalSkillIds,
|
|
104
114
|
loadCodexOverleafSkills: skillLoading.loadCodexOverleafSkills,
|
|
105
115
|
enabledCodexOverleafSkillIds: params.enabledCodexOverleafSkillIds,
|
|
106
116
|
env,
|
|
107
|
-
emit
|
|
117
|
+
emit,
|
|
118
|
+
signal
|
|
108
119
|
});
|
|
109
120
|
const effectiveSkillInvocation = getEffectiveSkillInvocation(codexSkillInvocationContext);
|
|
110
121
|
const runnerWorkspacePath = skillInstallTurn
|
|
@@ -116,7 +127,7 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
116
127
|
const execute = executeCodex || runCodexAppServerSession;
|
|
117
128
|
let unconfirmedStopError = null;
|
|
118
129
|
const runner = async input => {
|
|
119
|
-
try { return await execute(input); }
|
|
130
|
+
try { return await execute({ ...input, onProcessStarted }); }
|
|
120
131
|
catch (error) {
|
|
121
132
|
if (error?.code === 'codex_process_stop_unconfirmed') {
|
|
122
133
|
unconfirmedStopError = error;
|
|
@@ -125,11 +136,12 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
125
136
|
throw error;
|
|
126
137
|
}
|
|
127
138
|
};
|
|
128
|
-
//
|
|
129
|
-
//
|
|
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
|
|
130
141
|
// host (fresh sandbox — never nested), confined to the same mirror; the
|
|
131
142
|
// broker enforces file ownership and wall-clock deadlines (spec §5-§7).
|
|
132
143
|
const subagentBroker = !skillInstallTurn
|
|
144
|
+
&& settings.sandboxMode === 'workspace-write'
|
|
133
145
|
&& skillLoading.loadCodexOverleafSkills !== false
|
|
134
146
|
&& Array.isArray(params.enabledCodexOverleafSkillIds)
|
|
135
147
|
&& params.enabledCodexOverleafSkillIds.includes(PARALLEL_SUBAGENTS_SKILL_ID)
|
|
@@ -150,6 +162,8 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
150
162
|
speedTier: normalizeSpeedTier(params.speedTier),
|
|
151
163
|
loadCodexLocalSkills: skillLoading.loadCodexLocalSkills,
|
|
152
164
|
loadCodexOverleafSkills: skillLoading.loadCodexOverleafSkills,
|
|
165
|
+
enabledCodexOverleafSkillIds: params.enabledCodexOverleafSkillIds,
|
|
166
|
+
enabledCodexLocalSkillIds: params.enabledCodexLocalSkillIds,
|
|
153
167
|
skillInvocation: null,
|
|
154
168
|
installCodexOverleafSkillsTarget: false,
|
|
155
169
|
projectLocalSkills: null,
|
|
@@ -195,6 +209,8 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
195
209
|
speedTier: normalizeSpeedTier(params.speedTier),
|
|
196
210
|
loadCodexLocalSkills: skillLoading.loadCodexLocalSkills,
|
|
197
211
|
loadCodexOverleafSkills: skillLoading.loadCodexOverleafSkills,
|
|
212
|
+
enabledCodexOverleafSkillIds: params.enabledCodexOverleafSkillIds,
|
|
213
|
+
enabledCodexLocalSkillIds: params.enabledCodexLocalSkillIds,
|
|
198
214
|
skillInvocation: effectiveSkillInvocation,
|
|
199
215
|
installCodexOverleafSkillsTarget: skillInstallTurn,
|
|
200
216
|
projectLocalSkills: null,
|
|
@@ -243,6 +259,7 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
243
259
|
const filteredChanges = filterSyncChangesForFocus({
|
|
244
260
|
changes: selectionChanges.changes,
|
|
245
261
|
focusFiles: params.focusFiles || params.session?.focusFiles,
|
|
262
|
+
focusFilesAreLiteral: params.focusFilesAreLiteral === true,
|
|
246
263
|
restrictToFocusFiles: params.restrictToFocusFiles
|
|
247
264
|
});
|
|
248
265
|
let rawSyncChanges = filteredChanges.changes;
|
|
@@ -257,13 +274,14 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
257
274
|
// syncChanges would write directly.
|
|
258
275
|
const subagentViolationPaths = subagentBroker ? subagentBroker.getViolationPaths() : null;
|
|
259
276
|
if (subagentViolationPaths && subagentViolationPaths.size) {
|
|
260
|
-
const
|
|
261
|
-
|
|
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));
|
|
262
280
|
for (const change of blocked) {
|
|
263
281
|
unsupportedChanges.push({
|
|
264
282
|
type: 'unsupported-local-file',
|
|
265
283
|
path: change.path,
|
|
266
|
-
reason: subagentBroker.getBlockedReason(change
|
|
284
|
+
reason: subagentBroker.getBlockedReason(violatedPath(change))
|
|
267
285
|
});
|
|
268
286
|
}
|
|
269
287
|
}
|
|
@@ -324,7 +342,7 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
|
|
|
324
342
|
files: response.syncChanges.map(change => change.path),
|
|
325
343
|
unsupportedCount: response.unsupportedChanges.length,
|
|
326
344
|
unsupportedFiles: response.unsupportedChanges.map(change => change.path)
|
|
327
|
-
}, 'completed');
|
|
345
|
+
}, response.unsupportedChanges.length ? 'warning' : 'completed');
|
|
328
346
|
|
|
329
347
|
return response;
|
|
330
348
|
}
|
|
@@ -344,11 +362,11 @@ function buildCodexTurnPrompt(params = {}, mirror = {}, projectLocalSkills, turn
|
|
|
344
362
|
|
|
345
363
|
|
|
346
364
|
|
|
347
|
-
function normalizeFocusFiles(value) {
|
|
365
|
+
function normalizeFocusFiles(value, literal = false) {
|
|
348
366
|
const seen = new Set();
|
|
349
367
|
const files = [];
|
|
350
368
|
for (const item of Array.isArray(value) ? value : []) {
|
|
351
|
-
const filePath = normalizeProjectPath(item);
|
|
369
|
+
const filePath = literal ? normalizeSafeProjectPath(item) : normalizeProjectPath(item);
|
|
352
370
|
if (!filePath || seen.has(filePath)) {
|
|
353
371
|
continue;
|
|
354
372
|
}
|
|
@@ -360,20 +378,20 @@ function normalizeFocusFiles(value) {
|
|
|
360
378
|
}
|
|
361
379
|
return files;
|
|
362
380
|
}
|
|
363
|
-
|
|
364
|
-
function filterSyncChangesForFocus({ changes = [], focusFiles = [], restrictToFocusFiles = false } = {}) {
|
|
381
|
+
function filterSyncChangesForFocus({ changes = [], focusFiles = [], restrictToFocusFiles = false, focusFilesAreLiteral = false } = {}) {
|
|
365
382
|
if (!restrictToFocusFiles) {
|
|
366
383
|
return { changes, unsupportedChanges: [] };
|
|
367
384
|
}
|
|
368
|
-
const focusSet = new Set(normalizeFocusFiles(focusFiles));
|
|
369
|
-
if (!focusSet.size) {
|
|
385
|
+
const focusSet = new Set(normalizeFocusFiles(focusFiles, focusFilesAreLiteral === true));
|
|
386
|
+
if (!focusSet.size && focusFilesAreLiteral !== true) {
|
|
370
387
|
return { changes, unsupportedChanges: [] };
|
|
371
388
|
}
|
|
372
389
|
|
|
373
390
|
const accepted = [];
|
|
374
391
|
const rejected = [];
|
|
375
392
|
for (const change of changes || []) {
|
|
376
|
-
if (focusSet.has(
|
|
393
|
+
if (focusSet.has(normalizeSafeProjectPath(change?.path))
|
|
394
|
+
&& (!change?.to || focusSet.has(normalizeSafeProjectPath(change.to)))) {
|
|
377
395
|
accepted.push(change);
|
|
378
396
|
} else if (change?.path) {
|
|
379
397
|
rejected.push({
|
|
@@ -388,7 +406,6 @@ function filterSyncChangesForFocus({ changes = [], focusFiles = [], restrictToFo
|
|
|
388
406
|
unsupportedChanges: rejected
|
|
389
407
|
};
|
|
390
408
|
}
|
|
391
|
-
|
|
392
409
|
function normalizeProjectPath(value) {
|
|
393
410
|
return String(value || '')
|
|
394
411
|
.replace(/^@file:/i, '')
|
|
@@ -418,12 +435,15 @@ function normalizeSkillLoadingSettings(params = {}) {
|
|
|
418
435
|
};
|
|
419
436
|
}
|
|
420
437
|
|
|
421
|
-
function loadCodexSkillInvocationContext({
|
|
438
|
+
async function loadCodexSkillInvocationContext({
|
|
422
439
|
skillInvocation,
|
|
440
|
+
loadCodexLocalSkills = true,
|
|
441
|
+
enabledCodexLocalSkillIds,
|
|
423
442
|
loadCodexOverleafSkills = true,
|
|
424
443
|
enabledCodexOverleafSkillIds,
|
|
425
444
|
env = process.env,
|
|
426
|
-
emit = () => {}
|
|
445
|
+
emit = () => {},
|
|
446
|
+
signal
|
|
427
447
|
} = {}) {
|
|
428
448
|
const invocation = normalizeSkillInvocation(skillInvocation);
|
|
429
449
|
if (!invocation) {
|
|
@@ -433,19 +453,37 @@ function loadCodexSkillInvocationContext({
|
|
|
433
453
|
return { invocation, skill: null, missing: [], ignored: [] };
|
|
434
454
|
}
|
|
435
455
|
|
|
436
|
-
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({
|
|
437
469
|
skillId: invocation.id,
|
|
438
470
|
loadCodexOverleafSkills,
|
|
439
471
|
enabledCodexOverleafSkillIds,
|
|
440
472
|
env
|
|
441
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
|
+
}
|
|
442
478
|
if (result.missing.length) {
|
|
443
|
-
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', {
|
|
444
481
|
missingSkillIds: result.missing
|
|
445
482
|
}, 'failed');
|
|
446
483
|
}
|
|
447
484
|
if (result.ignored.length) {
|
|
448
|
-
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', {
|
|
449
487
|
ignoredSkillIds: result.ignored.map(item => item.id),
|
|
450
488
|
reason: result.ignored[0]?.reason || 'ignored'
|
|
451
489
|
}, 'warning');
|
|
@@ -476,17 +514,18 @@ function normalizeSkillInvocation(value) {
|
|
|
476
514
|
return null;
|
|
477
515
|
}
|
|
478
516
|
const title = String(value?.title || 'Skill Installer').trim().slice(0, 80) || 'Skill Installer';
|
|
479
|
-
if (id === 'skill-installer') {
|
|
517
|
+
if (id === 'skill-installer' && (!value?.scope || value.scope === 'builtin')) {
|
|
480
518
|
return { id, title };
|
|
481
519
|
}
|
|
482
|
-
if (
|
|
520
|
+
if (!['codex-overleaf', 'codex-local'].includes(value?.scope)) {
|
|
483
521
|
return null;
|
|
484
522
|
}
|
|
485
|
-
return { id, title, scope:
|
|
523
|
+
return { id, title, scope: value.scope };
|
|
486
524
|
}
|
|
487
525
|
|
|
488
526
|
function isSkillInstallerInvocation(value) {
|
|
489
|
-
|
|
527
|
+
const invocation = normalizeSkillInvocation(value);
|
|
528
|
+
return invocation?.id === 'skill-installer' && !invocation.scope;
|
|
490
529
|
}
|
|
491
530
|
|
|
492
531
|
function isSafeSkillId(id) {
|
|
@@ -551,146 +590,6 @@ function buildCodexAppServerArgs(input = {}) {
|
|
|
551
590
|
];
|
|
552
591
|
}
|
|
553
592
|
|
|
554
|
-
async function applyCodexSkillIsolation({ input = {}, childEnv = process.env, request, emit = () => {} } = {}) {
|
|
555
|
-
if (input.loadCodexLocalSkills !== false) {
|
|
556
|
-
return { disabled: [] };
|
|
557
|
-
}
|
|
558
|
-
if (typeof request !== 'function') {
|
|
559
|
-
throw new Error('Codex skill isolation requires an app-server request function');
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
const listResult = await request('skills/list', {
|
|
563
|
-
cwd: input.workspacePath,
|
|
564
|
-
includeDisabled: true
|
|
565
|
-
});
|
|
566
|
-
const skills = flattenCodexSkillsList(listResult);
|
|
567
|
-
const disabled = [];
|
|
568
|
-
for (const skill of skills) {
|
|
569
|
-
if (skill?.enabled === false || !shouldDisableCodexSkillForIsolation(skill, input, childEnv)) {
|
|
570
|
-
continue;
|
|
571
|
-
}
|
|
572
|
-
const params = buildSkillDisableParams(skill);
|
|
573
|
-
if (!params) {
|
|
574
|
-
continue;
|
|
575
|
-
}
|
|
576
|
-
await request('skills/config/write', params);
|
|
577
|
-
disabled.push(String(skill.name || skill.path || '').trim());
|
|
578
|
-
}
|
|
579
|
-
if (disabled.length) {
|
|
580
|
-
emitCodexEvent(emit, 'codex.skill_isolation.applied', 'Disabled non-Overleaf Codex skills for this turn', {
|
|
581
|
-
disabledSkillNames: disabled.filter(Boolean)
|
|
582
|
-
}, 'completed');
|
|
583
|
-
}
|
|
584
|
-
return { disabled };
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
// Recursion guard (spec S6): disable specific Codex-Overleaf skills for one
|
|
588
|
-
// app-server child process — used to strip `parallel-subagents` from worker
|
|
589
|
-
// runs so an inheriting worker cannot discover the queue and fan out again.
|
|
590
|
-
// Skill directories are named by skill id (<root>/<id>/SKILL.md).
|
|
591
|
-
async function applyWorkerSkillStrip({ input = {}, request } = {}) {
|
|
592
|
-
const ids = Array.isArray(input.disableCodexOverleafSkillIds)
|
|
593
|
-
? input.disableCodexOverleafSkillIds.filter(Boolean)
|
|
594
|
-
: [];
|
|
595
|
-
if (!ids.length || typeof request !== 'function') {
|
|
596
|
-
return { disabled: [] };
|
|
597
|
-
}
|
|
598
|
-
const listResult = await request('skills/list', {
|
|
599
|
-
cwd: input.workspacePath,
|
|
600
|
-
includeDisabled: true
|
|
601
|
-
});
|
|
602
|
-
const disabled = [];
|
|
603
|
-
for (const skill of flattenCodexSkillsList(listResult)) {
|
|
604
|
-
if (skill?.enabled === false) {
|
|
605
|
-
continue;
|
|
606
|
-
}
|
|
607
|
-
const skillDirName = path.basename(path.dirname(String(skill?.path || '')));
|
|
608
|
-
if (!ids.includes(skillDirName)) {
|
|
609
|
-
continue;
|
|
610
|
-
}
|
|
611
|
-
const params = buildSkillDisableParams(skill);
|
|
612
|
-
if (!params) {
|
|
613
|
-
continue;
|
|
614
|
-
}
|
|
615
|
-
await request('skills/config/write', params);
|
|
616
|
-
disabled.push(skillDirName);
|
|
617
|
-
}
|
|
618
|
-
return { disabled };
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
function flattenCodexSkillsList(listResult = {}) {
|
|
622
|
-
const data = Array.isArray(listResult?.data) ? listResult.data : [];
|
|
623
|
-
return data.flatMap(entry => Array.isArray(entry?.skills) ? entry.skills : []);
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
function shouldDisableCodexSkillForIsolation(skill = {}, input = {}, childEnv = process.env) {
|
|
627
|
-
if (isCodexSystemSkill(skill)) {
|
|
628
|
-
return !isAllowedSystemSkillForIsolation(skill, input);
|
|
629
|
-
}
|
|
630
|
-
return !isAllowedCodexOverleafSkillPath(skill.path, input, childEnv);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
function isCodexSystemSkill(skill = {}) {
|
|
634
|
-
return String(skill.scope || '') === 'system' || isSystemSkillPath(skill.path);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
function isAllowedSystemSkillForIsolation(skill = {}, input = {}) {
|
|
638
|
-
return input.installCodexOverleafSkillsTarget === true && String(skill.name || '') === 'skill-installer';
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
function isAllowedCodexOverleafSkillPath(skillPath, input = {}, childEnv = process.env) {
|
|
642
|
-
if (input.loadCodexOverleafSkills === false && input.installCodexOverleafSkillsTarget !== true) {
|
|
643
|
-
return false;
|
|
644
|
-
}
|
|
645
|
-
const pathText = String(skillPath || '');
|
|
646
|
-
if (!pathText || !path.isAbsolute(pathText) || isSystemSkillPath(pathText)) {
|
|
647
|
-
return false;
|
|
648
|
-
}
|
|
649
|
-
const roots = [
|
|
650
|
-
path.join(String(childEnv.CODEX_HOME || ''), 'skills'),
|
|
651
|
-
getCodexOverleafSkillsRoot({ env: childEnv })
|
|
652
|
-
].filter(Boolean);
|
|
653
|
-
return roots.some(root => isInsideOrSamePath(pathText, root));
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
function isSystemSkillPath(skillPath) {
|
|
657
|
-
return String(skillPath || '').split(path.sep).includes('.system');
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
function buildSkillDisableParams(skill = {}) {
|
|
661
|
-
const name = String(skill.name || '').trim();
|
|
662
|
-
if (isCodexSystemSkill(skill) && name) {
|
|
663
|
-
return { name, enabled: false };
|
|
664
|
-
}
|
|
665
|
-
const skillPath = String(skill.path || '').trim();
|
|
666
|
-
if (path.isAbsolute(skillPath)) {
|
|
667
|
-
return { path: skillPath, enabled: false };
|
|
668
|
-
}
|
|
669
|
-
if (name) {
|
|
670
|
-
return { name, enabled: false };
|
|
671
|
-
}
|
|
672
|
-
return null;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
function isInsideOrSamePath(target, root) {
|
|
676
|
-
const targetPaths = comparablePaths(target);
|
|
677
|
-
const rootPaths = comparablePaths(root);
|
|
678
|
-
return targetPaths.some(targetPath => rootPaths.some(rootPath => (
|
|
679
|
-
targetPath === rootPath || targetPath.startsWith(rootPath + path.sep)
|
|
680
|
-
)));
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
function comparablePaths(value) {
|
|
684
|
-
const resolved = path.resolve(String(value || ''));
|
|
685
|
-
const candidates = [resolved];
|
|
686
|
-
try {
|
|
687
|
-
candidates.push(fs.realpathSync.native(resolved));
|
|
688
|
-
} catch (_) {
|
|
689
|
-
// Fall back to the lexical path when the file is not present yet.
|
|
690
|
-
}
|
|
691
|
-
return Array.from(new Set(candidates));
|
|
692
|
-
}
|
|
693
|
-
|
|
694
593
|
function buildTurnStartParams(input = {}, threadId = input.threadId || '') {
|
|
695
594
|
const params = {
|
|
696
595
|
threadId,
|
|
@@ -731,6 +630,10 @@ function runCodexAppServerProcess(input) {
|
|
|
731
630
|
return;
|
|
732
631
|
}
|
|
733
632
|
const childEnv = applyProviderEnvironment(buildCodexHomeEnv(input.env || process.env, {
|
|
633
|
+
isolateRuntimeHome: true,
|
|
634
|
+
enabledCodexOverleafSkillIds: input.enabledCodexOverleafSkillIds,
|
|
635
|
+
enabledCodexLocalSkillIds: input.enabledCodexLocalSkillIds,
|
|
636
|
+
disableCodexOverleafSkillIds: input.disableCodexOverleafSkillIds,
|
|
734
637
|
loadCodexLocalSkills: input.loadCodexLocalSkills !== false,
|
|
735
638
|
loadCodexOverleafSkills: input.loadCodexOverleafSkills !== false,
|
|
736
639
|
installCodexOverleafSkillsTarget: input.installCodexOverleafSkillsTarget === true,
|
|
@@ -824,6 +727,8 @@ function runCodexAppServerProcess(input) {
|
|
|
824
727
|
fail(new Error(stderr || `codex app-server exited before turn completed with code ${code}`));
|
|
825
728
|
});
|
|
826
729
|
|
|
730
|
+
try { input.onProcessStarted?.(createProcessStopIdentity(child, { processGroup: process.platform !== 'win32' })); }
|
|
731
|
+
catch (error) { fail(error); return; }
|
|
827
732
|
start().catch(fail);
|
|
828
733
|
|
|
829
734
|
async function start() {
|
|
@@ -841,10 +746,6 @@ function runCodexAppServerProcess(input) {
|
|
|
841
746
|
request,
|
|
842
747
|
emit: input.emit
|
|
843
748
|
});
|
|
844
|
-
await applyWorkerSkillStrip({
|
|
845
|
-
input,
|
|
846
|
-
request
|
|
847
|
-
});
|
|
848
749
|
|
|
849
750
|
if (input.threadId) {
|
|
850
751
|
try {
|
|
@@ -934,7 +835,9 @@ function runCodexAppServerProcess(input) {
|
|
|
934
835
|
}
|
|
935
836
|
pending.delete(message.id);
|
|
936
837
|
if (message.error) {
|
|
937
|
-
|
|
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);
|
|
938
841
|
} else {
|
|
939
842
|
if (pendingRequest.method === 'thread/start' || pendingRequest.method === 'thread/resume') {
|
|
940
843
|
activeThreadId = message.result?.thread?.id || message.result?.threadId || pendingRequest.params?.threadId || activeThreadId;
|
|
@@ -974,7 +877,10 @@ function runCodexAppServerProcess(input) {
|
|
|
974
877
|
if (message.method === 'item/completed' && eventScope.owns(message.params) &&
|
|
975
878
|
!readProgressController.observe(message.params?.item || {})) return;
|
|
976
879
|
if (message.method === 'turn/completed' && activeTurnId && (message.params?.turn?.id === activeTurnId || message.params?.turnId === activeTurnId)) {
|
|
977
|
-
|
|
880
|
+
const turn = message.params?.turn || {};
|
|
881
|
+
const terminalError = getTurnCompletionError(turn);
|
|
882
|
+
if (terminalError) fail(terminalError);
|
|
883
|
+
else succeed(turn);
|
|
978
884
|
}
|
|
979
885
|
if (message.method === 'error' && isTransientCodexAppServerError(message.params)) {
|
|
980
886
|
return;
|
|
@@ -1083,17 +989,23 @@ function runCodexAppServerProcess(input) {
|
|
|
1083
989
|
if (settled || stopping) {
|
|
1084
990
|
return;
|
|
1085
991
|
}
|
|
1086
|
-
|
|
992
|
+
stopping = true;
|
|
1087
993
|
const turnEndedError = new Error('Codex turn ended before the pending app-server request completed.');
|
|
1088
994
|
turnEndedError.code = 'codex_turn_ended';
|
|
1089
995
|
rejectPendingRequests(pending, turnEndedError);
|
|
1090
996
|
cleanup();
|
|
1091
|
-
|
|
1092
|
-
resolve({
|
|
997
|
+
const result = {
|
|
1093
998
|
assistantMessage: buildFinalAssistantMessage(assistantMessages, assistantMessageOrder, {
|
|
1094
999
|
turnCompleted: turn.status === undefined || turn.status === 'completed'
|
|
1095
1000
|
}),
|
|
1096
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);
|
|
1097
1009
|
});
|
|
1098
1010
|
}
|
|
1099
1011
|
|
|
@@ -1404,6 +1316,10 @@ function emitCodexEvent(emit, type, title, detail = {}, status = 'running') {
|
|
|
1404
1316
|
}
|
|
1405
1317
|
|
|
1406
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
|
+
}
|
|
1407
1323
|
if (message.method === 'error' && isTransientCodexAppServerError(message.params)) {
|
|
1408
1324
|
return 'warning';
|
|
1409
1325
|
}
|
|
@@ -1413,6 +1329,19 @@ function inferNotificationStatus(message) {
|
|
|
1413
1329
|
return 'running';
|
|
1414
1330
|
}
|
|
1415
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
|
+
|
|
1416
1345
|
function isTransientCodexAppServerError(params = {}) {
|
|
1417
1346
|
const message = extractCodexAppServerErrorMessage(params);
|
|
1418
1347
|
return /^Reconnecting(?:\.\.\.|…)?\s+\d+\s*\/\s*\d+\.?$/i.test(message);
|
|
@@ -1446,9 +1375,7 @@ function isUnsupportedReasoningSummaryError(error) {
|
|
|
1446
1375
|
return /unsupported_parameter/i.test(message) && /reasoning\.summary|summary/i.test(message);
|
|
1447
1376
|
}
|
|
1448
1377
|
|
|
1449
|
-
|
|
1450
|
-
return String(value || '').trim();
|
|
1451
|
-
}
|
|
1378
|
+
const cleanAssistantMessage = value => String(value || '').trim();
|
|
1452
1379
|
|
|
1453
1380
|
module.exports = {
|
|
1454
1381
|
applyCodexSkillIsolation,
|
|
@@ -41,20 +41,25 @@ function rejectPendingRequests(pending, error) {
|
|
|
41
41
|
pending.clear();
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
interrupt, reason, processGroup = false, platform = process.platform,
|
|
46
|
-
interruptTimeoutMs = 1500, terminateTimeoutMs = 500, forceTimeoutMs = 1500,
|
|
47
|
-
kill = process.kill.bind(process), taskkill = defaultTaskkill
|
|
48
|
-
} = {}) {
|
|
44
|
+
function createProcessStopIdentity(child, { processGroup = false, platform = process.platform, kill = process.kill.bind(process) } = {}) {
|
|
49
45
|
const pid = Number(child?.pid);
|
|
50
|
-
if (!Number.isInteger(pid) || pid <= 0) return;
|
|
51
46
|
const grouped = processGroup && platform !== 'win32';
|
|
52
47
|
const exited = () => child.exitCode != null || child.signalCode != null;
|
|
53
48
|
const groupGone = () => {
|
|
54
49
|
if (!grouped) return true;
|
|
55
50
|
try { kill(-pid, 0); return false; } catch (error) { return error?.code === 'ESRCH'; }
|
|
56
51
|
};
|
|
57
|
-
|
|
52
|
+
return { processId: pid, processGroup: grouped, isStopped: () => exited() && groupGone() };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function stopCodexAppServer(child, {
|
|
56
|
+
interrupt, reason, processGroup = false, platform = process.platform,
|
|
57
|
+
interruptTimeoutMs = 1500, terminateTimeoutMs = 500, forceTimeoutMs = 1500,
|
|
58
|
+
kill = process.kill.bind(process), taskkill = defaultTaskkill
|
|
59
|
+
} = {}) {
|
|
60
|
+
const { processId: pid, processGroup: grouped, isStopped: stopped } = createProcessStopIdentity(child, { processGroup, platform, kill });
|
|
61
|
+
if (!Number.isInteger(pid) || pid <= 0) return;
|
|
62
|
+
const exited = () => child.exitCode != null || child.signalCode != null;
|
|
58
63
|
const waitForStop = async timeoutMs => {
|
|
59
64
|
const deadline = Date.now() + timeoutMs;
|
|
60
65
|
while (!stopped() && Date.now() < deadline) {
|
|
@@ -99,13 +104,18 @@ async function stopCodexAppServer(child, {
|
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
function defaultTaskkill(pid, timeout) {
|
|
107
|
+
const path = require('node:path');
|
|
108
|
+
const systemRoot = process.env.SystemRoot || process.env.SYSTEMROOT || process.env.windir || process.env.WINDIR;
|
|
109
|
+
const command = systemRoot && path.win32.isAbsolute(systemRoot)
|
|
110
|
+
? path.win32.join(systemRoot, 'System32', 'taskkill.exe') : 'taskkill';
|
|
102
111
|
return new Promise((resolve, reject) => {
|
|
103
|
-
require('node:child_process').execFile(
|
|
112
|
+
require('node:child_process').execFile(command, ['/pid', String(pid), '/t', '/f'],
|
|
104
113
|
{ windowsHide: true, timeout }, error => error ? reject(error) : resolve());
|
|
105
114
|
});
|
|
106
115
|
}
|
|
107
116
|
|
|
108
117
|
module.exports = {
|
|
118
|
+
createProcessStopIdentity,
|
|
109
119
|
createCodexIdleWatchdog,
|
|
110
120
|
createOptionalTimeout,
|
|
111
121
|
getAbortReason,
|