@wix/pathgrade 1.0.14 → 1.0.15
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 +28 -0
- package/dist/adapters/jest/results.js +1 -1
- package/dist/adapters/node-test/index.js +1 -1
- package/dist/agents/claude/sdk-message-projector.js +3 -2
- package/dist/agents/claude/tool-permission-bridge.d.ts +4 -0
- package/dist/agents/claude/tool-permission-bridge.js +68 -1
- package/dist/agents/claude.d.ts +2 -0
- package/dist/agents/claude.js +55 -10
- package/dist/agents/codex-app-server/agent.js +94 -76
- package/dist/agents/codex-app-server/mcp-approval-correlator.d.ts +55 -0
- package/dist/agents/codex-app-server/mcp-approval-correlator.js +299 -0
- package/dist/core/canonical-json.d.ts +2 -0
- package/dist/core/canonical-json.js +51 -0
- package/dist/core/generated-mcp-protocol.d.ts +19 -0
- package/dist/core/generated-mcp-protocol.js +26 -0
- package/dist/core/mcp-mock.d.ts +1 -1
- package/dist/core/mcp-mock.js +24 -0
- package/dist/core/mcp-mock.types.d.ts +6 -0
- package/dist/core/mcp-schema-profile.d.ts +10 -0
- package/dist/core/mcp-schema-profile.js +91 -0
- package/dist/mcp-mock-server.js +29 -13
- package/dist/providers/mcp-config.js +4 -2
- package/dist/providers/scripted-mcp-mock-host.d.ts +39 -0
- package/dist/providers/scripted-mcp-mock-host.js +368 -0
- package/dist/reporters/cli.js +4 -3
- package/dist/reporters/github-comment.js +1 -1
- package/dist/reporters/report-summary.js +1 -0
- package/dist/reporting/core.js +19 -5
- package/dist/reporting/types.d.ts +2 -1
- package/dist/runners/model-builders.js +1 -1
- package/dist/runners/model-validation.js +4 -1
- package/dist/runners/model.d.ts +1 -1
- package/dist/runners/report-projection.js +2 -2
- package/dist/runners/vitest-adapter.js +1 -1
- package/dist/sdk/agent.js +64 -19
- package/dist/sdk/diagnostics.d.ts +1 -0
- package/dist/sdk/diagnostics.js +6 -3
- package/dist/sdk/index.d.ts +4 -3
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/lifecycle.js +3 -3
- package/dist/sdk/managed-session.d.ts +3 -0
- package/dist/sdk/managed-session.js +71 -27
- package/dist/sdk/mcp-event-input.d.ts +3 -0
- package/dist/sdk/mcp-event-input.js +8 -0
- package/dist/sdk/mcp-evidence.d.ts +39 -0
- package/dist/sdk/mcp-evidence.js +71 -12
- package/dist/sdk/mcp-mock-approvals.d.ts +40 -0
- package/dist/sdk/mcp-mock-approvals.js +235 -0
- package/dist/sdk/scripted-mcp-events.d.ts +24 -0
- package/dist/sdk/scripted-mcp-events.js +30 -0
- package/dist/sdk/types.d.ts +6 -2
- package/dist/tool-events.d.ts +16 -1
- package/dist/types.d.ts +3 -1
- package/dist/viewer.html +4 -4
- package/package.json +3 -2
|
@@ -4,11 +4,13 @@ import { assertMcpSecretReferencesReady } from '../../providers/mcp-config.js';
|
|
|
4
4
|
import { buildSummary, enrichSkillEvents, extractSkillNameFromPath, inferCodexExecAction, } from '../../tool-events.js';
|
|
5
5
|
import { requireAskBusForLiveBatches } from '../../sdk/ask-bus/bus.js';
|
|
6
6
|
import { toAskUserToolEvent } from '../../sdk/ask-bus/projection.js';
|
|
7
|
-
import { decideMcpToolCall
|
|
7
|
+
import { decideMcpToolCall } from '../../sdk/mcp-safety.js';
|
|
8
|
+
import { attachOriginalMcpInput } from '../../sdk/mcp-event-input.js';
|
|
8
9
|
import { spawnAppServerTransport, } from './transport.js';
|
|
9
10
|
import { normalizeUpstreamQuestion, toWireAnswerMap, } from './wire-translators.js';
|
|
10
11
|
import { extractTurnCompletionFailure } from './turn-completion.js';
|
|
11
12
|
import { resolveCodexModel } from '../codex-model.js';
|
|
13
|
+
import { CodexMcpApprovalCorrelator, extractMcpToolApprovalRequest, hasScriptedApprovalPolicy, isMcpToolCallApprovalRequest, recordPolicyDeniedMcpToolCall } from './mcp-approval-correlator.js';
|
|
12
14
|
const TURN_COMPLETED_METHOD = 'turn/completed';
|
|
13
15
|
function recordFromUnknown(value) {
|
|
14
16
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
@@ -16,32 +18,6 @@ function recordFromUnknown(value) {
|
|
|
16
18
|
}
|
|
17
19
|
return {};
|
|
18
20
|
}
|
|
19
|
-
function isMcpToolCallApprovalRequest(params) {
|
|
20
|
-
const meta = recordFromUnknown(recordFromUnknown(params)._meta);
|
|
21
|
-
return meta.codex_approval_kind === 'mcp_tool_call';
|
|
22
|
-
}
|
|
23
|
-
function extractMcpToolApprovalRequest(params) {
|
|
24
|
-
if (!isMcpToolCallApprovalRequest(params))
|
|
25
|
-
return undefined;
|
|
26
|
-
const record = recordFromUnknown(params);
|
|
27
|
-
const meta = recordFromUnknown(record._meta);
|
|
28
|
-
const serverName = typeof record.serverName === 'string' ? record.serverName : undefined;
|
|
29
|
-
const toolName = typeof meta.toolName === 'string' ? meta.toolName
|
|
30
|
-
: typeof meta.tool_name === 'string' ? meta.tool_name
|
|
31
|
-
: typeof meta.name === 'string' ? meta.name
|
|
32
|
-
: typeof record.message === 'string' ? parseToolNameFromApprovalMessage(record.message)
|
|
33
|
-
: undefined;
|
|
34
|
-
if (!serverName || !toolName)
|
|
35
|
-
return undefined;
|
|
36
|
-
return {
|
|
37
|
-
serverName,
|
|
38
|
-
toolName,
|
|
39
|
-
arguments: recordFromUnknown(meta.tool_params),
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
function parseToolNameFromApprovalMessage(message) {
|
|
43
|
-
return message.match(/tool\s+"([^"]+)"/i)?.[1];
|
|
44
|
-
}
|
|
45
21
|
function extractCommandActionSkillName(action) {
|
|
46
22
|
if (typeof action.path === 'string') {
|
|
47
23
|
const direct = extractSkillNameFromPath(action.path);
|
|
@@ -127,12 +103,16 @@ function projectItemIntoTurn(item, turn) {
|
|
|
127
103
|
}
|
|
128
104
|
if (item.type === 'mcpToolCall') {
|
|
129
105
|
const call = item;
|
|
106
|
+
if (turn.nonAskToolEvents.some((event) => event.action === 'mcp_tool_call'
|
|
107
|
+
&& event.toolUseId === call.id && event.mcp?.invocation === 'not_invoked'))
|
|
108
|
+
return;
|
|
130
109
|
const args = recordFromUnknown(call.arguments);
|
|
131
110
|
const providerToolName = `${call.server}.${call.tool}`;
|
|
132
|
-
turn.nonAskToolEvents.push({
|
|
111
|
+
turn.nonAskToolEvents.push(attachOriginalMcpInput({
|
|
133
112
|
action: 'mcp_tool_call',
|
|
134
113
|
provider: 'codex',
|
|
135
114
|
providerToolName,
|
|
115
|
+
toolUseId: call.id,
|
|
136
116
|
turnNumber: turn.turnNumber,
|
|
137
117
|
arguments: {
|
|
138
118
|
...args,
|
|
@@ -143,7 +123,8 @@ function projectItemIntoTurn(item, turn) {
|
|
|
143
123
|
summary: `MCP tool ${providerToolName} ${call.status ?? 'unknown'}`,
|
|
144
124
|
confidence: 'high',
|
|
145
125
|
rawSnippet: JSON.stringify(call),
|
|
146
|
-
|
|
126
|
+
...(call.result !== undefined ? { result: { content: JSON.stringify(call.result) } } : {}),
|
|
127
|
+
}, args));
|
|
147
128
|
return;
|
|
148
129
|
}
|
|
149
130
|
}
|
|
@@ -167,36 +148,13 @@ function projectMcpStartupStatusIntoTurn(params, turn) {
|
|
|
167
148
|
});
|
|
168
149
|
if (status === 'failed') {
|
|
169
150
|
const message = `MCP server ${name} failed to start${error ? `: ${error}` : ''}`;
|
|
170
|
-
turn
|
|
171
|
-
turn.failureMessage = message;
|
|
172
|
-
turn.signalFailure?.(message);
|
|
151
|
+
failTurn(turn, message);
|
|
173
152
|
}
|
|
174
153
|
}
|
|
175
|
-
function
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const providerToolName = `${request.serverName}.${request.toolName}`;
|
|
180
|
-
turn.nonAskToolEvents.push({
|
|
181
|
-
action: 'mcp_tool_call',
|
|
182
|
-
provider: 'codex',
|
|
183
|
-
providerToolName,
|
|
184
|
-
turnNumber: turn.turnNumber,
|
|
185
|
-
arguments: {
|
|
186
|
-
...args,
|
|
187
|
-
server: request.serverName,
|
|
188
|
-
tool: request.toolName,
|
|
189
|
-
status: 'policy_denied',
|
|
190
|
-
policyResult: {
|
|
191
|
-
action: 'deny',
|
|
192
|
-
reason: decision.reason,
|
|
193
|
-
message: decision.message,
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
summary: `MCP tool ${providerToolName} policy_denied`,
|
|
197
|
-
confidence: 'high',
|
|
198
|
-
rawSnippet: JSON.stringify(redactMcpSecrets(rawParams)),
|
|
199
|
-
});
|
|
154
|
+
function failTurn(turn, message) {
|
|
155
|
+
turn.turnFailed = true;
|
|
156
|
+
turn.failureMessage = message;
|
|
157
|
+
turn.signalFailure?.(message);
|
|
200
158
|
}
|
|
201
159
|
function isLiveMcpSafetyMode(options) {
|
|
202
160
|
const runMode = options?.runMode ?? 'mock';
|
|
@@ -220,13 +178,19 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
220
178
|
let closeInfo = null;
|
|
221
179
|
let activeTurn = null;
|
|
222
180
|
let disposed = false;
|
|
181
|
+
let codexUserAgent = 'unknown';
|
|
182
|
+
const scriptedHost = options?.scriptedMcpHost;
|
|
183
|
+
const correlator = scriptedHost
|
|
184
|
+
? new CodexMcpApprovalCorrelator(scriptedHost, () => turnCounter, () => threadId, () => options?.getRemainingMs?.() ?? Number.POSITIVE_INFINITY)
|
|
185
|
+
: undefined;
|
|
223
186
|
const ensureTransport = async () => {
|
|
224
187
|
if (disposed)
|
|
225
188
|
throw new Error('CodexAppServerAgent session disposed');
|
|
226
189
|
if (handle)
|
|
227
190
|
return handle.transport;
|
|
228
191
|
const factory = this.deps.createTransport
|
|
229
|
-
?? (async (ctx) => spawnAppServerTransport({ cwd: ctx.workspacePath, env: ctx.env
|
|
192
|
+
?? (async (ctx) => spawnAppServerTransport({ cwd: ctx.workspacePath, env: ctx.env,
|
|
193
|
+
args: scriptedHost ? ['--enable', 'tool_call_mcp_elicitation'] : [] }));
|
|
230
194
|
handle = await factory({ workspacePath, env: runtimeEnv });
|
|
231
195
|
const transport = handle.transport;
|
|
232
196
|
transport.onServerRequest((req) => this.dispatchServerRequest(req, {
|
|
@@ -235,6 +199,8 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
235
199
|
activeTurn: () => activeTurn,
|
|
236
200
|
onPermissionGrant: this.deps.onPermissionGrant,
|
|
237
201
|
mcpSafety: options?.mcpSafety,
|
|
202
|
+
scriptedHost,
|
|
203
|
+
correlator,
|
|
238
204
|
}));
|
|
239
205
|
transport.onClose((info) => {
|
|
240
206
|
closeInfo = info;
|
|
@@ -250,20 +216,37 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
250
216
|
}
|
|
251
217
|
return;
|
|
252
218
|
}
|
|
253
|
-
if (n.method !== 'item/completed')
|
|
254
|
-
return;
|
|
255
219
|
const turn = activeTurn;
|
|
256
220
|
if (!turn)
|
|
257
221
|
return;
|
|
258
222
|
const params = n.params;
|
|
223
|
+
if (n.method === 'item/started') {
|
|
224
|
+
try {
|
|
225
|
+
correlator?.started(n.params);
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
failTurn(turn, error instanceof Error ? error.message : String(error));
|
|
229
|
+
}
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (n.method !== 'item/completed')
|
|
233
|
+
return;
|
|
259
234
|
if (!params?.item)
|
|
260
235
|
return;
|
|
261
|
-
|
|
236
|
+
try {
|
|
237
|
+
if (correlator?.completed(params) !== false)
|
|
238
|
+
projectItemIntoTurn(params.item, turn);
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
failTurn(turn, error instanceof Error ? error.message : String(error));
|
|
242
|
+
}
|
|
262
243
|
});
|
|
263
|
-
await transport.sendRequest('initialize', {
|
|
244
|
+
const initialized = await transport.sendRequest('initialize', {
|
|
264
245
|
clientInfo: { name: 'pathgrade', version: '0.5.0', title: null },
|
|
265
246
|
capabilities: { experimentalApi: true, optOutNotificationMethods: null },
|
|
266
247
|
});
|
|
248
|
+
if (typeof initialized.userAgent === 'string')
|
|
249
|
+
codexUserAgent = initialized.userAgent.slice(0, 200);
|
|
267
250
|
// Upstream ClientNotification = { method: "initialized" }: send it
|
|
268
251
|
// before any thread/start so the handshake matches the v0.124
|
|
269
252
|
// contract and is forward-compatible with servers that enforce it.
|
|
@@ -281,6 +264,7 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
281
264
|
turnFailed: false,
|
|
282
265
|
};
|
|
283
266
|
activeTurn = turn;
|
|
267
|
+
correlator?.beginTurn();
|
|
284
268
|
try {
|
|
285
269
|
if (threadId === null) {
|
|
286
270
|
if (options?.mcpConfigPath && isLiveMcpSafetyMode(options.mcpSafety)) {
|
|
@@ -290,13 +274,16 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
290
274
|
env: runtimeEnv,
|
|
291
275
|
});
|
|
292
276
|
}
|
|
293
|
-
const mcpConfig = options?.mcpConfigPath
|
|
277
|
+
const mcpConfig = scriptedHost?.codexConfig ?? (options?.mcpConfigPath
|
|
294
278
|
? await mountMcpForCodexAppServer({
|
|
295
279
|
workspacePath,
|
|
296
280
|
mcpConfigPath: options.mcpConfigPath,
|
|
297
281
|
})
|
|
298
|
-
: undefined;
|
|
299
|
-
const resp = await t.sendRequest('thread/start', buildThreadStartParams({ cwd: workspacePath, model, sandboxMode, mcpConfig }));
|
|
282
|
+
: undefined);
|
|
283
|
+
const resp = await t.sendRequest('thread/start', buildThreadStartParams({ cwd: workspacePath, model, sandboxMode, mcpConfig, scripted: !!scriptedHost }));
|
|
284
|
+
if (scriptedHost && !hasScriptedApprovalPolicy(resp)) {
|
|
285
|
+
throw new Error(`Codex app-server scripted MCP approval policy drift (userAgent=${codexUserAgent})`);
|
|
286
|
+
}
|
|
300
287
|
threadId = resp.thread.id;
|
|
301
288
|
}
|
|
302
289
|
// Wait for TurnCompleted OR subprocess crash OR dispatcher failure.
|
|
@@ -352,8 +339,7 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
352
339
|
}
|
|
353
340
|
}
|
|
354
341
|
});
|
|
355
|
-
const startTurnResp = t
|
|
356
|
-
.sendRequest('turn/start', {
|
|
342
|
+
const startTurnResp = t.sendRequest('turn/start', {
|
|
357
343
|
threadId,
|
|
358
344
|
input: [{ type: 'text', text: message, text_elements: [] }],
|
|
359
345
|
})
|
|
@@ -369,6 +355,18 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
369
355
|
: 'turn/start failed';
|
|
370
356
|
turn.signalFailure?.(msg);
|
|
371
357
|
});
|
|
358
|
+
if (scriptedHost) {
|
|
359
|
+
const started = await startTurnResp;
|
|
360
|
+
if (!started?.turn?.id || !threadId) {
|
|
361
|
+
scriptedHost.failProtocol('turn/start did not return an authoritative turn id');
|
|
362
|
+
turn.signalFailure?.('turn/start did not return an authoritative turn id');
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
if (correlator?.setAuthoritativeTurn(threadId, started.turn.id) === false) {
|
|
366
|
+
turn.signalFailure?.('MCP lifecycle did not match the authoritative turn');
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
372
370
|
try {
|
|
373
371
|
await turnCompletion;
|
|
374
372
|
}
|
|
@@ -383,7 +381,8 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
383
381
|
signal: info.signal,
|
|
384
382
|
});
|
|
385
383
|
}
|
|
386
|
-
|
|
384
|
+
if (!scriptedHost)
|
|
385
|
+
void startTurnResp;
|
|
387
386
|
if (turn.turnFailed) {
|
|
388
387
|
return assembleTurnResult({
|
|
389
388
|
askBus,
|
|
@@ -401,6 +400,7 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
401
400
|
}
|
|
402
401
|
finally {
|
|
403
402
|
activeTurn = null;
|
|
403
|
+
correlator?.endTurn();
|
|
404
404
|
}
|
|
405
405
|
};
|
|
406
406
|
const dispose = async () => {
|
|
@@ -439,12 +439,16 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
439
439
|
};
|
|
440
440
|
}
|
|
441
441
|
dispatchServerRequest(req, ctx) {
|
|
442
|
-
const { transport, askBus, activeTurn, onPermissionGrant, mcpSafety } = ctx;
|
|
442
|
+
const { transport, askBus, activeTurn, onPermissionGrant, mcpSafety, scriptedHost, correlator } = ctx;
|
|
443
443
|
switch (req.method) {
|
|
444
444
|
case 'item/tool/requestUserInput':
|
|
445
445
|
void handleRequestUserInput(req, { transport, askBus, activeTurn });
|
|
446
446
|
return;
|
|
447
447
|
case 'item/permissions/requestApproval': {
|
|
448
|
+
if (scriptedHost) {
|
|
449
|
+
transport.sendResponse(req.id, { permissions: {}, scope: 'turn', strictAutoReview: false });
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
448
452
|
const params = (req.params ?? {});
|
|
449
453
|
transport.sendResponse(req.id, {
|
|
450
454
|
permissions: params.permissions ?? {},
|
|
@@ -467,12 +471,25 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
467
471
|
case 'item/fileChange/requestApproval':
|
|
468
472
|
case 'applyPatchApproval':
|
|
469
473
|
case 'execCommandApproval':
|
|
470
|
-
transport.sendResponse(req.id,
|
|
474
|
+
transport.sendResponse(req.id, scriptedHost
|
|
475
|
+
? { decision: 'denied' }
|
|
476
|
+
: { decision: 'approved', scope: 'turn' });
|
|
471
477
|
return;
|
|
472
478
|
case 'item/tool/call':
|
|
473
479
|
transport.sendResponse(req.id, { status: 'declined' });
|
|
474
480
|
return;
|
|
475
481
|
case 'mcpServer/elicitation/request':
|
|
482
|
+
if (scriptedHost && correlator) {
|
|
483
|
+
void correlator.decide(req.id, req.params).then((correlated) => {
|
|
484
|
+
activeTurn()?.nonAskToolEvents.push(...correlated.events);
|
|
485
|
+
transport.sendResponse(req.id, {
|
|
486
|
+
action: correlated.action,
|
|
487
|
+
content: correlated.action === 'accept' ? {} : null,
|
|
488
|
+
_meta: null,
|
|
489
|
+
});
|
|
490
|
+
});
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
476
493
|
if (isMcpToolCallApprovalRequest(req.params)) {
|
|
477
494
|
const toolRequest = extractMcpToolApprovalRequest(req.params);
|
|
478
495
|
if (toolRequest) {
|
|
@@ -502,11 +519,8 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
502
519
|
const message = 'codex app-server requires OPENAI_API_KEY for pathgrade and honors OPENAI_BASE_URL when set; ChatGPT/cached auth unsupported under transport=app-server';
|
|
503
520
|
transport.sendErrorResponse(req.id, -32001, message);
|
|
504
521
|
const turn = activeTurn();
|
|
505
|
-
if (turn)
|
|
506
|
-
turn
|
|
507
|
-
turn.failureMessage = message;
|
|
508
|
-
turn.signalFailure?.(message);
|
|
509
|
-
}
|
|
522
|
+
if (turn)
|
|
523
|
+
failTurn(turn, message);
|
|
510
524
|
return;
|
|
511
525
|
}
|
|
512
526
|
default:
|
|
@@ -549,7 +563,11 @@ async function handleRequestUserInput(req, ctx) {
|
|
|
549
563
|
function buildThreadStartParams(opts) {
|
|
550
564
|
return {
|
|
551
565
|
cwd: opts.cwd,
|
|
552
|
-
approvalPolicy:
|
|
566
|
+
approvalPolicy: opts.scripted ? { granular: {
|
|
567
|
+
sandbox_approval: false, rules: false, skill_approval: false,
|
|
568
|
+
request_permissions: false, mcp_elicitations: true,
|
|
569
|
+
} } : 'never',
|
|
570
|
+
...(opts.scripted ? { approvalsReviewer: 'user' } : {}),
|
|
553
571
|
sandbox: opts.sandboxMode,
|
|
554
572
|
ephemeral: true,
|
|
555
573
|
experimentalRawEvents: false,
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ToolEvent } from '../../tool-events.js';
|
|
2
|
+
import type { ScriptedMcpMockHost } from '../../providers/scripted-mcp-mock-host.js';
|
|
3
|
+
import { type McpToolPolicyDecision } from '../../sdk/mcp-safety.js';
|
|
4
|
+
export interface CorrelatedApprovalResponse {
|
|
5
|
+
action: 'accept' | 'decline';
|
|
6
|
+
events: ToolEvent[];
|
|
7
|
+
}
|
|
8
|
+
export declare function isMcpToolCallApprovalRequest(params: unknown): boolean;
|
|
9
|
+
export declare function hasScriptedApprovalPolicy(response: {
|
|
10
|
+
approvalPolicy?: unknown;
|
|
11
|
+
approvalsReviewer?: unknown;
|
|
12
|
+
}): boolean;
|
|
13
|
+
export declare function extractMcpToolApprovalRequest(params: unknown): {
|
|
14
|
+
serverName: string;
|
|
15
|
+
toolName: string;
|
|
16
|
+
arguments: Record<string, unknown>;
|
|
17
|
+
} | undefined;
|
|
18
|
+
export declare function recordPolicyDeniedMcpToolCall(turn: {
|
|
19
|
+
turnNumber: number;
|
|
20
|
+
nonAskToolEvents: ToolEvent[];
|
|
21
|
+
} | null, request: {
|
|
22
|
+
serverName: string;
|
|
23
|
+
toolName: string;
|
|
24
|
+
arguments: Record<string, unknown>;
|
|
25
|
+
}, decision: Extract<McpToolPolicyDecision, {
|
|
26
|
+
action: 'deny';
|
|
27
|
+
}>, rawParams: unknown): void;
|
|
28
|
+
export declare class CodexMcpApprovalCorrelator {
|
|
29
|
+
private readonly host;
|
|
30
|
+
private readonly getTurnNumber;
|
|
31
|
+
private readonly getThreadId;
|
|
32
|
+
private readonly getRemainingMs;
|
|
33
|
+
private live;
|
|
34
|
+
private terminal;
|
|
35
|
+
private decisions;
|
|
36
|
+
private active;
|
|
37
|
+
private authoritativeTurn?;
|
|
38
|
+
private authorityPromise;
|
|
39
|
+
private resolveAuthority?;
|
|
40
|
+
private waitingRequests;
|
|
41
|
+
private poisoned;
|
|
42
|
+
constructor(host: ScriptedMcpMockHost, getTurnNumber: () => number, getThreadId: () => string | null, getRemainingMs?: () => number);
|
|
43
|
+
started(params: unknown): void;
|
|
44
|
+
completed(params: unknown): boolean;
|
|
45
|
+
decide(requestId: string | number, rawParams: unknown): Promise<CorrelatedApprovalResponse>;
|
|
46
|
+
beginTurn(): void;
|
|
47
|
+
setAuthoritativeTurn(threadId: string, turnId: string): boolean;
|
|
48
|
+
endTurn(): void;
|
|
49
|
+
private protocolEvent;
|
|
50
|
+
private waitForAuthority;
|
|
51
|
+
private parseLifecycleRecord;
|
|
52
|
+
private validateLifecycleTurn;
|
|
53
|
+
private failLifecycle;
|
|
54
|
+
private poison;
|
|
55
|
+
}
|