@mrrlin-dev/mcp 0.4.107 → 0.4.109
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/dist/bin.cjs +414 -243
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -37432,6 +37432,7 @@ var openApiOperationIds = {
|
|
|
37432
37432
|
listOperatorTranscriptMessages: "listOperatorTranscriptMessages",
|
|
37433
37433
|
createIntentProposal: "createIntentProposal",
|
|
37434
37434
|
getIntentProposal: "getIntentProposal",
|
|
37435
|
+
listIntentProposals: "listIntentProposals",
|
|
37435
37436
|
recordIntentClarification: "recordIntentClarification",
|
|
37436
37437
|
answerIntentClarification: "answerIntentClarification",
|
|
37437
37438
|
confirmIntentProposal: "confirmIntentProposal",
|
|
@@ -38171,13 +38172,13 @@ var mrrlinIntentProposalSchema = external_exports.object({
|
|
|
38171
38172
|
updatedAt: external_exports.string()
|
|
38172
38173
|
});
|
|
38173
38174
|
var mrrlinIntentProposalCreateSchema = external_exports.object({
|
|
38174
|
-
proposalId: external_exports.string().uuid(),
|
|
38175
|
-
version: external_exports.number().int().min(1),
|
|
38175
|
+
proposalId: external_exports.string().uuid().optional(),
|
|
38176
|
+
version: external_exports.number().int().min(1).optional(),
|
|
38176
38177
|
resolvedIntent: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
38177
|
-
digest: external_exports.string().min(1),
|
|
38178
|
+
digest: external_exports.string().min(1).optional(),
|
|
38178
38179
|
transcriptRevision: external_exports.string().optional(),
|
|
38179
|
-
expectedTranscriptRevisionNumber: external_exports.number().int().nonnegative(),
|
|
38180
|
-
messageIds: external_exports.array(external_exports.string().uuid())
|
|
38180
|
+
expectedTranscriptRevisionNumber: external_exports.number().int().nonnegative().optional(),
|
|
38181
|
+
messageIds: external_exports.array(external_exports.string().uuid()).min(1).optional()
|
|
38181
38182
|
}).strict();
|
|
38182
38183
|
var intentProposalResponseSchema = external_exports.object({
|
|
38183
38184
|
data: mrrlinIntentProposalSchema
|
|
@@ -38221,7 +38222,8 @@ var mrrlinIntentConfirmRequestSchema = external_exports.object({
|
|
|
38221
38222
|
actor: external_exports.string().min(1).optional(),
|
|
38222
38223
|
materializeParams: external_exports.object({
|
|
38223
38224
|
task: external_exports.object({
|
|
38224
|
-
id
|
|
38225
|
+
// Omitted ⇒ the API allocates the next per-project GT-N id before confirming.
|
|
38226
|
+
id: external_exports.string().min(1).optional(),
|
|
38225
38227
|
title: external_exports.string().min(1).optional(),
|
|
38226
38228
|
category: external_exports.string().optional(),
|
|
38227
38229
|
subcategory: external_exports.string().optional(),
|
|
@@ -38268,11 +38270,16 @@ var mrrlinIntentConfirmationSchema = external_exports.object({
|
|
|
38268
38270
|
digest: external_exports.string().min(1),
|
|
38269
38271
|
transcriptRevision: external_exports.string(),
|
|
38270
38272
|
transcriptRevisionNumber: external_exports.number().int().nonnegative().optional(),
|
|
38273
|
+
// The task the confirmation materialized, when it materialized one.
|
|
38274
|
+
materializedTaskId: external_exports.string().nullable().optional(),
|
|
38271
38275
|
createdAt: external_exports.string()
|
|
38272
38276
|
});
|
|
38273
38277
|
var intentConfirmationMaybeResponseSchema = external_exports.object({
|
|
38274
38278
|
data: mrrlinIntentConfirmationSchema.nullable()
|
|
38275
38279
|
});
|
|
38280
|
+
var intentProposalListResponseSchema = external_exports.object({
|
|
38281
|
+
data: external_exports.array(mrrlinIntentProposalSchema)
|
|
38282
|
+
});
|
|
38276
38283
|
|
|
38277
38284
|
// ../../packages/schemas/dist/appsumo.js
|
|
38278
38285
|
var APPSUMO_CODE_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
@@ -41024,8 +41031,8 @@ function createMrrlinClient(config2) {
|
|
|
41024
41031
|
throw error51;
|
|
41025
41032
|
}
|
|
41026
41033
|
},
|
|
41027
|
-
async getActiveAsyncJob(projectSlug,
|
|
41028
|
-
const url2 = appendQuery(`${projectPath(projectSlug)}/async-jobs/active`, { toolName, dedupKey });
|
|
41034
|
+
async getActiveAsyncJob(projectSlug, toolName2, dedupKey) {
|
|
41035
|
+
const url2 = appendQuery(`${projectPath(projectSlug)}/async-jobs/active`, { toolName: toolName2, dedupKey });
|
|
41029
41036
|
const body = await request(url2);
|
|
41030
41037
|
return asyncJobMaybeResponseSchema.parse(body).data;
|
|
41031
41038
|
},
|
|
@@ -41647,6 +41654,10 @@ function createMrrlinClient(config2) {
|
|
|
41647
41654
|
});
|
|
41648
41655
|
return intentProposalResponseSchema.parse(body).data;
|
|
41649
41656
|
},
|
|
41657
|
+
async listIntentProposals(projectSlug) {
|
|
41658
|
+
const body = await request(`${projectPath(projectSlug)}/intent/proposals`);
|
|
41659
|
+
return intentProposalListResponseSchema.parse(body).data;
|
|
41660
|
+
},
|
|
41650
41661
|
async getIntentProposal(projectSlug, proposalId, version2) {
|
|
41651
41662
|
try {
|
|
41652
41663
|
const body = await request(`${projectPath(projectSlug)}/intent/proposals/${encodeURIComponent(proposalId)}/${encodeURIComponent(String(version2))}`);
|
|
@@ -41685,7 +41696,7 @@ function createMrrlinClient(config2) {
|
|
|
41685
41696
|
if (error51 instanceof MrrlinApiError && (error51.status === 409 || error51.status === 422)) {
|
|
41686
41697
|
try {
|
|
41687
41698
|
const parsed = JSON.parse(error51.responseBody);
|
|
41688
|
-
const maybeResult = mrrlinIntentConfirmResponseSchema.safeParse(parsed);
|
|
41699
|
+
const maybeResult = mrrlinIntentConfirmResponseSchema.safeParse(parsed?.data ?? parsed);
|
|
41689
41700
|
if (maybeResult.success)
|
|
41690
41701
|
return maybeResult.data;
|
|
41691
41702
|
} catch {
|
|
@@ -44170,6 +44181,23 @@ var CodexAgentHandle = class {
|
|
|
44170
44181
|
}
|
|
44171
44182
|
};
|
|
44172
44183
|
|
|
44184
|
+
// ../../packages/agent-client/dist/providers/thread-env.js
|
|
44185
|
+
function threadProcessEnv(childEnv, additions) {
|
|
44186
|
+
if (!additions || Object.keys(additions).length === 0)
|
|
44187
|
+
return childEnv;
|
|
44188
|
+
const env = { ...childEnv ?? process.env };
|
|
44189
|
+
for (const [key, value] of Object.entries(additions)) {
|
|
44190
|
+
if (value === null)
|
|
44191
|
+
delete env[key];
|
|
44192
|
+
else
|
|
44193
|
+
env[key] = value;
|
|
44194
|
+
}
|
|
44195
|
+
return env;
|
|
44196
|
+
}
|
|
44197
|
+
function envOption(env) {
|
|
44198
|
+
return env === void 0 ? {} : { env };
|
|
44199
|
+
}
|
|
44200
|
+
|
|
44173
44201
|
// ../../packages/agent-client/dist/providers/claude/process.js
|
|
44174
44202
|
var import_node_child_process3 = require("node:child_process");
|
|
44175
44203
|
var import_node_crypto = require("node:crypto");
|
|
@@ -44198,7 +44226,11 @@ var ClaudeProcess = class {
|
|
|
44198
44226
|
if (options.brokerSocket != null) {
|
|
44199
44227
|
stdio[3] = options.brokerSocket;
|
|
44200
44228
|
}
|
|
44201
|
-
|
|
44229
|
+
const [spawnExecutable, ...spawnArgs] = spawnCmd;
|
|
44230
|
+
if (spawnExecutable === void 0) {
|
|
44231
|
+
throw new Error("Claude command wrapper returned no executable");
|
|
44232
|
+
}
|
|
44233
|
+
this.child = (0, import_node_child_process3.spawn)(spawnExecutable, spawnArgs, {
|
|
44202
44234
|
cwd: options.cwd?.trim() || void 0,
|
|
44203
44235
|
// Inherit the operator's env so the CLI picks up their own ~/.claude.json tool registry —
|
|
44204
44236
|
// unless an explicit mcpConfig was provided in options.
|
|
@@ -44546,7 +44578,7 @@ var ClaudeAgentHandle = class {
|
|
|
44546
44578
|
appendSystemPrompt: params.baseInstructions,
|
|
44547
44579
|
wrapCommand: this.wrapCommand,
|
|
44548
44580
|
brokerSocket: this.brokerSocket,
|
|
44549
|
-
...this.childEnv
|
|
44581
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
44550
44582
|
});
|
|
44551
44583
|
this.processes.set(child.sessionId, child);
|
|
44552
44584
|
this.mappers.set(child.sessionId, new ClaudeBridgeEventMapper());
|
|
@@ -44568,7 +44600,7 @@ var ClaudeAgentHandle = class {
|
|
|
44568
44600
|
appendSystemPrompt: params.baseInstructions,
|
|
44569
44601
|
wrapCommand: this.wrapCommand,
|
|
44570
44602
|
brokerSocket: this.brokerSocket,
|
|
44571
|
-
...this.childEnv
|
|
44603
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
44572
44604
|
});
|
|
44573
44605
|
this.processes.set(threadId, child);
|
|
44574
44606
|
this.mappers.set(threadId, new ClaudeBridgeEventMapper());
|
|
@@ -44740,7 +44772,11 @@ var AgyProcess = class _AgyProcess {
|
|
|
44740
44772
|
if (options.brokerSocket != null) {
|
|
44741
44773
|
stdio[3] = options.brokerSocket;
|
|
44742
44774
|
}
|
|
44743
|
-
|
|
44775
|
+
const [spawnExecutable, ...spawnArgs] = spawnCmd;
|
|
44776
|
+
if (spawnExecutable === void 0) {
|
|
44777
|
+
throw new Error("Agy command wrapper returned no executable");
|
|
44778
|
+
}
|
|
44779
|
+
this.child = (0, import_node_child_process4.spawn)(spawnExecutable, spawnArgs, {
|
|
44744
44780
|
cwd,
|
|
44745
44781
|
env: options.env ?? process.env,
|
|
44746
44782
|
stdio
|
|
@@ -45078,7 +45114,7 @@ var AgyAgentHandle = class {
|
|
|
45078
45114
|
wrapCommand: this.wrapCommand,
|
|
45079
45115
|
brokerSocket: this.brokerSocket,
|
|
45080
45116
|
disabledTools: this.disabledTools,
|
|
45081
|
-
...this.childEnv
|
|
45117
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
45082
45118
|
});
|
|
45083
45119
|
this.processes.set(child.sessionId, child);
|
|
45084
45120
|
this.mappers.set(child.sessionId, new AgyBridgeEventMapper());
|
|
@@ -45102,7 +45138,7 @@ var AgyAgentHandle = class {
|
|
|
45102
45138
|
wrapCommand: this.wrapCommand,
|
|
45103
45139
|
brokerSocket: this.brokerSocket,
|
|
45104
45140
|
disabledTools: this.disabledTools,
|
|
45105
|
-
...this.childEnv
|
|
45141
|
+
...envOption(threadProcessEnv(this.childEnv, params.env))
|
|
45106
45142
|
});
|
|
45107
45143
|
this.processes.set(threadId, child);
|
|
45108
45144
|
this.mappers.set(threadId, new AgyBridgeEventMapper());
|
|
@@ -45854,7 +45890,7 @@ async function resolvePinnedProviderIps(hosts, options) {
|
|
|
45854
45890
|
result[normalized] = records;
|
|
45855
45891
|
continue;
|
|
45856
45892
|
}
|
|
45857
|
-
} catch (
|
|
45893
|
+
} catch (_err) {
|
|
45858
45894
|
if (options?.failClosedOnDnsError) {
|
|
45859
45895
|
if ((process.env.NODE_ENV === "test" || !process.env.NODE_ENV || process.env.MRRLIN_TEST === "1") && DEFAULT_PINNED_PROVIDER_IPS[normalized]) {
|
|
45860
45896
|
result[normalized] = DEFAULT_PINNED_PROVIDER_IPS[normalized];
|
|
@@ -45917,6 +45953,8 @@ function parseIpv4Bytes(ip) {
|
|
|
45917
45953
|
const out = new Uint8Array(4);
|
|
45918
45954
|
for (let i = 0; i < 4; i++) {
|
|
45919
45955
|
const p = parts[i];
|
|
45956
|
+
if (p === void 0)
|
|
45957
|
+
return null;
|
|
45920
45958
|
if (!/^\d+$/.test(p))
|
|
45921
45959
|
return null;
|
|
45922
45960
|
if (p.length > 1 && p.startsWith("0"))
|
|
@@ -45950,10 +45988,13 @@ function parseIpv6Bytes(ip) {
|
|
|
45950
45988
|
}
|
|
45951
45989
|
const out = new Uint8Array(16);
|
|
45952
45990
|
if (v4Bytes) {
|
|
45953
|
-
|
|
45954
|
-
|
|
45955
|
-
|
|
45956
|
-
out[
|
|
45991
|
+
const [first, second, third, fourth] = v4Bytes;
|
|
45992
|
+
if (first === void 0 || second === void 0 || third === void 0 || fourth === void 0)
|
|
45993
|
+
return null;
|
|
45994
|
+
out[12] = first;
|
|
45995
|
+
out[13] = second;
|
|
45996
|
+
out[14] = third;
|
|
45997
|
+
out[15] = fourth;
|
|
45957
45998
|
}
|
|
45958
45999
|
const targetGroupCount = v4Bytes ? 6 : 8;
|
|
45959
46000
|
if (doubleColonIdx === -1) {
|
|
@@ -45962,6 +46003,8 @@ function parseIpv6Bytes(ip) {
|
|
|
45962
46003
|
return null;
|
|
45963
46004
|
for (let i = 0; i < targetGroupCount; i++) {
|
|
45964
46005
|
const g = groups[i];
|
|
46006
|
+
if (g === void 0)
|
|
46007
|
+
return null;
|
|
45965
46008
|
if (!/^[0-9a-f]{1,4}$/.test(g))
|
|
45966
46009
|
return null;
|
|
45967
46010
|
const val = parseInt(g, 16);
|
|
@@ -45977,6 +46020,8 @@ function parseIpv6Bytes(ip) {
|
|
|
45977
46020
|
return null;
|
|
45978
46021
|
for (let i = 0; i < leftGroups.length; i++) {
|
|
45979
46022
|
const g = leftGroups[i];
|
|
46023
|
+
if (g === void 0)
|
|
46024
|
+
return null;
|
|
45980
46025
|
if (!/^[0-9a-f]{1,4}$/.test(g))
|
|
45981
46026
|
return null;
|
|
45982
46027
|
const val = parseInt(g, 16);
|
|
@@ -45986,6 +46031,8 @@ function parseIpv6Bytes(ip) {
|
|
|
45986
46031
|
const omitted = targetGroupCount - leftGroups.length - rightGroups.length;
|
|
45987
46032
|
for (let i = 0; i < rightGroups.length; i++) {
|
|
45988
46033
|
const g = rightGroups[i];
|
|
46034
|
+
if (g === void 0)
|
|
46035
|
+
return null;
|
|
45989
46036
|
if (!/^[0-9a-f]{1,4}$/.test(g))
|
|
45990
46037
|
return null;
|
|
45991
46038
|
const val = parseInt(g, 16);
|
|
@@ -45997,9 +46044,9 @@ function parseIpv6Bytes(ip) {
|
|
|
45997
46044
|
return out;
|
|
45998
46045
|
}
|
|
45999
46046
|
function isRestrictedIpv4Bytes(b) {
|
|
46000
|
-
const b0 = b
|
|
46001
|
-
|
|
46002
|
-
|
|
46047
|
+
const [b0, b1, b2] = b;
|
|
46048
|
+
if (b0 === void 0 || b1 === void 0 || b2 === void 0)
|
|
46049
|
+
return true;
|
|
46003
46050
|
if (b0 === 0)
|
|
46004
46051
|
return true;
|
|
46005
46052
|
if (b0 === 10)
|
|
@@ -46067,9 +46114,13 @@ function isRestrictedIp(ip) {
|
|
|
46067
46114
|
}
|
|
46068
46115
|
if (isLoopback)
|
|
46069
46116
|
return true;
|
|
46070
|
-
|
|
46117
|
+
const firstByte = v6[0];
|
|
46118
|
+
const secondByte = v6[1];
|
|
46119
|
+
if (firstByte === void 0 || secondByte === void 0)
|
|
46120
|
+
return true;
|
|
46121
|
+
if (firstByte === 254 && (secondByte & 192) === 128)
|
|
46071
46122
|
return true;
|
|
46072
|
-
if ((
|
|
46123
|
+
if ((firstByte & 254) === 252)
|
|
46073
46124
|
return true;
|
|
46074
46125
|
if (v6[0] === 255)
|
|
46075
46126
|
return true;
|
|
@@ -46098,6 +46149,8 @@ function extractTlsSni(buf) {
|
|
|
46098
46149
|
if (offset >= buf.length)
|
|
46099
46150
|
return null;
|
|
46100
46151
|
const sidLen = buf[offset];
|
|
46152
|
+
if (sidLen === void 0)
|
|
46153
|
+
return null;
|
|
46101
46154
|
offset += 1 + sidLen;
|
|
46102
46155
|
if (offset + 2 > buf.length)
|
|
46103
46156
|
return null;
|
|
@@ -46106,6 +46159,8 @@ function extractTlsSni(buf) {
|
|
|
46106
46159
|
if (offset + 1 > buf.length)
|
|
46107
46160
|
return null;
|
|
46108
46161
|
const cmLen = buf[offset];
|
|
46162
|
+
if (cmLen === void 0)
|
|
46163
|
+
return null;
|
|
46109
46164
|
offset += 1 + cmLen;
|
|
46110
46165
|
if (offset + 2 > buf.length)
|
|
46111
46166
|
return null;
|
|
@@ -46124,6 +46179,8 @@ function extractTlsSni(buf) {
|
|
|
46124
46179
|
const sniEnd = Math.min(extensionsEnd, sniOffset + sniListLen);
|
|
46125
46180
|
while (sniOffset + 3 <= sniEnd) {
|
|
46126
46181
|
const nameType = buf[sniOffset];
|
|
46182
|
+
if (nameType === void 0)
|
|
46183
|
+
return null;
|
|
46127
46184
|
const nameLen = buf.readUInt16BE(sniOffset + 1);
|
|
46128
46185
|
sniOffset += 3;
|
|
46129
46186
|
if (nameType === 0) {
|
|
@@ -46225,7 +46282,13 @@ async function startProviderProxy(allowedHosts, options) {
|
|
|
46225
46282
|
return;
|
|
46226
46283
|
}
|
|
46227
46284
|
}
|
|
46228
|
-
const
|
|
46285
|
+
const firstAddress = addresses[0];
|
|
46286
|
+
if (!firstAddress) {
|
|
46287
|
+
res.writeHead(502, { "content-type": "text/plain" });
|
|
46288
|
+
res.end(`BAD_GATEWAY: DNS lookup failed for provider host "${effectiveHost}"`);
|
|
46289
|
+
return;
|
|
46290
|
+
}
|
|
46291
|
+
const validatedIp = options?.allowPrivateUpstream ? "127.0.0.1" : firstAddress.address;
|
|
46229
46292
|
const requestFn = isHttps ? import_node_https.default.request : import_node_http.default.request;
|
|
46230
46293
|
const transportOpts = {
|
|
46231
46294
|
host: validatedIp,
|
|
@@ -46304,7 +46367,12 @@ async function startProviderProxy(allowedHosts, options) {
|
|
|
46304
46367
|
return;
|
|
46305
46368
|
}
|
|
46306
46369
|
}
|
|
46307
|
-
const
|
|
46370
|
+
const firstAddress = addresses[0];
|
|
46371
|
+
if (!firstAddress) {
|
|
46372
|
+
clientSocket.end("HTTP/1.1 502 Bad Gateway\\r\\n\\r\\n");
|
|
46373
|
+
return;
|
|
46374
|
+
}
|
|
46375
|
+
const validatedIp = options?.allowPrivateUpstream ? "127.0.0.1" : firstAddress.address;
|
|
46308
46376
|
const serverSocket = import_node_net.default.connect({ host: validatedIp, port: targetPort }, () => {
|
|
46309
46377
|
clientSocket.write("HTTP/1.1 200 Connection Established\r\n\r\n");
|
|
46310
46378
|
let validatedAuthority = false;
|
|
@@ -46383,19 +46451,20 @@ async function startProviderProxy(allowedHosts, options) {
|
|
|
46383
46451
|
await new Promise((resolve2, reject) => {
|
|
46384
46452
|
server.on("error", reject);
|
|
46385
46453
|
if (options?.socketPath) {
|
|
46454
|
+
const socketPath = options.socketPath;
|
|
46386
46455
|
try {
|
|
46387
|
-
if (import_node_fs2.default.existsSync(
|
|
46388
|
-
import_node_fs2.default.unlinkSync(
|
|
46456
|
+
if (import_node_fs2.default.existsSync(socketPath)) {
|
|
46457
|
+
import_node_fs2.default.unlinkSync(socketPath);
|
|
46389
46458
|
}
|
|
46390
46459
|
} catch {
|
|
46391
46460
|
}
|
|
46392
|
-
server.listen(
|
|
46461
|
+
server.listen(socketPath, () => {
|
|
46393
46462
|
try {
|
|
46394
|
-
import_node_fs2.default.chmodSync(
|
|
46463
|
+
import_node_fs2.default.chmodSync(socketPath, 384);
|
|
46395
46464
|
} catch {
|
|
46396
46465
|
}
|
|
46397
46466
|
server.unref();
|
|
46398
|
-
assignedSocketPath =
|
|
46467
|
+
assignedSocketPath = socketPath;
|
|
46399
46468
|
resolve2();
|
|
46400
46469
|
});
|
|
46401
46470
|
} else {
|
|
@@ -46597,7 +46666,6 @@ async function createVerificationNetworkSandbox(config2) {
|
|
|
46597
46666
|
}
|
|
46598
46667
|
};
|
|
46599
46668
|
}
|
|
46600
|
-
const allPinnedIps = Array.from(new Set(Object.values(resolvedIpsMap).flat()));
|
|
46601
46669
|
const hostsLines = [
|
|
46602
46670
|
"127.0.0.1 localhost",
|
|
46603
46671
|
"::1 localhost",
|
|
@@ -47137,8 +47205,7 @@ exit $EXIT_CODE`,
|
|
|
47137
47205
|
dispose: () => {
|
|
47138
47206
|
try {
|
|
47139
47207
|
if (providerProxy) {
|
|
47140
|
-
providerProxy.close().catch(() =>
|
|
47141
|
-
});
|
|
47208
|
+
providerProxy.close().catch(() => void 0);
|
|
47142
47209
|
}
|
|
47143
47210
|
} catch {
|
|
47144
47211
|
}
|
|
@@ -50451,8 +50518,8 @@ var Protocol = class {
|
|
|
50451
50518
|
if (queuedMessage.type === "response") {
|
|
50452
50519
|
resolver(message);
|
|
50453
50520
|
} else {
|
|
50454
|
-
const
|
|
50455
|
-
const error51 = new McpError(
|
|
50521
|
+
const errorMessage2 = message;
|
|
50522
|
+
const error51 = new McpError(errorMessage2.error.code, errorMessage2.error.message, errorMessage2.error.data);
|
|
50456
50523
|
resolver(error51);
|
|
50457
50524
|
}
|
|
50458
50525
|
} else {
|
|
@@ -51758,8 +51825,8 @@ var Client = class extends Protocol {
|
|
|
51758
51825
|
const wrappedHandler = async (request, extra) => {
|
|
51759
51826
|
const validatedRequest = safeParse3(ElicitRequestSchema, request);
|
|
51760
51827
|
if (!validatedRequest.success) {
|
|
51761
|
-
const
|
|
51762
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation request: ${
|
|
51828
|
+
const errorMessage2 = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
|
|
51829
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation request: ${errorMessage2}`);
|
|
51763
51830
|
}
|
|
51764
51831
|
const { params } = validatedRequest.data;
|
|
51765
51832
|
params.mode = params.mode ?? "form";
|
|
@@ -51774,15 +51841,15 @@ var Client = class extends Protocol {
|
|
|
51774
51841
|
if (params.task) {
|
|
51775
51842
|
const taskValidationResult = safeParse3(CreateTaskResultSchema, result);
|
|
51776
51843
|
if (!taskValidationResult.success) {
|
|
51777
|
-
const
|
|
51778
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${
|
|
51844
|
+
const errorMessage2 = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
|
|
51845
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage2}`);
|
|
51779
51846
|
}
|
|
51780
51847
|
return taskValidationResult.data;
|
|
51781
51848
|
}
|
|
51782
51849
|
const validationResult = safeParse3(ElicitResultSchema, result);
|
|
51783
51850
|
if (!validationResult.success) {
|
|
51784
|
-
const
|
|
51785
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation result: ${
|
|
51851
|
+
const errorMessage2 = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
|
|
51852
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation result: ${errorMessage2}`);
|
|
51786
51853
|
}
|
|
51787
51854
|
const validatedResult = validationResult.data;
|
|
51788
51855
|
const requestedSchema = params.mode === "form" ? params.requestedSchema : void 0;
|
|
@@ -51802,16 +51869,16 @@ var Client = class extends Protocol {
|
|
|
51802
51869
|
const wrappedHandler = async (request, extra) => {
|
|
51803
51870
|
const validatedRequest = safeParse3(CreateMessageRequestSchema, request);
|
|
51804
51871
|
if (!validatedRequest.success) {
|
|
51805
|
-
const
|
|
51806
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid sampling request: ${
|
|
51872
|
+
const errorMessage2 = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
|
|
51873
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid sampling request: ${errorMessage2}`);
|
|
51807
51874
|
}
|
|
51808
51875
|
const { params } = validatedRequest.data;
|
|
51809
51876
|
const result = await Promise.resolve(handler(request, extra));
|
|
51810
51877
|
if (params.task) {
|
|
51811
51878
|
const taskValidationResult = safeParse3(CreateTaskResultSchema, result);
|
|
51812
51879
|
if (!taskValidationResult.success) {
|
|
51813
|
-
const
|
|
51814
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${
|
|
51880
|
+
const errorMessage2 = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
|
|
51881
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage2}`);
|
|
51815
51882
|
}
|
|
51816
51883
|
return taskValidationResult.data;
|
|
51817
51884
|
}
|
|
@@ -51819,8 +51886,8 @@ var Client = class extends Protocol {
|
|
|
51819
51886
|
const resultSchema = hasTools ? CreateMessageResultWithToolsSchema : CreateMessageResultSchema;
|
|
51820
51887
|
const validationResult = safeParse3(resultSchema, result);
|
|
51821
51888
|
if (!validationResult.success) {
|
|
51822
|
-
const
|
|
51823
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid sampling result: ${
|
|
51889
|
+
const errorMessage2 = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
|
|
51890
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid sampling result: ${errorMessage2}`);
|
|
51824
51891
|
}
|
|
51825
51892
|
return validationResult.data;
|
|
51826
51893
|
};
|
|
@@ -52048,18 +52115,18 @@ var Client = class extends Protocol {
|
|
|
52048
52115
|
}
|
|
52049
52116
|
return result;
|
|
52050
52117
|
}
|
|
52051
|
-
isToolTask(
|
|
52118
|
+
isToolTask(toolName2) {
|
|
52052
52119
|
if (!this._serverCapabilities?.tasks?.requests?.tools?.call) {
|
|
52053
52120
|
return false;
|
|
52054
52121
|
}
|
|
52055
|
-
return this._cachedKnownTaskTools.has(
|
|
52122
|
+
return this._cachedKnownTaskTools.has(toolName2);
|
|
52056
52123
|
}
|
|
52057
52124
|
/**
|
|
52058
52125
|
* Check if a tool requires task-based execution.
|
|
52059
52126
|
* Unlike isToolTask which includes 'optional' tools, this only checks for 'required'.
|
|
52060
52127
|
*/
|
|
52061
|
-
isToolTaskRequired(
|
|
52062
|
-
return this._cachedRequiredTaskTools.has(
|
|
52128
|
+
isToolTaskRequired(toolName2) {
|
|
52129
|
+
return this._cachedRequiredTaskTools.has(toolName2);
|
|
52063
52130
|
}
|
|
52064
52131
|
/**
|
|
52065
52132
|
* Cache validators for tool output schemas.
|
|
@@ -52086,8 +52153,8 @@ var Client = class extends Protocol {
|
|
|
52086
52153
|
/**
|
|
52087
52154
|
* Get cached validator for a tool
|
|
52088
52155
|
*/
|
|
52089
|
-
getToolOutputValidator(
|
|
52090
|
-
return this._cachedToolOutputValidators.get(
|
|
52156
|
+
getToolOutputValidator(toolName2) {
|
|
52157
|
+
return this._cachedToolOutputValidators.get(toolName2);
|
|
52091
52158
|
}
|
|
52092
52159
|
async listTools(params, options) {
|
|
52093
52160
|
const result = await this.request({ method: "tools/list", params }, ListToolsResultSchema, options);
|
|
@@ -52630,8 +52697,8 @@ async function parseErrorResponse(input) {
|
|
|
52630
52697
|
return new errorClass(error_description || "", error_uri);
|
|
52631
52698
|
} catch (error51) {
|
|
52632
52699
|
const redirect = input instanceof Response ? unfollowedRedirect(input, input.url) : void 0;
|
|
52633
|
-
const
|
|
52634
|
-
return new ServerError(
|
|
52700
|
+
const errorMessage2 = `${statusCode ? `HTTP ${statusCode}: ` : ""}${redirect ?? `Invalid OAuth error response: ${error51}. Raw body: ${body}`}`;
|
|
52701
|
+
return new ServerError(errorMessage2);
|
|
52635
52702
|
}
|
|
52636
52703
|
}
|
|
52637
52704
|
function issuersMatch(a, b) {
|
|
@@ -53974,7 +54041,7 @@ var StdioClientTransport = class {
|
|
|
53974
54041
|
};
|
|
53975
54042
|
|
|
53976
54043
|
// src/delivery/invoke.ts
|
|
53977
|
-
async function invokeCapability(server,
|
|
54044
|
+
async function invokeCapability(server, toolName2, payload) {
|
|
53978
54045
|
const client = new Client({ name: "mrrlin-delivery-invoker", version: "1.0.0" });
|
|
53979
54046
|
try {
|
|
53980
54047
|
let result;
|
|
@@ -54020,14 +54087,14 @@ async function invokeCapability(server, toolName, payload) {
|
|
|
54020
54087
|
await client.connect(transport);
|
|
54021
54088
|
}
|
|
54022
54089
|
result = await client.callTool({
|
|
54023
|
-
name:
|
|
54090
|
+
name: toolName2,
|
|
54024
54091
|
arguments: isRecord(payload) ? payload : void 0
|
|
54025
54092
|
});
|
|
54026
54093
|
} catch (error51) {
|
|
54027
|
-
throw classifyInvokeError(error51, target,
|
|
54094
|
+
throw classifyInvokeError(error51, target, toolName2);
|
|
54028
54095
|
}
|
|
54029
54096
|
if (result.isError) {
|
|
54030
|
-
throw new InvokeToolExecutionError(
|
|
54097
|
+
throw new InvokeToolExecutionError(toolName2, extractFirstText(result.content));
|
|
54031
54098
|
}
|
|
54032
54099
|
return { content: result.content, url: extractFirstUrl(result.content) };
|
|
54033
54100
|
} finally {
|
|
@@ -54036,14 +54103,14 @@ async function invokeCapability(server, toolName, payload) {
|
|
|
54036
54103
|
}
|
|
54037
54104
|
}
|
|
54038
54105
|
var InvokeToolNotFoundError = class extends Error {
|
|
54039
|
-
constructor(
|
|
54040
|
-
super(`invokeCapability: tool "${
|
|
54106
|
+
constructor(toolName2, cause) {
|
|
54107
|
+
super(`invokeCapability: tool "${toolName2}" not found on the granted server`, { cause });
|
|
54041
54108
|
this.name = "InvokeToolNotFoundError";
|
|
54042
54109
|
}
|
|
54043
54110
|
};
|
|
54044
54111
|
var InvokeToolExecutionError = class extends Error {
|
|
54045
|
-
constructor(
|
|
54046
|
-
super(`invokeCapability: tool "${
|
|
54112
|
+
constructor(toolName2, detail, cause) {
|
|
54113
|
+
super(`invokeCapability: tool "${toolName2}" reported isError -- ${detail}`, { cause });
|
|
54047
54114
|
this.name = "InvokeToolExecutionError";
|
|
54048
54115
|
}
|
|
54049
54116
|
};
|
|
@@ -54071,7 +54138,7 @@ var InvokeUnexpandedHeaderError = class extends Error {
|
|
|
54071
54138
|
this.name = "InvokeUnexpandedHeaderError";
|
|
54072
54139
|
}
|
|
54073
54140
|
};
|
|
54074
|
-
function classifyInvokeError(error51, url2,
|
|
54141
|
+
function classifyInvokeError(error51, url2, toolName2) {
|
|
54075
54142
|
if (error51 instanceof InvokeUnexpandedHeaderError) {
|
|
54076
54143
|
return error51;
|
|
54077
54144
|
}
|
|
@@ -54081,10 +54148,10 @@ function classifyInvokeError(error51, url2, toolName) {
|
|
|
54081
54148
|
}
|
|
54082
54149
|
if (error51 instanceof McpError) {
|
|
54083
54150
|
if (error51.code === ErrorCode.MethodNotFound) {
|
|
54084
|
-
return new InvokeToolNotFoundError(
|
|
54151
|
+
return new InvokeToolNotFoundError(toolName2, error51);
|
|
54085
54152
|
}
|
|
54086
54153
|
if (error51.code === ErrorCode.InvalidParams) {
|
|
54087
|
-
return new InvokeMalformedResultError(`invalid parameters for tool "${
|
|
54154
|
+
return new InvokeMalformedResultError(`invalid parameters for tool "${toolName2}": ${error51.message}`, error51);
|
|
54088
54155
|
}
|
|
54089
54156
|
return new InvokeMalformedResultError(error51.message, error51);
|
|
54090
54157
|
}
|
|
@@ -54160,12 +54227,12 @@ function parsePullRequestUrl(url2) {
|
|
|
54160
54227
|
}
|
|
54161
54228
|
return {};
|
|
54162
54229
|
}
|
|
54163
|
-
async function deliverToGit(server,
|
|
54230
|
+
async function deliverToGit(server, toolName2, payload) {
|
|
54164
54231
|
const defaultRoute = server.id ? getDefaultCapabilityRouteForServer(server.id) : null;
|
|
54165
54232
|
const isDefaultGitHubRoute = defaultRoute?.capability === "repo_host";
|
|
54166
54233
|
if (payload.operation === "pull_request") {
|
|
54167
54234
|
const { operation: _operation, ...args } = payload;
|
|
54168
|
-
if (isDefaultGitHubRoute &&
|
|
54235
|
+
if (isDefaultGitHubRoute && toolName2 === defaultRoute.operations.pull_request) {
|
|
54169
54236
|
let owner = args.owner;
|
|
54170
54237
|
let repo = args.repo;
|
|
54171
54238
|
const repository = args.repository;
|
|
@@ -54189,11 +54256,11 @@ async function deliverToGit(server, toolName, payload) {
|
|
|
54189
54256
|
if (typeof payload.draft === "boolean") {
|
|
54190
54257
|
adaptedArgs.draft = payload.draft;
|
|
54191
54258
|
}
|
|
54192
|
-
return invokeCapability(server,
|
|
54259
|
+
return invokeCapability(server, toolName2, adaptedArgs);
|
|
54193
54260
|
}
|
|
54194
|
-
return invokeCapability(server,
|
|
54261
|
+
return invokeCapability(server, toolName2, args);
|
|
54195
54262
|
}
|
|
54196
|
-
if (isDefaultGitHubRoute && (
|
|
54263
|
+
if (isDefaultGitHubRoute && (toolName2 === defaultRoute.operations.pull_request_state || toolName2 === "pull_request_read")) {
|
|
54197
54264
|
const { operation: _operation, ...args } = payload;
|
|
54198
54265
|
const urlParts = parsePullRequestUrl(payload.pullRequestUrl);
|
|
54199
54266
|
let owner = args.owner ?? urlParts.owner;
|
|
@@ -54209,16 +54276,16 @@ async function deliverToGit(server, toolName, payload) {
|
|
|
54209
54276
|
if (owner) adaptedArgs.owner = owner;
|
|
54210
54277
|
if (repo) adaptedArgs.repo = repo;
|
|
54211
54278
|
if (pullNumber !== void 0) {
|
|
54212
|
-
if (
|
|
54279
|
+
if (toolName2 === "pull_request_read") {
|
|
54213
54280
|
adaptedArgs.method = "get";
|
|
54214
54281
|
adaptedArgs.pullNumber = pullNumber;
|
|
54215
54282
|
} else {
|
|
54216
54283
|
adaptedArgs.pull_number = pullNumber;
|
|
54217
54284
|
}
|
|
54218
54285
|
}
|
|
54219
|
-
return invokeCapability(server,
|
|
54286
|
+
return invokeCapability(server, toolName2, adaptedArgs);
|
|
54220
54287
|
}
|
|
54221
|
-
return invokeCapability(server,
|
|
54288
|
+
return invokeCapability(server, toolName2, { pullRequestUrl: payload.pullRequestUrl });
|
|
54222
54289
|
}
|
|
54223
54290
|
|
|
54224
54291
|
// src/mcp-tool-error.ts
|
|
@@ -54297,11 +54364,11 @@ async function deliverToArtifacts(client, projectSlug, payload, bareFetch) {
|
|
|
54297
54364
|
}
|
|
54298
54365
|
|
|
54299
54366
|
// src/delivery/send.ts
|
|
54300
|
-
async function deliverToSend(server,
|
|
54367
|
+
async function deliverToSend(server, toolName2, payload) {
|
|
54301
54368
|
const { operation: _operation, ...args } = payload;
|
|
54302
54369
|
const defaultRoute = server.id ? getDefaultCapabilityRouteForServer(server.id) : null;
|
|
54303
54370
|
const isDefaultSlackRoute = defaultRoute?.capability === "send";
|
|
54304
|
-
if (payload.operation === "dispatch" && isDefaultSlackRoute &&
|
|
54371
|
+
if (payload.operation === "dispatch" && isDefaultSlackRoute && toolName2 === defaultRoute.operations.dispatch) {
|
|
54305
54372
|
const rawChannel = args.channel_id ?? args.destination ?? args.channel ?? args.to;
|
|
54306
54373
|
const channelId = typeof rawChannel === "string" ? rawChannel.trim() : rawChannel !== void 0 ? String(rawChannel) : void 0;
|
|
54307
54374
|
const rawText = args.text ?? args.body ?? args.message ?? args.content;
|
|
@@ -54309,15 +54376,15 @@ async function deliverToSend(server, toolName, payload) {
|
|
|
54309
54376
|
const adaptedArgs = {};
|
|
54310
54377
|
if (channelId !== void 0) adaptedArgs.channel_id = channelId;
|
|
54311
54378
|
if (text !== void 0) adaptedArgs.text = text;
|
|
54312
|
-
return invokeCapability(server,
|
|
54379
|
+
return invokeCapability(server, toolName2, adaptedArgs);
|
|
54313
54380
|
}
|
|
54314
|
-
return invokeCapability(server,
|
|
54381
|
+
return invokeCapability(server, toolName2, args);
|
|
54315
54382
|
}
|
|
54316
54383
|
|
|
54317
54384
|
// src/delivery/publish.ts
|
|
54318
|
-
async function deliverToPublish(server,
|
|
54385
|
+
async function deliverToPublish(server, toolName2, payload) {
|
|
54319
54386
|
const { operation: _operation, ...args } = payload;
|
|
54320
|
-
return invokeCapability(server,
|
|
54387
|
+
return invokeCapability(server, toolName2, args);
|
|
54321
54388
|
}
|
|
54322
54389
|
function parsePublishObserveResult(content) {
|
|
54323
54390
|
const raw = parseStructuredContent(content);
|
|
@@ -54472,7 +54539,7 @@ async function proceedToDestination(client, route, resolvedToolName, input) {
|
|
|
54472
54539
|
serverId: route.serverId,
|
|
54473
54540
|
capability: route.capability,
|
|
54474
54541
|
toolName: resolvedToolName,
|
|
54475
|
-
operationClass: route
|
|
54542
|
+
operationClass: resolveOperationClass(route, "reversible"),
|
|
54476
54543
|
payloadDigest
|
|
54477
54544
|
});
|
|
54478
54545
|
const idempotencyKey = `deliver:${input.taskProjectSlug}:${permit.id}`;
|
|
@@ -54492,7 +54559,7 @@ async function proceedToDestination(client, route, resolvedToolName, input) {
|
|
|
54492
54559
|
return {
|
|
54493
54560
|
ok: false,
|
|
54494
54561
|
reason: "invocation_failed",
|
|
54495
|
-
message:
|
|
54562
|
+
message: errorMessage(redemption.error) ?? "Capability invocation previously failed"
|
|
54496
54563
|
};
|
|
54497
54564
|
}
|
|
54498
54565
|
await recordUse(client, route, resolvedToolName, input, "refused");
|
|
@@ -54504,7 +54571,7 @@ async function proceedToDestination(client, route, resolvedToolName, input) {
|
|
|
54504
54571
|
}
|
|
54505
54572
|
} catch (permitError) {
|
|
54506
54573
|
await recordUse(client, route, resolvedToolName, input, "refused");
|
|
54507
|
-
const msg = permitError
|
|
54574
|
+
const msg = errorMessage(permitError) ?? String(permitError);
|
|
54508
54575
|
const isNoGrant = msg.includes("GRANT_REQUIRED") || msg.includes("no active grant");
|
|
54509
54576
|
return {
|
|
54510
54577
|
ok: false,
|
|
@@ -54799,7 +54866,7 @@ async function readPublishState(client, projectSlug, taskProjectSlug, payload, m
|
|
|
54799
54866
|
return redemption.result;
|
|
54800
54867
|
}
|
|
54801
54868
|
if (redemption.status === "failed") {
|
|
54802
|
-
const errMsg =
|
|
54869
|
+
const errMsg = errorMessage(redemption.error) ?? "Capability invocation previously failed";
|
|
54803
54870
|
throw new Error(`CAPABILITY_REPLAY_FAILED: ${errMsg}`);
|
|
54804
54871
|
}
|
|
54805
54872
|
throw new Error(`OPERATIONAL_INCIDENT: capability invocation ${redemption.id} is in status "${redemption.status}" and cannot be replayed as success`);
|
|
@@ -54866,7 +54933,7 @@ async function dispatchPublishOperation(client, projectSlug, taskProjectSlug, ta
|
|
|
54866
54933
|
serverId: route.serverId,
|
|
54867
54934
|
capability: route.capability,
|
|
54868
54935
|
toolName: resolvedToolName,
|
|
54869
|
-
operationClass: route
|
|
54936
|
+
operationClass: resolveOperationClass(route, payload.operation === "preview" ? "reversible" : "irreversible"),
|
|
54870
54937
|
payloadDigest
|
|
54871
54938
|
});
|
|
54872
54939
|
const idempotencyKey = `publish:${taskProjectSlug}:${permit.id}`;
|
|
@@ -54879,11 +54946,14 @@ async function dispatchPublishOperation(client, projectSlug, taskProjectSlug, ta
|
|
|
54879
54946
|
if (redemption.replayed) {
|
|
54880
54947
|
if (redemption.status === "completed") {
|
|
54881
54948
|
const use2 = await recordUse(client, route, resolvedToolName, input, "ok");
|
|
54882
|
-
|
|
54949
|
+
if (!isRecord3(redemption.result) || !("content" in redemption.result) || !("url" in redemption.result)) {
|
|
54950
|
+
throw new Error("CAPABILITY_REPLAY_INVALID_RESULT: completed publish invocation has no object result");
|
|
54951
|
+
}
|
|
54952
|
+
return { content: redemption.result.content, url: typeof redemption.result.url === "string" ? redemption.result.url : null, use: use2 };
|
|
54883
54953
|
}
|
|
54884
54954
|
if (redemption.status === "failed") {
|
|
54885
54955
|
const use2 = await recordUse(client, route, resolvedToolName, input, "error");
|
|
54886
|
-
const errMsg =
|
|
54956
|
+
const errMsg = errorMessage(redemption.error) ?? "Capability invocation previously failed";
|
|
54887
54957
|
throw Object.assign(new Error(`CAPABILITY_REPLAY_FAILED: ${errMsg}`), { use: use2 });
|
|
54888
54958
|
}
|
|
54889
54959
|
const use = await recordUse(client, route, resolvedToolName, input, "refused");
|
|
@@ -54928,8 +54998,8 @@ async function readPullRequestState(client, projectSlug, taskProjectSlug, pullRe
|
|
|
54928
54998
|
throw new RepoHostRouteUnavailableError(`repo_host capability route unavailable: ${resolution.reason}`);
|
|
54929
54999
|
}
|
|
54930
55000
|
const { route } = resolution;
|
|
54931
|
-
const
|
|
54932
|
-
if (typeof
|
|
55001
|
+
const toolName2 = route.operations.pull_request_state;
|
|
55002
|
+
if (typeof toolName2 !== "string") {
|
|
54933
55003
|
throw new RepoHostRouteUnavailableError('operation "pull_request_state" is not configured for repo_host capability');
|
|
54934
55004
|
}
|
|
54935
55005
|
const server = readMcpServerById(mcpConfigPath ?? defaultMcpConfigPath(), route.serverId);
|
|
@@ -54950,7 +55020,7 @@ async function readPullRequestState(client, projectSlug, taskProjectSlug, pullRe
|
|
|
54950
55020
|
taskId,
|
|
54951
55021
|
serverId: route.serverId,
|
|
54952
55022
|
capability: route.capability,
|
|
54953
|
-
toolName,
|
|
55023
|
+
toolName: toolName2,
|
|
54954
55024
|
operationClass: "read",
|
|
54955
55025
|
payloadDigest
|
|
54956
55026
|
});
|
|
@@ -54961,18 +55031,18 @@ async function readPullRequestState(client, projectSlug, taskProjectSlug, pullRe
|
|
|
54961
55031
|
payloadDigest
|
|
54962
55032
|
});
|
|
54963
55033
|
if (redemption.replayed) {
|
|
54964
|
-
if (redemption.status === "completed" && redemption.result && typeof redemption.result.merged === "boolean") {
|
|
55034
|
+
if (redemption.status === "completed" && isRecord3(redemption.result) && typeof redemption.result.merged === "boolean") {
|
|
54965
55035
|
return { merged: redemption.result.merged };
|
|
54966
55036
|
}
|
|
54967
55037
|
if (redemption.status === "failed") {
|
|
54968
|
-
const errMsg =
|
|
55038
|
+
const errMsg = errorMessage(redemption.error) ?? "Capability invocation previously failed";
|
|
54969
55039
|
throw new Error(`CAPABILITY_REPLAY_FAILED: ${errMsg}`);
|
|
54970
55040
|
}
|
|
54971
55041
|
throw new Error(`OPERATIONAL_INCIDENT: capability invocation ${redemption.id} is in status "${redemption.status}" and cannot be replayed as success`);
|
|
54972
55042
|
}
|
|
54973
55043
|
const invocationId = redemption.id;
|
|
54974
55044
|
try {
|
|
54975
|
-
const result = await deliverToGit(server,
|
|
55045
|
+
const result = await deliverToGit(server, toolName2, payload);
|
|
54976
55046
|
const raw = parseStructuredContent(result.content);
|
|
54977
55047
|
const parsed = gitPullRequestStateResponseSchema.safeParse(raw);
|
|
54978
55048
|
if (!parsed.success) {
|
|
@@ -55003,6 +55073,17 @@ async function readPullRequestState(client, projectSlug, taskProjectSlug, pullRe
|
|
|
55003
55073
|
function isRecord3(value) {
|
|
55004
55074
|
return typeof value === "object" && value !== null;
|
|
55005
55075
|
}
|
|
55076
|
+
function errorMessage(value) {
|
|
55077
|
+
if (typeof value === "string") return value;
|
|
55078
|
+
if (value instanceof Error) return value.message;
|
|
55079
|
+
if (isRecord3(value) && typeof value.message === "string") return value.message;
|
|
55080
|
+
return void 0;
|
|
55081
|
+
}
|
|
55082
|
+
function resolveOperationClass(route, fallback) {
|
|
55083
|
+
if (!isRecord3(route)) return fallback;
|
|
55084
|
+
const operationClass = route.operationClass;
|
|
55085
|
+
return operationClass === "read" || operationClass === "reversible" || operationClass === "irreversible" ? operationClass : fallback;
|
|
55086
|
+
}
|
|
55006
55087
|
|
|
55007
55088
|
// src/decision-consensus.ts
|
|
55008
55089
|
var ANCHOR_TIMEOUT_MS = Number(process.env["MRRLIN_DECISION_TIMEOUT_MS"] ?? 9e4);
|
|
@@ -55149,8 +55230,8 @@ var registry2 = /* @__PURE__ */ new Map();
|
|
|
55149
55230
|
function registerAsyncTool(descriptor2) {
|
|
55150
55231
|
registry2.set(descriptor2.toolName, descriptor2);
|
|
55151
55232
|
}
|
|
55152
|
-
function getAsyncToolDescriptor(
|
|
55153
|
-
return registry2.get(
|
|
55233
|
+
function getAsyncToolDescriptor(toolName2) {
|
|
55234
|
+
return registry2.get(toolName2);
|
|
55154
55235
|
}
|
|
55155
55236
|
|
|
55156
55237
|
// src/async-tools/consensus.ts
|
|
@@ -56793,12 +56874,12 @@ function buildProjection(payload, type, ms, telemetry) {
|
|
|
56793
56874
|
const tool = rawEvent.tool;
|
|
56794
56875
|
if (!isRecord4(tool)) return null;
|
|
56795
56876
|
const toolId = tool.id;
|
|
56796
|
-
const
|
|
56797
|
-
if (typeof toolId !== "string" || typeof
|
|
56877
|
+
const toolName2 = tool.name;
|
|
56878
|
+
if (typeof toolId !== "string" || typeof toolName2 !== "string") return null;
|
|
56798
56879
|
const input = tool.input;
|
|
56799
56880
|
const argKeys = isRecord4(input) ? Object.keys(input) : [];
|
|
56800
56881
|
const projectSlug = isRecord4(input) && typeof input.projectSlug === "string" ? input.projectSlug : void 0;
|
|
56801
|
-
const proj = { kind: "tool_use", toolId, toolName, argKeys, seq: maybeSeq ?? 0 };
|
|
56882
|
+
const proj = { kind: "tool_use", toolId, toolName: toolName2, argKeys, seq: maybeSeq ?? 0 };
|
|
56802
56883
|
if (maybeTurnId !== void 0) proj.turnId = maybeTurnId;
|
|
56803
56884
|
if (ms !== void 0) proj.ms = ms;
|
|
56804
56885
|
if (projectSlug !== void 0) proj.projectSlug = projectSlug;
|
|
@@ -56963,6 +57044,9 @@ var READ_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
56963
57044
|
"search_knowledge",
|
|
56964
57045
|
"search_wiki_pages",
|
|
56965
57046
|
"create_task",
|
|
57047
|
+
// propose_task only records a pending intent proposal; nothing happens until the operator
|
|
57048
|
+
// confirms it in the web UI, so it is as in-product as create_task.
|
|
57049
|
+
"propose_task",
|
|
56966
57050
|
"update_task",
|
|
56967
57051
|
"create_wiki_page",
|
|
56968
57052
|
"update_wiki_page",
|
|
@@ -56974,14 +57058,14 @@ var READ_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
56974
57058
|
// call), making every turn that stops a run permanently, unfixably "unresolved".
|
|
56975
57059
|
"stop_execution_run"
|
|
56976
57060
|
]);
|
|
56977
|
-
function normalizeToolName(
|
|
56978
|
-
return
|
|
57061
|
+
function normalizeToolName(toolName2) {
|
|
57062
|
+
return toolName2.replace(/^mcp__.+?__/, "");
|
|
56979
57063
|
}
|
|
56980
57064
|
var MRRLIN_MCP_NAMESPACE_PREFIXES = ["mcp__mrrlin__", "mcp__mrrlin-browser__"];
|
|
56981
57065
|
function classifyToolEffect(rawToolName) {
|
|
56982
|
-
const
|
|
56983
|
-
if (READ_TOOL_NAMES.has(
|
|
56984
|
-
if (OUTWARD_TOOL_NAMES.has(
|
|
57066
|
+
const toolName2 = normalizeToolName(rawToolName);
|
|
57067
|
+
if (READ_TOOL_NAMES.has(toolName2)) return "read";
|
|
57068
|
+
if (OUTWARD_TOOL_NAMES.has(toolName2)) return "outward";
|
|
56985
57069
|
if (MRRLIN_MCP_NAMESPACE_PREFIXES.some((prefix) => rawToolName.startsWith(prefix))) return "outward";
|
|
56986
57070
|
return "read";
|
|
56987
57071
|
}
|
|
@@ -56994,10 +57078,10 @@ var BROWSER_OUTWARD_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
56994
57078
|
"browser_select_option"
|
|
56995
57079
|
]);
|
|
56996
57080
|
var IN_PRODUCT_WRITE_TOOL_NAMES = /* @__PURE__ */ new Set(["create_task", "update_task", "create_wiki_page", "update_wiki_page", "create_inbox_item"]);
|
|
56997
|
-
function buildBrowserAttemptReceipt(
|
|
57081
|
+
function buildBrowserAttemptReceipt(toolName2) {
|
|
56998
57082
|
return {
|
|
56999
57083
|
kind: "attempt",
|
|
57000
|
-
evidence: { type: "human_tap", value:
|
|
57084
|
+
evidence: { type: "human_tap", value: toolName2 },
|
|
57001
57085
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
57002
57086
|
requiresCovered: []
|
|
57003
57087
|
};
|
|
@@ -57127,20 +57211,20 @@ function createBridgeLogger(stateDir, env = process.env) {
|
|
|
57127
57211
|
if (isNewTurn) state.pending = [];
|
|
57128
57212
|
}
|
|
57129
57213
|
if (projection?.kind === "tool_use" && typeof projection.toolName === "string" && typeof projection.toolId === "string") {
|
|
57130
|
-
const
|
|
57214
|
+
const toolName2 = normalizeToolName(projection.toolName);
|
|
57131
57215
|
if (classifyToolEffect(projection.toolName) === "outward") {
|
|
57132
|
-
if (BROWSER_OUTWARD_TOOL_NAMES.has(
|
|
57133
|
-
syntheticReceipt = buildBrowserAttemptReceipt(
|
|
57216
|
+
if (BROWSER_OUTWARD_TOOL_NAMES.has(toolName2)) {
|
|
57217
|
+
syntheticReceipt = buildBrowserAttemptReceipt(toolName2);
|
|
57134
57218
|
} else {
|
|
57135
57219
|
state.pending.push({
|
|
57136
57220
|
turnSpanId: projection.turnId,
|
|
57137
|
-
toolName,
|
|
57221
|
+
toolName: toolName2,
|
|
57138
57222
|
toolId: projection.toolId,
|
|
57139
57223
|
seq: projection.seq,
|
|
57140
57224
|
armedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
57141
57225
|
});
|
|
57142
57226
|
}
|
|
57143
|
-
} else if (IN_PRODUCT_WRITE_TOOL_NAMES.has(
|
|
57227
|
+
} else if (IN_PRODUCT_WRITE_TOOL_NAMES.has(toolName2) && state.pending.length > 0) {
|
|
57144
57228
|
if (state.pending.length > 1) {
|
|
57145
57229
|
recordingObligationMultiResolve = {
|
|
57146
57230
|
resolvedCount: state.pending.length,
|
|
@@ -57348,10 +57432,10 @@ async function assembleEvidence(stateDir, sessionId, reportId, gateCtx) {
|
|
|
57348
57432
|
if (line.projection?.kind !== "tool_use") continue;
|
|
57349
57433
|
const rawToolId = line.payload?.event?.tool?.id;
|
|
57350
57434
|
const paired = typeof rawToolId === "string" ? resultByToolId.get(rawToolId) : void 0;
|
|
57351
|
-
const
|
|
57435
|
+
const toolName2 = line.projection.toolName ?? line.payload?.event?.tool?.name ?? "";
|
|
57352
57436
|
const ms = line.projection.ms ?? 0;
|
|
57353
57437
|
const outcome = paired?.projection?.kind === "tool_result" ? paired.projection.outcome ?? "unknown" : "unknown";
|
|
57354
|
-
const step = { toolName, ms, outcome };
|
|
57438
|
+
const step = { toolName: toolName2, ms, outcome };
|
|
57355
57439
|
if (paired?.projection?.kind === "tool_result" && paired.projection.exitCode !== void 0) {
|
|
57356
57440
|
step.exitCode = paired.projection.exitCode;
|
|
57357
57441
|
}
|
|
@@ -57728,6 +57812,7 @@ var mcpToolNames = {
|
|
|
57728
57812
|
deleteTaskDependency: "delete_task_dependency",
|
|
57729
57813
|
createInboxItem: "create_inbox_item",
|
|
57730
57814
|
createTask: "create_task",
|
|
57815
|
+
proposeTask: "propose_task",
|
|
57731
57816
|
decideInboxItem: "decide_inbox_item",
|
|
57732
57817
|
getExecutionRun: "get_execution_run",
|
|
57733
57818
|
getProjectSchedulerPolicy: "get_project_scheduler_policy",
|
|
@@ -58350,6 +58435,22 @@ var listTasksInputSchema = projectScopedSchema.merge(mrrlinTaskListFiltersSchema
|
|
|
58350
58435
|
var getTaskInputSchema = taskScopedSchema;
|
|
58351
58436
|
var createTaskInputSchema = proposalProvenanceSchema.merge(projectScopedSchema).merge(mrrlinTaskCreateWithoutIdSchema);
|
|
58352
58437
|
var updateTaskInputSchema = taskScopedSchema.merge(mrrlinTaskUpdateSchema);
|
|
58438
|
+
var proposeTaskInputSchema = projectScopedSchema.extend({
|
|
58439
|
+
kind: external_exports.enum(["task", "plan"]).optional().describe("What the operator's confirmation creates. 'task' (default): the task itself. 'plan': nothing yet \u2014 call create_plan with the confirmed proposalId/proposalVersion/proposalDigest."),
|
|
58440
|
+
title: external_exports.string().min(1).max(500),
|
|
58441
|
+
notes: external_exports.string().max(2e4).optional(),
|
|
58442
|
+
type: mrrlinTaskTypeSchema.optional(),
|
|
58443
|
+
category: external_exports.string().min(1).optional(),
|
|
58444
|
+
subcategory: external_exports.string().min(1).optional(),
|
|
58445
|
+
impact: mrrlinTaskImpactSchema.optional(),
|
|
58446
|
+
autonomyLevel: mrrlinAutonomyLevelSchema.optional(),
|
|
58447
|
+
autonomyReason: external_exports.string().min(1).max(240).optional(),
|
|
58448
|
+
autoDeploy: mrrlinAutoDeploySchema.optional(),
|
|
58449
|
+
domains: mrrlinTaskDomainsSchema.optional(),
|
|
58450
|
+
tags: external_exports.array(external_exports.string().min(1)).optional(),
|
|
58451
|
+
planId: mrrlinPlanIdSchema.optional(),
|
|
58452
|
+
specWikiPageId: mrrlinWikiPageIdSchema.optional()
|
|
58453
|
+
});
|
|
58353
58454
|
var resetDirectorThreadInputSchema = taskScopedSchema;
|
|
58354
58455
|
var archiveTaskInputSchema = taskScopedSchema;
|
|
58355
58456
|
var unarchiveTaskInputSchema = taskScopedSchema;
|
|
@@ -58487,6 +58588,7 @@ var mcpToolInputSchemas = {
|
|
|
58487
58588
|
[mcpToolNames.createWikiPage]: createWikiPageInputSchema,
|
|
58488
58589
|
[mcpToolNames.deleteTaskDependency]: deleteTaskDependencyInputSchema,
|
|
58489
58590
|
[mcpToolNames.createTask]: createTaskInputSchema,
|
|
58591
|
+
[mcpToolNames.proposeTask]: proposeTaskInputSchema,
|
|
58490
58592
|
[mcpToolNames.getExecutionRun]: getExecutionRunInputSchema,
|
|
58491
58593
|
[mcpToolNames.getProjectSchedulerPolicy]: getProjectSchedulerPolicyInputSchema,
|
|
58492
58594
|
[mcpToolNames.getSchedulerPendingTasks]: getSchedulerPendingTasksInputSchema,
|
|
@@ -58551,6 +58653,7 @@ var mcpToolOperationIds = {
|
|
|
58551
58653
|
[mcpToolNames.createWikiPage]: openApiOperationIds.createWikiPage,
|
|
58552
58654
|
[mcpToolNames.deleteTaskDependency]: openApiOperationIds.deleteTaskDependency,
|
|
58553
58655
|
[mcpToolNames.createTask]: openApiOperationIds.createTask,
|
|
58656
|
+
[mcpToolNames.proposeTask]: openApiOperationIds.createIntentProposal,
|
|
58554
58657
|
[mcpToolNames.getExecutionRun]: openApiOperationIds.getExecutionRun,
|
|
58555
58658
|
[mcpToolNames.getProjectSchedulerPolicy]: openApiOperationIds.getProjectSchedulerPolicy,
|
|
58556
58659
|
[mcpToolNames.getSchedulerPendingTasks]: openApiOperationIds.getSchedulerPendingTasks,
|
|
@@ -58605,7 +58708,8 @@ var mcpToolDescriptions = {
|
|
|
58605
58708
|
[mcpToolNames.appendTaskEvent]: "Append an operator note to a task's activity timeline. Also use it as the task-linked receipt path for material immediate work that has a parent task; summarize scope, outcome/no-result, evidence or artifacts, blockers, and next action in the note body.",
|
|
58606
58709
|
[mcpToolNames.createWikiPage]: "Create a markdown Wiki page.",
|
|
58607
58710
|
[mcpToolNames.deleteTaskDependency]: "Delete a blocked-by relationship.",
|
|
58608
|
-
[mcpToolNames.
|
|
58711
|
+
[mcpToolNames.proposeTask]: "Propose a task (or plan) for the operator to confirm. This is how work gets created: a proposal does nothing on its own; the operator sees it in the Director chat and confirms it, and that confirmation creates the task. It binds to the operator's latest message in this chat, so call it right after the operator asked for the work, in the same turn. Call it once per task. Then tell the operator, in plain words, that the task is waiting for their confirmation in the chat \u2014 never say it was created. A new operator message makes an unconfirmed proposal stale; propose again if the operator still wants it. Fails with NO_OPERATOR_TRANSCRIPT when the operator has not said anything this proposal could quote.",
|
|
58712
|
+
[mcpToolNames.createTask]: "Only for a proposal the operator already confirmed: pass its proposalId, proposalVersion and proposalDigest. A confirmed task proposal has already created its task, and this returns that task; never call it to create new work \u2014 use propose_task. Create a new task in a project. Defaults to status='todo' to authorize immediate autopilot work; pass status='backlog' only if explicitly parking the task for later. 'backlog' and 'todo' are the only creatable statuses. Pass parentTaskId when spawning a follow-up task to continue work from an existing task \u2014 its operator_seed_request is inherited automatically if you don't supply your own. Domain is required UNLESS parentTaskId is supplied (a follow-up inherits its parent's domain automatically). Domain selects which reviewer roster judges the task's spec. Valid values: code, seo, marketing, content. When creating tasks for work that produces a published web page, author the work as a [code_change] task and a [page] task (with domain: 'content') linked by blocked_by. Set autoDeploy according to the publish policy: 'prod' if only meaningful once live (robots.txt, sitemap), 'dev' to stop at preview (landing page, layout), or 'off' if the repo is not the operator's own.",
|
|
58609
58713
|
[mcpToolNames.getProject]: "Fetch a single project summary by slug.",
|
|
58610
58714
|
[mcpToolNames.getProjectSnapshot]: "Fetch the full project snapshot: GitHub binding, tasks, plans, and wiki pages.",
|
|
58611
58715
|
[mcpToolNames.getTask]: "Fetch a single task by project slug and task id.",
|
|
@@ -58850,6 +58954,7 @@ async function getAgentProviderForPanel(client, opts = {}) {
|
|
|
58850
58954
|
function createMrrlinTools(options) {
|
|
58851
58955
|
const client = createMrrlinClient(withAuth(options));
|
|
58852
58956
|
async function resolveBoundSlug() {
|
|
58957
|
+
if (process.env.MRRLIN_PROJECT_BINDING === "none") return void 0;
|
|
58853
58958
|
if (options.activeProjectSlug !== void 0) return options.activeProjectSlug;
|
|
58854
58959
|
const envSlug = process.env.MRRLIN_PROJECT_SLUG?.trim();
|
|
58855
58960
|
if (envSlug) return envSlug;
|
|
@@ -59049,10 +59154,35 @@ function createMrrlinTools(options) {
|
|
|
59049
59154
|
`Task materialization digest mismatch for proposal ${proposalId} v${proposalVersion}.`
|
|
59050
59155
|
);
|
|
59051
59156
|
}
|
|
59157
|
+
if (confirmation.materializedTaskId) {
|
|
59158
|
+
return await c.getTask(projectSlug, confirmation.materializedTaskId);
|
|
59159
|
+
}
|
|
59052
59160
|
const status = input.status ?? "todo";
|
|
59053
59161
|
return await c.createTask(projectSlug, { ...input, status });
|
|
59054
59162
|
}
|
|
59055
59163
|
),
|
|
59164
|
+
[mcpToolNames.proposeTask]: makeTool(
|
|
59165
|
+
client,
|
|
59166
|
+
mcpToolNames.proposeTask,
|
|
59167
|
+
"TASK_PROPOSE_FAILED",
|
|
59168
|
+
"Unable to propose task.",
|
|
59169
|
+
async (c, { projectSlug, kind, ...intent }) => {
|
|
59170
|
+
await checkTenantBoundary(projectSlug, "task proposal");
|
|
59171
|
+
const proposal = await c.createIntentProposal(projectSlug, {
|
|
59172
|
+
resolvedIntent: { kind: kind ?? "task", ...intent }
|
|
59173
|
+
});
|
|
59174
|
+
return {
|
|
59175
|
+
proposalId: proposal.proposalId,
|
|
59176
|
+
proposalVersion: proposal.version,
|
|
59177
|
+
proposalDigest: proposal.digest,
|
|
59178
|
+
state: proposal.state,
|
|
59179
|
+
kind: kind ?? "task",
|
|
59180
|
+
title: intent.title,
|
|
59181
|
+
awaitingOperatorConfirmation: true,
|
|
59182
|
+
next: (kind ?? "task") === "task" ? "Tell the operator the task is waiting for their confirmation in the chat. Their confirmation creates it; do not call create_task." : "Tell the operator the plan is waiting for their confirmation in the chat. After they confirm, call create_plan with proposalId, proposalVersion and proposalDigest."
|
|
59183
|
+
};
|
|
59184
|
+
}
|
|
59185
|
+
),
|
|
59056
59186
|
[mcpToolNames.getProject]: makeTool(
|
|
59057
59187
|
client,
|
|
59058
59188
|
mcpToolNames.getProject,
|
|
@@ -61611,7 +61741,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
|
|
|
61611
61741
|
}
|
|
61612
61742
|
|
|
61613
61743
|
// src/_generated/version.ts
|
|
61614
|
-
var PKG_VERSION = "0.4.
|
|
61744
|
+
var PKG_VERSION = "0.4.109";
|
|
61615
61745
|
|
|
61616
61746
|
// src/receipt-signing.ts
|
|
61617
61747
|
var import_node_crypto13 = __toESM(require("node:crypto"), 1);
|
|
@@ -61838,26 +61968,26 @@ function turnReferences(events) {
|
|
|
61838
61968
|
if (event.type === "tool_use") {
|
|
61839
61969
|
hasToolEvents = true;
|
|
61840
61970
|
const rawName = event.tool?.name ?? event.name ?? "";
|
|
61841
|
-
const
|
|
61842
|
-
const isMutation = MUTATION_TOOLS.has(
|
|
61971
|
+
const toolName2 = rawName.replace(/^.*__/, "");
|
|
61972
|
+
const isMutation = MUTATION_TOOLS.has(toolName2);
|
|
61843
61973
|
const inputObj = event.tool?.input && typeof event.tool.input === "object" ? event.tool.input : event.input && typeof event.input === "object" ? event.input : {};
|
|
61844
61974
|
const rawTargetId = typeof inputObj.taskId === "string" ? inputObj.taskId : typeof inputObj.pageId === "string" ? inputObj.pageId : typeof inputObj.id === "string" ? inputObj.id : null;
|
|
61845
61975
|
let targetId = null;
|
|
61846
61976
|
if (rawTargetId) {
|
|
61847
|
-
if ((
|
|
61977
|
+
if ((toolName2 === "create_task" || toolName2 === "update_task") && /^GT-\d+$/.test(rawTargetId)) {
|
|
61848
61978
|
targetId = rawTargetId;
|
|
61849
|
-
} else if ((
|
|
61979
|
+
} else if ((toolName2 === "create_wiki_page" || toolName2 === "update_wiki_page") && /^WK-\d+$/.test(rawTargetId)) {
|
|
61850
61980
|
targetId = rawTargetId;
|
|
61851
61981
|
}
|
|
61852
61982
|
}
|
|
61853
61983
|
const callId = event.tool?.id ?? event.tool_use_id ?? event.id;
|
|
61854
61984
|
if (callId && typeof callId === "string") {
|
|
61855
61985
|
if (isMutation) {
|
|
61856
|
-
keyedPending.set(callId, { toolName, targetId });
|
|
61986
|
+
keyedPending.set(callId, { toolName: toolName2, targetId });
|
|
61857
61987
|
}
|
|
61858
61988
|
} else {
|
|
61859
61989
|
if (isMutation) {
|
|
61860
|
-
unkeyedCalls.push({ isMutation: true, toolName, targetId });
|
|
61990
|
+
unkeyedCalls.push({ isMutation: true, toolName: toolName2, targetId });
|
|
61861
61991
|
} else {
|
|
61862
61992
|
unkeyedCalls.push({ isMutation: false });
|
|
61863
61993
|
}
|
|
@@ -66306,7 +66436,7 @@ ${renderTaskStateSection(taskState)}`;
|
|
|
66306
66436
|
turnCwd = worktreePath;
|
|
66307
66437
|
useExecutor = true;
|
|
66308
66438
|
if (deps.acquireExecutorAgent) {
|
|
66309
|
-
const executorAgent = await deps.acquireExecutorAgent(worktreePath, resolvedProviderId);
|
|
66439
|
+
const executorAgent = await deps.acquireExecutorAgent(worktreePath, resolvedProviderId, projectSlug);
|
|
66310
66440
|
codex = executorAgent.handle;
|
|
66311
66441
|
disposeCodex = executorAgent.dispose;
|
|
66312
66442
|
} else {
|
|
@@ -67818,13 +67948,13 @@ async function driveAsyncJob(deps, projectSlug, jobId) {
|
|
|
67818
67948
|
}
|
|
67819
67949
|
if (descriptor2.wakeDirector) deps.wake(projectSlug, claimed.directorSessionId, delivery.body, delivery.kind);
|
|
67820
67950
|
}
|
|
67821
|
-
async function deriveRequestedHash(client,
|
|
67951
|
+
async function deriveRequestedHash(client, toolName2, input) {
|
|
67822
67952
|
if (input.requestedHash) return input.requestedHash;
|
|
67823
|
-
if (
|
|
67953
|
+
if (toolName2 === "run_spec_consensus" && input.pageId) {
|
|
67824
67954
|
const page = await client.getWikiPage(input.projectSlug, input.pageId);
|
|
67825
67955
|
return page.contentHash ?? import_node_crypto18.default.createHash("sha256").update(page.markdownBody).digest("hex");
|
|
67826
67956
|
}
|
|
67827
|
-
if (
|
|
67957
|
+
if (toolName2 === "draft_task_spec" && input.taskId) {
|
|
67828
67958
|
const task = await client.getTask(input.projectSlug, input.taskId);
|
|
67829
67959
|
return task.updatedAt ?? import_node_crypto18.default.createHash("sha256").update(JSON.stringify(task)).digest("hex");
|
|
67830
67960
|
}
|
|
@@ -72168,18 +72298,19 @@ async function startExecutorServer(opts) {
|
|
|
72168
72298
|
const childEnv = withDisabledGitHooksEnv(baseEnv, opts.disabledGitHooksDir);
|
|
72169
72299
|
const baseSpawn = opts.spawn ?? import_node_child_process22.spawn;
|
|
72170
72300
|
const hasExtraFd = opts.brokerSocket != null || opts.brokerSocketFd != null;
|
|
72171
|
-
const spawnFn = (cmd, args, spawnOpts) => {
|
|
72172
|
-
const argList =
|
|
72173
|
-
const optsObj = args && !Array.isArray(args) ? args : spawnOpts ?? {};
|
|
72301
|
+
const spawnFn = (cmd, args = [], spawnOpts = {}) => {
|
|
72302
|
+
const argList = [...args];
|
|
72174
72303
|
const fullCmd = [cmd, ...argList];
|
|
72175
72304
|
const wrapped = opts.wrapCommand ? opts.wrapCommand(fullCmd) : fullCmd;
|
|
72176
|
-
const finalSpawnOpts = { ...
|
|
72305
|
+
const finalSpawnOpts = { ...spawnOpts };
|
|
72177
72306
|
if (hasExtraFd) {
|
|
72178
|
-
const stdio = Array.isArray(finalSpawnOpts
|
|
72307
|
+
const stdio = Array.isArray(finalSpawnOpts.stdio) ? [...finalSpawnOpts.stdio] : ["pipe", "pipe", "pipe"];
|
|
72179
72308
|
stdio[3] = opts.brokerSocket ?? opts.brokerSocketFd;
|
|
72180
72309
|
finalSpawnOpts.stdio = stdio;
|
|
72181
72310
|
}
|
|
72182
|
-
|
|
72311
|
+
const executable = wrapped[0];
|
|
72312
|
+
if (!executable) throw new Error("command wrapper returned an empty command");
|
|
72313
|
+
return baseSpawn(executable, wrapped.slice(1), finalSpawnOpts);
|
|
72183
72314
|
};
|
|
72184
72315
|
if (opts.provider === "codex") {
|
|
72185
72316
|
const manager = new CodexServerManager();
|
|
@@ -72429,19 +72560,21 @@ function parseIpv4Numeric(ipStr) {
|
|
|
72429
72560
|
parsedParts.push(n);
|
|
72430
72561
|
}
|
|
72431
72562
|
if (parsedParts.length === 4) {
|
|
72432
|
-
for (const
|
|
72433
|
-
if (
|
|
72563
|
+
for (const b2 of parsedParts) {
|
|
72564
|
+
if (b2 > 255) return null;
|
|
72434
72565
|
}
|
|
72435
|
-
|
|
72566
|
+
const [a, b, c, d] = parsedParts;
|
|
72567
|
+
if (a === void 0 || b === void 0 || c === void 0 || d === void 0) return null;
|
|
72568
|
+
return [a, b, c, d];
|
|
72436
72569
|
}
|
|
72437
72570
|
if (parsedParts.length === 3) {
|
|
72438
72571
|
const [a, b, c] = parsedParts;
|
|
72439
|
-
if (a > 255 || b > 255 || c > 65535) return null;
|
|
72572
|
+
if (a === void 0 || b === void 0 || c === void 0 || a > 255 || b > 255 || c > 65535) return null;
|
|
72440
72573
|
return [a, b, c >>> 8 & 255, c & 255];
|
|
72441
72574
|
}
|
|
72442
72575
|
if (parsedParts.length === 2) {
|
|
72443
72576
|
const [a, b] = parsedParts;
|
|
72444
|
-
if (a > 255 || b > 16777215) return null;
|
|
72577
|
+
if (a === void 0 || b === void 0 || a > 255 || b > 16777215) return null;
|
|
72445
72578
|
return [a, b >>> 16 & 255, b >>> 8 & 255, b & 255];
|
|
72446
72579
|
}
|
|
72447
72580
|
return null;
|
|
@@ -72475,14 +72608,14 @@ function isGlobalIpv6(ipStr) {
|
|
|
72475
72608
|
}
|
|
72476
72609
|
const mappedMatch = /^::ffff:(?:0:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i.exec(clean);
|
|
72477
72610
|
if (mappedMatch) {
|
|
72478
|
-
const ipv43 = parseIpv4Numeric(mappedMatch[1]);
|
|
72611
|
+
const ipv43 = parseIpv4Numeric(mappedMatch[1] ?? "");
|
|
72479
72612
|
if (!ipv43) return false;
|
|
72480
72613
|
return isGlobalIpv4(ipv43);
|
|
72481
72614
|
}
|
|
72482
72615
|
const hexMappedMatch = /^::ffff:(?:0:)?([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i.exec(clean);
|
|
72483
72616
|
if (hexMappedMatch) {
|
|
72484
|
-
const high = Number.parseInt(hexMappedMatch[1], 16);
|
|
72485
|
-
const low = Number.parseInt(hexMappedMatch[2], 16);
|
|
72617
|
+
const high = Number.parseInt(hexMappedMatch[1] ?? "", 16);
|
|
72618
|
+
const low = Number.parseInt(hexMappedMatch[2] ?? "", 16);
|
|
72486
72619
|
const b0 = high >>> 8 & 255;
|
|
72487
72620
|
const b1 = high & 255;
|
|
72488
72621
|
const b2 = low >>> 8 & 255;
|
|
@@ -72492,13 +72625,13 @@ function isGlobalIpv6(ipStr) {
|
|
|
72492
72625
|
if (clean.startsWith("::ffff:")) return false;
|
|
72493
72626
|
const compatMatch = /^::(?:0:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i.exec(clean);
|
|
72494
72627
|
if (compatMatch) {
|
|
72495
|
-
const ipv43 = parseIpv4Numeric(compatMatch[1]);
|
|
72628
|
+
const ipv43 = parseIpv4Numeric(compatMatch[1] ?? "");
|
|
72496
72629
|
if (!ipv43) return false;
|
|
72497
72630
|
return isGlobalIpv4(ipv43);
|
|
72498
72631
|
}
|
|
72499
72632
|
const nat64Match = /^64:ff9b::(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i.exec(clean);
|
|
72500
72633
|
if (nat64Match) {
|
|
72501
|
-
const ipv43 = parseIpv4Numeric(nat64Match[1]);
|
|
72634
|
+
const ipv43 = parseIpv4Numeric(nat64Match[1] ?? "");
|
|
72502
72635
|
if (!ipv43) return false;
|
|
72503
72636
|
return isGlobalIpv4(ipv43);
|
|
72504
72637
|
}
|
|
@@ -72618,7 +72751,9 @@ async function resolveAndPinAddress(hostname3, customResolver) {
|
|
|
72618
72751
|
}
|
|
72619
72752
|
return {
|
|
72620
72753
|
hostname: cleanHost,
|
|
72621
|
-
pinnedIp: allIps[0]
|
|
72754
|
+
pinnedIp: allIps[0] ?? (() => {
|
|
72755
|
+
throw new Error("DNS_RESOLUTION_FAILED: empty address set");
|
|
72756
|
+
})(),
|
|
72622
72757
|
allIps
|
|
72623
72758
|
};
|
|
72624
72759
|
}
|
|
@@ -72748,11 +72883,11 @@ async function createVerificationBrokerSession(options) {
|
|
|
72748
72883
|
clearTimeout(timer);
|
|
72749
72884
|
try {
|
|
72750
72885
|
res.destroy();
|
|
72751
|
-
} catch {
|
|
72886
|
+
} catch (error51) {
|
|
72752
72887
|
}
|
|
72753
72888
|
try {
|
|
72754
72889
|
req.destroy();
|
|
72755
|
-
} catch {
|
|
72890
|
+
} catch (error51) {
|
|
72756
72891
|
}
|
|
72757
72892
|
reject(err);
|
|
72758
72893
|
};
|
|
@@ -72783,7 +72918,7 @@ async function createVerificationBrokerSession(options) {
|
|
|
72783
72918
|
if (decompressedBytes > maxDecompBytes) {
|
|
72784
72919
|
try {
|
|
72785
72920
|
decompressor.destroy();
|
|
72786
|
-
} catch {
|
|
72921
|
+
} catch (error51) {
|
|
72787
72922
|
}
|
|
72788
72923
|
fail(new Error(`DECOMPRESSION_LIMIT_EXCEEDED: decompressed body exceeded ${maxDecompBytes} bytes`));
|
|
72789
72924
|
}
|
|
@@ -72948,12 +73083,12 @@ async function createVerificationBrokerSession(options) {
|
|
|
72948
73083
|
server.close();
|
|
72949
73084
|
try {
|
|
72950
73085
|
if (import_node_fs22.default.existsSync(socketPath)) import_node_fs22.default.unlinkSync(socketPath);
|
|
72951
|
-
} catch {
|
|
73086
|
+
} catch (error51) {
|
|
72952
73087
|
}
|
|
72953
73088
|
if (createdDir) {
|
|
72954
73089
|
try {
|
|
72955
73090
|
import_node_fs22.default.rmSync(createdDir, { recursive: true, force: true });
|
|
72956
|
-
} catch {
|
|
73091
|
+
} catch (error51) {
|
|
72957
73092
|
}
|
|
72958
73093
|
}
|
|
72959
73094
|
throw new Error(`BROKER_SOCKET_ERROR: failed to establish inherited client socket connection: ${String(err)}`);
|
|
@@ -72973,7 +73108,7 @@ async function createVerificationBrokerSession(options) {
|
|
|
72973
73108
|
if (clientSocket) {
|
|
72974
73109
|
try {
|
|
72975
73110
|
clientSocket.destroy();
|
|
72976
|
-
} catch {
|
|
73111
|
+
} catch (error51) {
|
|
72977
73112
|
}
|
|
72978
73113
|
}
|
|
72979
73114
|
await new Promise((resolve2) => {
|
|
@@ -72997,6 +73132,31 @@ async function createVerificationBrokerSession(options) {
|
|
|
72997
73132
|
}
|
|
72998
73133
|
|
|
72999
73134
|
// src/verification-turn.ts
|
|
73135
|
+
function runtimeHandle(handle) {
|
|
73136
|
+
return handle;
|
|
73137
|
+
}
|
|
73138
|
+
function toolName(tool) {
|
|
73139
|
+
if (typeof tool === "string") return tool;
|
|
73140
|
+
if (tool !== null && typeof tool === "object") {
|
|
73141
|
+
const descriptor2 = tool;
|
|
73142
|
+
if (typeof descriptor2.name === "string") return descriptor2.name;
|
|
73143
|
+
if (typeof descriptor2.function?.name === "string") return descriptor2.function.name;
|
|
73144
|
+
}
|
|
73145
|
+
return "";
|
|
73146
|
+
}
|
|
73147
|
+
function disabledToolFromEvent(event, disabledTools) {
|
|
73148
|
+
if (event === null || typeof event !== "object") return null;
|
|
73149
|
+
const record2 = event;
|
|
73150
|
+
if (record2.type !== "tool_use") return null;
|
|
73151
|
+
const name = typeof record2.tool?.name === "string" ? record2.tool.name : null;
|
|
73152
|
+
if (name === null) return null;
|
|
73153
|
+
return disabledTools.some((tool) => tool.toLowerCase() === name.toLowerCase()) ? name : null;
|
|
73154
|
+
}
|
|
73155
|
+
function isDnsNoData(error51) {
|
|
73156
|
+
if (error51 === null || typeof error51 !== "object") return false;
|
|
73157
|
+
const code = error51.code;
|
|
73158
|
+
return code === "ENODATA" || code === "ENOTFOUND";
|
|
73159
|
+
}
|
|
73000
73160
|
var DISABLED_NATIVE_VERIFICATION_TOOLS = [
|
|
73001
73161
|
"WebFetch",
|
|
73002
73162
|
"WebSearch",
|
|
@@ -73007,42 +73167,40 @@ var DISABLED_NATIVE_VERIFICATION_TOOLS = [
|
|
|
73007
73167
|
"curl"
|
|
73008
73168
|
];
|
|
73009
73169
|
var DisabledToolInvocationError = class extends Error {
|
|
73010
|
-
constructor(
|
|
73011
|
-
super(`TOOL_INVOCATION_FORBIDDEN: native network tool "${
|
|
73170
|
+
constructor(toolName2) {
|
|
73171
|
+
super(`TOOL_INVOCATION_FORBIDDEN: native network tool "${toolName2}" is disabled in verification isolation mode`);
|
|
73012
73172
|
this.name = "DisabledToolInvocationError";
|
|
73013
73173
|
}
|
|
73014
73174
|
};
|
|
73015
|
-
function assertNativeToolsDisabled(
|
|
73175
|
+
function assertNativeToolsDisabled(toolName2, disabledTools = DISABLED_NATIVE_VERIFICATION_TOOLS) {
|
|
73016
73176
|
const disabledSet = new Set(disabledTools.map((t) => t.toLowerCase()));
|
|
73017
|
-
if (disabledSet.has(
|
|
73018
|
-
throw new DisabledToolInvocationError(
|
|
73177
|
+
if (disabledSet.has(toolName2.toLowerCase())) {
|
|
73178
|
+
throw new DisabledToolInvocationError(toolName2);
|
|
73019
73179
|
}
|
|
73020
73180
|
}
|
|
73021
73181
|
function enforceNativeToolsDisabled(handle, disabledTools = DISABLED_NATIVE_VERIFICATION_TOOLS) {
|
|
73022
73182
|
const disabledSet = new Set(disabledTools.map((t) => t.toLowerCase()));
|
|
73183
|
+
const extendedHandle = runtimeHandle(handle);
|
|
73023
73184
|
for (const prop of ["tools", "availableTools", "registeredTools"]) {
|
|
73024
|
-
const val =
|
|
73185
|
+
const val = extendedHandle[prop];
|
|
73025
73186
|
if (Array.isArray(val)) {
|
|
73026
|
-
|
|
73027
|
-
const name = typeof t === "string" ? t : t?.name ?? t?.function?.name ?? "";
|
|
73028
|
-
return !disabledSet.has(String(name).toLowerCase());
|
|
73029
|
-
});
|
|
73187
|
+
extendedHandle[prop] = val.filter((tool) => !disabledSet.has(toolName(tool).toLowerCase()));
|
|
73030
73188
|
}
|
|
73031
73189
|
}
|
|
73032
|
-
const toolsConfig =
|
|
73190
|
+
const toolsConfig = extendedHandle.toolsConfig;
|
|
73033
73191
|
if (toolsConfig && typeof toolsConfig === "object") {
|
|
73034
73192
|
for (const tool of disabledTools) {
|
|
73035
73193
|
toolsConfig[tool] = false;
|
|
73036
73194
|
toolsConfig[tool.toLowerCase()] = false;
|
|
73037
73195
|
}
|
|
73038
73196
|
}
|
|
73039
|
-
if (typeof
|
|
73197
|
+
if (typeof extendedHandle.disableNativeTools === "function") {
|
|
73040
73198
|
try {
|
|
73041
|
-
|
|
73042
|
-
} catch {
|
|
73199
|
+
extendedHandle.disableNativeTools(disabledTools);
|
|
73200
|
+
} catch (error51) {
|
|
73043
73201
|
}
|
|
73044
73202
|
}
|
|
73045
|
-
|
|
73203
|
+
extendedHandle.disabledTools = disabledTools;
|
|
73046
73204
|
return handle;
|
|
73047
73205
|
}
|
|
73048
73206
|
function createVerificationTurnRunner(baseRunTurn, disabledTools = DISABLED_NATIVE_VERIFICATION_TOOLS) {
|
|
@@ -73051,11 +73209,12 @@ function createVerificationTurnRunner(baseRunTurn, disabledTools = DISABLED_NATI
|
|
|
73051
73209
|
throw new Error("INVALID_AGENT_HANDLE: handle is required for verification turn runner");
|
|
73052
73210
|
}
|
|
73053
73211
|
enforceNativeToolsDisabled(handle, disabledTools);
|
|
73054
|
-
|
|
73212
|
+
const extendedHandle = runtimeHandle(handle);
|
|
73213
|
+
let origExecute;
|
|
73055
73214
|
let didPatchExecute = false;
|
|
73056
|
-
let origStartThread
|
|
73057
|
-
let origResumeThread
|
|
73058
|
-
let origStartTurn
|
|
73215
|
+
let origStartThread;
|
|
73216
|
+
let origResumeThread;
|
|
73217
|
+
let origStartTurn;
|
|
73059
73218
|
const unsubscribes = [];
|
|
73060
73219
|
const subscribedThreads = /* @__PURE__ */ new Set();
|
|
73061
73220
|
let toolViolationError = null;
|
|
@@ -73065,32 +73224,26 @@ function createVerificationTurnRunner(baseRunTurn, disabledTools = DISABLED_NATI
|
|
|
73065
73224
|
if (typeof handle.onEvent === "function") {
|
|
73066
73225
|
try {
|
|
73067
73226
|
const unsub = handle.onEvent(threadId, (event) => {
|
|
73068
|
-
|
|
73069
|
-
|
|
73070
|
-
|
|
73071
|
-
|
|
73072
|
-
|
|
73073
|
-
|
|
73074
|
-
|
|
73075
|
-
handle.interruptTurn(threadId).catch(() => {
|
|
73076
|
-
});
|
|
73077
|
-
} catch {
|
|
73078
|
-
}
|
|
73079
|
-
}
|
|
73080
|
-
break;
|
|
73081
|
-
}
|
|
73227
|
+
const disabledTool = disabledToolFromEvent(event, disabledTools);
|
|
73228
|
+
if (disabledTool !== null) {
|
|
73229
|
+
toolViolationError = new DisabledToolInvocationError(disabledTool);
|
|
73230
|
+
try {
|
|
73231
|
+
void handle.interruptTurn(threadId).catch((error51) => {
|
|
73232
|
+
});
|
|
73233
|
+
} catch (error51) {
|
|
73082
73234
|
}
|
|
73083
73235
|
}
|
|
73084
73236
|
});
|
|
73085
73237
|
unsubscribes.push(unsub);
|
|
73086
|
-
} catch {
|
|
73238
|
+
} catch (error51) {
|
|
73087
73239
|
}
|
|
73088
73240
|
}
|
|
73089
73241
|
};
|
|
73090
73242
|
if (typeof handle.startThread === "function") {
|
|
73091
|
-
|
|
73243
|
+
const startThread = handle.startThread;
|
|
73244
|
+
origStartThread = startThread;
|
|
73092
73245
|
handle.startThread = async (params) => {
|
|
73093
|
-
const res = await
|
|
73246
|
+
const res = await startThread.call(handle, params);
|
|
73094
73247
|
if (res?.threadId) {
|
|
73095
73248
|
subscribeThread(res.threadId);
|
|
73096
73249
|
}
|
|
@@ -73098,9 +73251,10 @@ function createVerificationTurnRunner(baseRunTurn, disabledTools = DISABLED_NATI
|
|
|
73098
73251
|
};
|
|
73099
73252
|
}
|
|
73100
73253
|
if (typeof handle.resumeThread === "function") {
|
|
73101
|
-
|
|
73254
|
+
const resumeThread = handle.resumeThread;
|
|
73255
|
+
origResumeThread = resumeThread;
|
|
73102
73256
|
handle.resumeThread = async (threadId, params) => {
|
|
73103
|
-
const res = await
|
|
73257
|
+
const res = await resumeThread.call(handle, threadId, params);
|
|
73104
73258
|
if (res?.threadId) {
|
|
73105
73259
|
subscribeThread(res.threadId);
|
|
73106
73260
|
}
|
|
@@ -73108,44 +73262,39 @@ function createVerificationTurnRunner(baseRunTurn, disabledTools = DISABLED_NATI
|
|
|
73108
73262
|
};
|
|
73109
73263
|
}
|
|
73110
73264
|
if (typeof handle.startTurn === "function") {
|
|
73111
|
-
|
|
73265
|
+
const startTurn = handle.startTurn;
|
|
73266
|
+
origStartTurn = startTurn;
|
|
73112
73267
|
handle.startTurn = async (threadId, input, effort) => {
|
|
73113
73268
|
if (threadId) {
|
|
73114
73269
|
subscribeThread(threadId);
|
|
73115
73270
|
}
|
|
73116
|
-
return
|
|
73271
|
+
return startTurn.call(handle, threadId, input, effort);
|
|
73117
73272
|
};
|
|
73118
73273
|
}
|
|
73119
73274
|
if (typeof handle.onEvent === "function" && typeof handle.startThread !== "function") {
|
|
73120
73275
|
try {
|
|
73121
73276
|
const unsub = handle.onEvent("*", (event) => {
|
|
73122
|
-
|
|
73123
|
-
|
|
73124
|
-
|
|
73125
|
-
|
|
73126
|
-
|
|
73127
|
-
|
|
73128
|
-
|
|
73129
|
-
handle.interruptTurn("*").catch(() => {
|
|
73130
|
-
});
|
|
73131
|
-
} catch {
|
|
73132
|
-
}
|
|
73133
|
-
}
|
|
73134
|
-
break;
|
|
73135
|
-
}
|
|
73277
|
+
const disabledTool = disabledToolFromEvent(event, disabledTools);
|
|
73278
|
+
if (disabledTool !== null) {
|
|
73279
|
+
toolViolationError = new DisabledToolInvocationError(disabledTool);
|
|
73280
|
+
try {
|
|
73281
|
+
void handle.interruptTurn("*").catch((error51) => {
|
|
73282
|
+
});
|
|
73283
|
+
} catch (error51) {
|
|
73136
73284
|
}
|
|
73137
73285
|
}
|
|
73138
73286
|
});
|
|
73139
73287
|
unsubscribes.push(unsub);
|
|
73140
|
-
} catch {
|
|
73288
|
+
} catch (error51) {
|
|
73141
73289
|
}
|
|
73142
73290
|
}
|
|
73143
|
-
if (typeof
|
|
73144
|
-
|
|
73291
|
+
if (typeof extendedHandle.executeTool === "function") {
|
|
73292
|
+
const executeTool = extendedHandle.executeTool;
|
|
73293
|
+
origExecute = executeTool;
|
|
73145
73294
|
didPatchExecute = true;
|
|
73146
|
-
|
|
73295
|
+
extendedHandle.executeTool = async (name, args) => {
|
|
73147
73296
|
assertNativeToolsDisabled(name, disabledTools);
|
|
73148
|
-
return
|
|
73297
|
+
return executeTool.call(handle, name, args);
|
|
73149
73298
|
};
|
|
73150
73299
|
}
|
|
73151
73300
|
try {
|
|
@@ -73158,14 +73307,14 @@ function createVerificationTurnRunner(baseRunTurn, disabledTools = DISABLED_NATI
|
|
|
73158
73307
|
for (const unsub of unsubscribes) {
|
|
73159
73308
|
try {
|
|
73160
73309
|
unsub();
|
|
73161
|
-
} catch {
|
|
73310
|
+
} catch (error51) {
|
|
73162
73311
|
}
|
|
73163
73312
|
}
|
|
73164
73313
|
if (origStartThread) handle.startThread = origStartThread;
|
|
73165
73314
|
if (origResumeThread) handle.resumeThread = origResumeThread;
|
|
73166
73315
|
if (origStartTurn) handle.startTurn = origStartTurn;
|
|
73167
73316
|
if (didPatchExecute && origExecute) {
|
|
73168
|
-
|
|
73317
|
+
extendedHandle.executeTool = origExecute;
|
|
73169
73318
|
}
|
|
73170
73319
|
}
|
|
73171
73320
|
};
|
|
@@ -73245,7 +73394,7 @@ function createRunVerificationTurn(deps) {
|
|
|
73245
73394
|
let v6 = [];
|
|
73246
73395
|
try {
|
|
73247
73396
|
v4 = await import_node_dns2.default.promises.resolve4(normalizedUrl.hostname).catch((err) => {
|
|
73248
|
-
if (err
|
|
73397
|
+
if (isDnsNoData(err)) return [];
|
|
73249
73398
|
throw err;
|
|
73250
73399
|
});
|
|
73251
73400
|
} catch (err) {
|
|
@@ -73257,7 +73406,7 @@ function createRunVerificationTurn(deps) {
|
|
|
73257
73406
|
}
|
|
73258
73407
|
try {
|
|
73259
73408
|
v6 = await import_node_dns2.default.promises.resolve6(normalizedUrl.hostname).catch((err) => {
|
|
73260
|
-
if (err
|
|
73409
|
+
if (isDnsNoData(err)) return [];
|
|
73261
73410
|
throw err;
|
|
73262
73411
|
});
|
|
73263
73412
|
} catch (err) {
|
|
@@ -73302,7 +73451,7 @@ function createRunVerificationTurn(deps) {
|
|
|
73302
73451
|
if (!brokerSession.clientSocket) {
|
|
73303
73452
|
try {
|
|
73304
73453
|
await brokerSession.close();
|
|
73305
|
-
} catch {
|
|
73454
|
+
} catch (error51) {
|
|
73306
73455
|
}
|
|
73307
73456
|
return {
|
|
73308
73457
|
verdict: "fail",
|
|
@@ -73323,7 +73472,7 @@ function createRunVerificationTurn(deps) {
|
|
|
73323
73472
|
if (brokerSession) {
|
|
73324
73473
|
try {
|
|
73325
73474
|
await brokerSession.close();
|
|
73326
|
-
} catch {
|
|
73475
|
+
} catch (error51) {
|
|
73327
73476
|
}
|
|
73328
73477
|
}
|
|
73329
73478
|
return { verdict: "fail", summary: `network sandbox initialization failed: ${String(err)}`, turnRef: null };
|
|
@@ -73338,13 +73487,13 @@ function createRunVerificationTurn(deps) {
|
|
|
73338
73487
|
if (sandboxHandle) {
|
|
73339
73488
|
try {
|
|
73340
73489
|
sandboxHandle.dispose();
|
|
73341
|
-
} catch {
|
|
73490
|
+
} catch (error51) {
|
|
73342
73491
|
}
|
|
73343
73492
|
}
|
|
73344
73493
|
if (brokerSession) {
|
|
73345
73494
|
try {
|
|
73346
73495
|
await brokerSession.close();
|
|
73347
|
-
} catch {
|
|
73496
|
+
} catch (error51) {
|
|
73348
73497
|
}
|
|
73349
73498
|
}
|
|
73350
73499
|
return {
|
|
@@ -73370,13 +73519,13 @@ function createRunVerificationTurn(deps) {
|
|
|
73370
73519
|
if (sandboxHandle) {
|
|
73371
73520
|
try {
|
|
73372
73521
|
sandboxHandle.dispose();
|
|
73373
|
-
} catch {
|
|
73522
|
+
} catch (error51) {
|
|
73374
73523
|
}
|
|
73375
73524
|
}
|
|
73376
73525
|
if (brokerSession) {
|
|
73377
73526
|
try {
|
|
73378
73527
|
await brokerSession.close();
|
|
73379
|
-
} catch {
|
|
73528
|
+
} catch (error51) {
|
|
73380
73529
|
}
|
|
73381
73530
|
}
|
|
73382
73531
|
return { verdict: "fail", summary: `agent sandbox startup failed: ${String(err)}`, turnRef: null };
|
|
@@ -73385,19 +73534,19 @@ function createRunVerificationTurn(deps) {
|
|
|
73385
73534
|
if (agentSandbox) {
|
|
73386
73535
|
try {
|
|
73387
73536
|
agentSandbox.dispose();
|
|
73388
|
-
} catch {
|
|
73537
|
+
} catch (error51) {
|
|
73389
73538
|
}
|
|
73390
73539
|
}
|
|
73391
73540
|
if (sandboxHandle) {
|
|
73392
73541
|
try {
|
|
73393
73542
|
sandboxHandle.dispose();
|
|
73394
|
-
} catch {
|
|
73543
|
+
} catch (error51) {
|
|
73395
73544
|
}
|
|
73396
73545
|
}
|
|
73397
73546
|
if (brokerSession) {
|
|
73398
73547
|
try {
|
|
73399
73548
|
await brokerSession.close();
|
|
73400
|
-
} catch {
|
|
73549
|
+
} catch (error51) {
|
|
73401
73550
|
}
|
|
73402
73551
|
}
|
|
73403
73552
|
return {
|
|
@@ -73422,19 +73571,19 @@ function createRunVerificationTurn(deps) {
|
|
|
73422
73571
|
if (agentSandbox) {
|
|
73423
73572
|
try {
|
|
73424
73573
|
agentSandbox.dispose();
|
|
73425
|
-
} catch {
|
|
73574
|
+
} catch (error51) {
|
|
73426
73575
|
}
|
|
73427
73576
|
}
|
|
73428
73577
|
if (sandboxHandle) {
|
|
73429
73578
|
try {
|
|
73430
73579
|
sandboxHandle.dispose();
|
|
73431
|
-
} catch {
|
|
73580
|
+
} catch (error51) {
|
|
73432
73581
|
}
|
|
73433
73582
|
}
|
|
73434
73583
|
if (brokerSession) {
|
|
73435
73584
|
try {
|
|
73436
73585
|
await brokerSession.close();
|
|
73437
|
-
} catch {
|
|
73586
|
+
} catch (error51) {
|
|
73438
73587
|
}
|
|
73439
73588
|
}
|
|
73440
73589
|
}
|
|
@@ -74204,6 +74353,13 @@ function neutralCheckoutCwd(stateDir) {
|
|
|
74204
74353
|
}
|
|
74205
74354
|
return dir;
|
|
74206
74355
|
}
|
|
74356
|
+
function directorThreadEnv(projectSlug) {
|
|
74357
|
+
const slug = projectSlug ?? "";
|
|
74358
|
+
if (!slug || slug.length > 200 || /[\s\p{Cc}]/u.test(slug)) {
|
|
74359
|
+
return { MRRLIN_PROJECT_SLUG: null, MRRLIN_PROJECT_BINDING: "none" };
|
|
74360
|
+
}
|
|
74361
|
+
return { MRRLIN_PROJECT_SLUG: slug, MRRLIN_PROJECT_BINDING: null };
|
|
74362
|
+
}
|
|
74207
74363
|
function buildThreadStartParams(msg, config2, desiredModel) {
|
|
74208
74364
|
const baseInstructions = [
|
|
74209
74365
|
"You are the Mrrlin Director assistant.",
|
|
@@ -74241,10 +74397,10 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
74241
74397
|
"- Every read or write of Mrrlin data \u2014 tasks, plans, wiki pages, inbox items, execution runs,",
|
|
74242
74398
|
" projects \u2014 must go through the corresponding typed MCP tool. Never use `commandExecution`,",
|
|
74243
74399
|
" `curl`, `python`, or any direct HTTP call to the Mrrlin API.",
|
|
74244
|
-
"-
|
|
74245
|
-
" `subcategory`, `impact`, `autonomyLevel`, `planId`,
|
|
74246
|
-
"
|
|
74247
|
-
" for
|
|
74400
|
+
"- New work is created through `propose_task`, one call per task: it accepts `title`, `notes`,",
|
|
74401
|
+
" `category`, `subcategory`, `impact`, `autonomyLevel`, `planId`, and more in one call. The",
|
|
74402
|
+
" operator confirms the proposal in the chat, and that confirmation creates the task \u2014 you do",
|
|
74403
|
+
" not call `create_task` for it. Do not propose then patch.",
|
|
74248
74404
|
"- `commandExecution` is for the operator's own machine and repositories \u2014 running builds, tests,",
|
|
74249
74405
|
" `git`, inspecting local files \u2014 and for public third-party web checks. It is not a transport",
|
|
74250
74406
|
" for this product's API.",
|
|
@@ -74327,11 +74483,12 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
74327
74483
|
"NOT add words of your own.",
|
|
74328
74484
|
"",
|
|
74329
74485
|
"Once the operator replies and clarifies or confirms the scope (or if scope was already clear),",
|
|
74330
|
-
"you MUST
|
|
74331
|
-
"
|
|
74332
|
-
"
|
|
74333
|
-
"
|
|
74334
|
-
"
|
|
74486
|
+
"you MUST propose the tasks in the same turn: call `propose_task` once per task (`kind: 'plan'` for",
|
|
74487
|
+
"a plan) so the operator gets a confirmation card for each one immediately. Never leave the",
|
|
74488
|
+
"operator with nothing to confirm after agreeing on scope. Never claim tasks are created, queued,",
|
|
74489
|
+
"or ready before the operator confirmed them: say they are waiting for the operator's confirmation",
|
|
74490
|
+
"in the chat. Proposals bind to the operator's latest message, so propose in the same turn as the",
|
|
74491
|
+
"request \u2014 a later operator message makes an unconfirmed proposal stale.",
|
|
74335
74492
|
"When referring to created tasks or where to view them, use natural, human-friendly language with a markdown link",
|
|
74336
74493
|
"to the Tasks page (e.g. 'on the [Tasks page](/tasks)', '[Tasks board](/tasks)', or in Ukrainian '\u043D\u0430 [\u0441\u0442\u043E\u0440\u0456\u043D\u0446\u0456 \u0437\u0430\u0434\u0430\u0447](/tasks)').",
|
|
74337
74494
|
"Never output raw technical URL fragments like '\u043D\u0430 /tasks' or 'on /tasks', and never use developer database",
|
|
@@ -74618,7 +74775,10 @@ function buildThreadStartParams(msg, config2, desiredModel) {
|
|
|
74618
74775
|
model: desiredModel,
|
|
74619
74776
|
baseInstructions,
|
|
74620
74777
|
developerInstructions: null,
|
|
74621
|
-
ephemeral: null
|
|
74778
|
+
ephemeral: null,
|
|
74779
|
+
// Claude and Agy spawn a process per thread and every Director turn starts or resumes one,
|
|
74780
|
+
// so the turn's own project always reaches the child, including after a project switch.
|
|
74781
|
+
env: directorThreadEnv(msg.context?.projectSlug)
|
|
74622
74782
|
};
|
|
74623
74783
|
}
|
|
74624
74784
|
function readEnvInt(name, fallback) {
|
|
@@ -75990,7 +76150,15 @@ function createBridgeMessageHandler(deps) {
|
|
|
75990
76150
|
project: projectContext,
|
|
75991
76151
|
answeredQuestions,
|
|
75992
76152
|
openQuestions: presentedLedger.shown.length ? presentedLedger.shown : void 0,
|
|
75993
|
-
clarifications: msg.context?.clarifications ?? (presentedLedger.shown.some((i) => i.id) ? presentedLedger.shown
|
|
76153
|
+
clarifications: msg.context?.clarifications ?? (presentedLedger.shown.some((i) => i.id) ? presentedLedger.shown.map(({ id, round, ordinal, question, status, answer, actor }) => ({
|
|
76154
|
+
id,
|
|
76155
|
+
round,
|
|
76156
|
+
ordinal,
|
|
76157
|
+
question,
|
|
76158
|
+
status,
|
|
76159
|
+
answer,
|
|
76160
|
+
actor
|
|
76161
|
+
})) : void 0),
|
|
75994
76162
|
directorSessionId
|
|
75995
76163
|
});
|
|
75996
76164
|
const sendInTurn = (msg2) => {
|
|
@@ -76698,9 +76866,12 @@ async function startDirectorBridge() {
|
|
|
76698
76866
|
// Task 1.11: providerId is the caller's own pinned/minted seat (execution-consumer.ts's
|
|
76699
76867
|
// resolvedProviderId), not resolved ambiently here — this run-scoped spawn has no business
|
|
76700
76868
|
// re-reading a setting that could have moved since the run's own seat was decided.
|
|
76701
|
-
acquireExecutorAgent: async (worktreePath, providerId) => {
|
|
76869
|
+
acquireExecutorAgent: async (worktreePath, providerId, projectSlug) => {
|
|
76702
76870
|
const executor = await startExecutorServer({
|
|
76703
76871
|
worktree: worktreePath,
|
|
76872
|
+
// The run's provider process carries exactly its own project (or none), so its Mrrlin MCP
|
|
76873
|
+
// server is bound to it and never to whatever the bridge's environment names.
|
|
76874
|
+
env: threadProcessEnv(process.env, directorThreadEnv(projectSlug)),
|
|
76704
76875
|
disabledGitHooksDir: prepareDisabledGitHooksDir(import_node_path40.default.join(config2.stateDir, "locks"), import_node_path40.default.basename(worktreePath)),
|
|
76705
76876
|
provider: providerId
|
|
76706
76877
|
});
|
|
@@ -77631,7 +77802,7 @@ function renderContextPrefix(context) {
|
|
|
77631
77802
|
}
|
|
77632
77803
|
if (context?.activeProposal) {
|
|
77633
77804
|
parts.push(
|
|
77634
|
-
`[ACTIVE PROPOSAL] Proposal ID: ${context.activeProposal.id} (version ${context.activeProposal.version}). Work
|
|
77805
|
+
`[ACTIVE PROPOSAL] Proposal ID: ${context.activeProposal.id} (version ${context.activeProposal.version}). Work is created only by the operator confirming a proposal in the chat; propose new work with propose_task. create_plan, and create_task for an already-confirmed proposal, need its proposalId, proposalVersion, and proposalDigest.`
|
|
77635
77806
|
);
|
|
77636
77807
|
}
|
|
77637
77808
|
if (context?.clarifications?.length) {
|
|
@@ -77935,23 +78106,23 @@ var Server = class extends Protocol {
|
|
|
77935
78106
|
const wrappedHandler = async (request, extra) => {
|
|
77936
78107
|
const validatedRequest = safeParse3(CallToolRequestSchema, request);
|
|
77937
78108
|
if (!validatedRequest.success) {
|
|
77938
|
-
const
|
|
77939
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call request: ${
|
|
78109
|
+
const errorMessage2 = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
|
|
78110
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call request: ${errorMessage2}`);
|
|
77940
78111
|
}
|
|
77941
78112
|
const { params } = validatedRequest.data;
|
|
77942
78113
|
const result = await Promise.resolve(handler(request, extra));
|
|
77943
78114
|
if (params.task) {
|
|
77944
78115
|
const taskValidationResult = safeParse3(CreateTaskResultSchema, result);
|
|
77945
78116
|
if (!taskValidationResult.success) {
|
|
77946
|
-
const
|
|
77947
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${
|
|
78117
|
+
const errorMessage2 = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
|
|
78118
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage2}`);
|
|
77948
78119
|
}
|
|
77949
78120
|
return taskValidationResult.data;
|
|
77950
78121
|
}
|
|
77951
78122
|
const validationResult = safeParse3(CallToolResultSchema, result);
|
|
77952
78123
|
if (!validationResult.success) {
|
|
77953
|
-
const
|
|
77954
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call result: ${
|
|
78124
|
+
const errorMessage2 = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
|
|
78125
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call result: ${errorMessage2}`);
|
|
77955
78126
|
}
|
|
77956
78127
|
return validationResult.data;
|
|
77957
78128
|
};
|