@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.
Files changed (2) hide show
  1. package/dist/bin.cjs +414 -243
  2. 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: external_exports.string().min(1),
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, toolName, dedupKey) {
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
- this.child = (0, import_node_child_process3.spawn)(spawnCmd[0], spawnCmd.slice(1), {
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 === void 0 ? {} : { env: 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 === void 0 ? {} : { env: 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
- this.child = (0, import_node_child_process4.spawn)(spawnCmd[0], spawnCmd.slice(1), {
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 === void 0 ? {} : { env: 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 === void 0 ? {} : { env: 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 (err) {
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
- out[12] = v4Bytes[0];
45954
- out[13] = v4Bytes[1];
45955
- out[14] = v4Bytes[2];
45956
- out[15] = v4Bytes[3];
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[0];
46001
- const b1 = b[1];
46002
- const b2 = b[2];
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
- if (v6[0] === 254 && (v6[1] & 192) === 128)
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 ((v6[0] & 254) === 252)
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 validatedIp = options?.allowPrivateUpstream ? "127.0.0.1" : addresses[0].address;
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 validatedIp = options?.allowPrivateUpstream ? "127.0.0.1" : addresses[0].address;
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(options.socketPath)) {
46388
- import_node_fs2.default.unlinkSync(options.socketPath);
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(options.socketPath, () => {
46461
+ server.listen(socketPath, () => {
46393
46462
  try {
46394
- import_node_fs2.default.chmodSync(options.socketPath, 384);
46463
+ import_node_fs2.default.chmodSync(socketPath, 384);
46395
46464
  } catch {
46396
46465
  }
46397
46466
  server.unref();
46398
- assignedSocketPath = options.socketPath;
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 errorMessage = message;
50455
- const error51 = new McpError(errorMessage.error.code, errorMessage.error.message, errorMessage.error.data);
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 errorMessage = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
51762
- throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation request: ${errorMessage}`);
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 errorMessage = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
51778
- throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage}`);
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 errorMessage = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
51785
- throw new McpError(ErrorCode.InvalidParams, `Invalid elicitation result: ${errorMessage}`);
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 errorMessage = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
51806
- throw new McpError(ErrorCode.InvalidParams, `Invalid sampling request: ${errorMessage}`);
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 errorMessage = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
51814
- throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage}`);
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 errorMessage = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
51823
- throw new McpError(ErrorCode.InvalidParams, `Invalid sampling result: ${errorMessage}`);
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(toolName) {
52118
+ isToolTask(toolName2) {
52052
52119
  if (!this._serverCapabilities?.tasks?.requests?.tools?.call) {
52053
52120
  return false;
52054
52121
  }
52055
- return this._cachedKnownTaskTools.has(toolName);
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(toolName) {
52062
- return this._cachedRequiredTaskTools.has(toolName);
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(toolName) {
52090
- return this._cachedToolOutputValidators.get(toolName);
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 errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}${redirect ?? `Invalid OAuth error response: ${error51}. Raw body: ${body}`}`;
52634
- return new ServerError(errorMessage);
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, toolName, payload) {
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: toolName,
54090
+ name: toolName2,
54024
54091
  arguments: isRecord(payload) ? payload : void 0
54025
54092
  });
54026
54093
  } catch (error51) {
54027
- throw classifyInvokeError(error51, target, toolName);
54094
+ throw classifyInvokeError(error51, target, toolName2);
54028
54095
  }
54029
54096
  if (result.isError) {
54030
- throw new InvokeToolExecutionError(toolName, extractFirstText(result.content));
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(toolName, cause) {
54040
- super(`invokeCapability: tool "${toolName}" not found on the granted server`, { cause });
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(toolName, detail, cause) {
54046
- super(`invokeCapability: tool "${toolName}" reported isError -- ${detail}`, { cause });
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, toolName) {
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(toolName, error51);
54151
+ return new InvokeToolNotFoundError(toolName2, error51);
54085
54152
  }
54086
54153
  if (error51.code === ErrorCode.InvalidParams) {
54087
- return new InvokeMalformedResultError(`invalid parameters for tool "${toolName}": ${error51.message}`, error51);
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, toolName, payload) {
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 && toolName === defaultRoute.operations.pull_request) {
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, toolName, adaptedArgs);
54259
+ return invokeCapability(server, toolName2, adaptedArgs);
54193
54260
  }
54194
- return invokeCapability(server, toolName, args);
54261
+ return invokeCapability(server, toolName2, args);
54195
54262
  }
54196
- if (isDefaultGitHubRoute && (toolName === defaultRoute.operations.pull_request_state || toolName === "pull_request_read")) {
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 (toolName === "pull_request_read") {
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, toolName, adaptedArgs);
54286
+ return invokeCapability(server, toolName2, adaptedArgs);
54220
54287
  }
54221
- return invokeCapability(server, toolName, { pullRequestUrl: payload.pullRequestUrl });
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, toolName, payload) {
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 && toolName === defaultRoute.operations.dispatch) {
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, toolName, adaptedArgs);
54379
+ return invokeCapability(server, toolName2, adaptedArgs);
54313
54380
  }
54314
- return invokeCapability(server, toolName, args);
54381
+ return invokeCapability(server, toolName2, args);
54315
54382
  }
54316
54383
 
54317
54384
  // src/delivery/publish.ts
54318
- async function deliverToPublish(server, toolName, payload) {
54385
+ async function deliverToPublish(server, toolName2, payload) {
54319
54386
  const { operation: _operation, ...args } = payload;
54320
- return invokeCapability(server, toolName, args);
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.operationClass ?? "reversible",
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: typeof redemption.error === "string" ? redemption.error : redemption.error?.message ?? "Capability invocation previously failed"
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?.message ?? String(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 = typeof redemption.error === "string" ? redemption.error : redemption.error?.message ?? "Capability invocation previously failed";
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.operationClass ?? (payload.operation === "preview" ? "reversible" : "irreversible"),
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
- return { ...redemption.result, use: use2 };
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 = typeof redemption.error === "string" ? redemption.error : redemption.error?.message ?? "Capability invocation previously failed";
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 toolName = route.operations.pull_request_state;
54932
- if (typeof toolName !== "string") {
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 = typeof redemption.error === "string" ? redemption.error : redemption.error?.message ?? "Capability invocation previously failed";
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, toolName, payload);
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(toolName) {
55153
- return registry2.get(toolName);
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 toolName = tool.name;
56797
- if (typeof toolId !== "string" || typeof toolName !== "string") return null;
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(toolName) {
56978
- return toolName.replace(/^mcp__.+?__/, "");
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 toolName = normalizeToolName(rawToolName);
56983
- if (READ_TOOL_NAMES.has(toolName)) return "read";
56984
- if (OUTWARD_TOOL_NAMES.has(toolName)) return "outward";
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(toolName) {
57081
+ function buildBrowserAttemptReceipt(toolName2) {
56998
57082
  return {
56999
57083
  kind: "attempt",
57000
- evidence: { type: "human_tap", value: toolName },
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 toolName = normalizeToolName(projection.toolName);
57214
+ const toolName2 = normalizeToolName(projection.toolName);
57131
57215
  if (classifyToolEffect(projection.toolName) === "outward") {
57132
- if (BROWSER_OUTWARD_TOOL_NAMES.has(toolName)) {
57133
- syntheticReceipt = buildBrowserAttemptReceipt(toolName);
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(toolName) && state.pending.length > 0) {
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 toolName = line.projection.toolName ?? line.payload?.event?.tool?.name ?? "";
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.createTask]: "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.",
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.107";
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 toolName = rawName.replace(/^.*__/, "");
61842
- const isMutation = MUTATION_TOOLS.has(toolName);
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 ((toolName === "create_task" || toolName === "update_task") && /^GT-\d+$/.test(rawTargetId)) {
61977
+ if ((toolName2 === "create_task" || toolName2 === "update_task") && /^GT-\d+$/.test(rawTargetId)) {
61848
61978
  targetId = rawTargetId;
61849
- } else if ((toolName === "create_wiki_page" || toolName === "update_wiki_page") && /^WK-\d+$/.test(rawTargetId)) {
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, toolName, input) {
67951
+ async function deriveRequestedHash(client, toolName2, input) {
67822
67952
  if (input.requestedHash) return input.requestedHash;
67823
- if (toolName === "run_spec_consensus" && input.pageId) {
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 (toolName === "draft_task_spec" && input.taskId) {
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 = Array.isArray(args) ? args : [];
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 = { ...optsObj };
72305
+ const finalSpawnOpts = { ...spawnOpts };
72177
72306
  if (hasExtraFd) {
72178
- const stdio = Array.isArray(finalSpawnOpts?.stdio) ? [...finalSpawnOpts.stdio] : ["pipe", "pipe", "pipe"];
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
- return baseSpawn(wrapped[0], wrapped.slice(1), finalSpawnOpts);
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 b of parsedParts) {
72433
- if (b > 255) return null;
72563
+ for (const b2 of parsedParts) {
72564
+ if (b2 > 255) return null;
72434
72565
  }
72435
- return [parsedParts[0], parsedParts[1], parsedParts[2], parsedParts[3]];
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(toolName) {
73011
- super(`TOOL_INVOCATION_FORBIDDEN: native network tool "${toolName}" is disabled in verification isolation mode`);
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(toolName, disabledTools = DISABLED_NATIVE_VERIFICATION_TOOLS) {
73175
+ function assertNativeToolsDisabled(toolName2, disabledTools = DISABLED_NATIVE_VERIFICATION_TOOLS) {
73016
73176
  const disabledSet = new Set(disabledTools.map((t) => t.toLowerCase()));
73017
- if (disabledSet.has(toolName.toLowerCase())) {
73018
- throw new DisabledToolInvocationError(toolName);
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 = handle[prop];
73185
+ const val = extendedHandle[prop];
73025
73186
  if (Array.isArray(val)) {
73026
- handle[prop] = val.filter((t) => {
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 = handle.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 handle.disableNativeTools === "function") {
73197
+ if (typeof extendedHandle.disableNativeTools === "function") {
73040
73198
  try {
73041
- handle.disableNativeTools(disabledTools);
73042
- } catch {
73199
+ extendedHandle.disableNativeTools(disabledTools);
73200
+ } catch (error51) {
73043
73201
  }
73044
73202
  }
73045
- handle.disabledTools = disabledTools;
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
- let origExecute = null;
73212
+ const extendedHandle = runtimeHandle(handle);
73213
+ let origExecute;
73055
73214
  let didPatchExecute = false;
73056
- let origStartThread = null;
73057
- let origResumeThread = null;
73058
- let origStartTurn = null;
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
- if (event && event.type === "tool_use" && event.tool?.name) {
73069
- const name = String(event.tool.name).toLowerCase();
73070
- for (const disabled of disabledTools) {
73071
- if (name === disabled.toLowerCase()) {
73072
- toolViolationError = new DisabledToolInvocationError(event.tool.name);
73073
- if (typeof handle.interruptTurn === "function") {
73074
- try {
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
- origStartThread = handle.startThread;
73243
+ const startThread = handle.startThread;
73244
+ origStartThread = startThread;
73092
73245
  handle.startThread = async (params) => {
73093
- const res = await origStartThread.call(handle, params);
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
- origResumeThread = handle.resumeThread;
73254
+ const resumeThread = handle.resumeThread;
73255
+ origResumeThread = resumeThread;
73102
73256
  handle.resumeThread = async (threadId, params) => {
73103
- const res = await origResumeThread.call(handle, threadId, params);
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
- origStartTurn = handle.startTurn;
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 origStartTurn.call(handle, threadId, input, effort);
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
- if (event && event.type === "tool_use" && event.tool?.name) {
73123
- const name = String(event.tool.name).toLowerCase();
73124
- for (const disabled of disabledTools) {
73125
- if (name === disabled.toLowerCase()) {
73126
- toolViolationError = new DisabledToolInvocationError(event.tool.name);
73127
- if (typeof handle.interruptTurn === "function") {
73128
- try {
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 handle.executeTool === "function") {
73144
- origExecute = handle.executeTool;
73291
+ if (typeof extendedHandle.executeTool === "function") {
73292
+ const executeTool = extendedHandle.executeTool;
73293
+ origExecute = executeTool;
73145
73294
  didPatchExecute = true;
73146
- handle.executeTool = async (name, args) => {
73295
+ extendedHandle.executeTool = async (name, args) => {
73147
73296
  assertNativeToolsDisabled(name, disabledTools);
73148
- return origExecute.call(handle, name, args);
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
- handle.executeTool = origExecute;
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?.code === "ENODATA" || err?.code === "ENOTFOUND") return [];
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?.code === "ENODATA" || err?.code === "ENOTFOUND") return [];
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
- "- A single `create_task` call creates a task completely; it accepts `title`, `notes`, `category`,",
74245
- " `subcategory`, `impact`, `autonomyLevel`, `planId`, `parentTaskId`, and more in one call.",
74246
- " Do not create then patch, and do not re-read the task afterwards unless the operator asked",
74247
- " for confirmation.",
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 create the tasks: create the plan (if needed) and call `create_task` in the same turn so",
74331
- "actionable task cards appear on the Tasks board immediately. Never leave the board empty with 0",
74332
- "tasks after agreeing on scope. Never claim tasks are created, queued, or ready unless `create_task`",
74333
- "was actually invoked and returned the task ID. Set `status: 'todo'` on newly created actionable",
74334
- "tasks unless explicitly asked for backlog, so they appear in active Kanban columns immediately.",
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 : void 0),
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 materialization requires explicit operator confirmation of this proposal. You MUST provide proposalId, proposalVersion, and proposalDigest when creating tasks or plans. Direct agent materialization without confirmation will fail closed.`
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 errorMessage = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
77939
- throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call request: ${errorMessage}`);
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 errorMessage = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
77947
- throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage}`);
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 errorMessage = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
77954
- throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call result: ${errorMessage}`);
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
  };