@mrrlin-dev/mcp 0.4.98 → 0.4.100

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 +404 -52
  2. package/package.json +1 -1
package/dist/bin.cjs CHANGED
@@ -9776,7 +9776,7 @@ var require_cross_spawn = __commonJS({
9776
9776
  var cp = require("child_process");
9777
9777
  var parse8 = require_parse2();
9778
9778
  var enoent = require_enoent();
9779
- function spawn6(command, args, options) {
9779
+ function spawn7(command, args, options) {
9780
9780
  const parsed = parse8(command, args, options);
9781
9781
  const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
9782
9782
  enoent.hookChildProcess(spawned, parsed);
@@ -9788,8 +9788,8 @@ var require_cross_spawn = __commonJS({
9788
9788
  result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
9789
9789
  return result;
9790
9790
  }
9791
- module2.exports = spawn6;
9792
- module2.exports.spawn = spawn6;
9791
+ module2.exports = spawn7;
9792
+ module2.exports.spawn = spawn7;
9793
9793
  module2.exports.sync = spawnSync7;
9794
9794
  module2.exports._parse = parse8;
9795
9795
  module2.exports._enoent = enoent;
@@ -21662,7 +21662,7 @@ __export(bin_exports, {
21662
21662
  });
21663
21663
  module.exports = __toCommonJS(bin_exports);
21664
21664
  var import_node_path42 = __toESM(require("node:path"), 1);
21665
- var import_node_child_process22 = require("node:child_process");
21665
+ var import_node_child_process23 = require("node:child_process");
21666
21666
  var import_node_fs25 = require("node:fs");
21667
21667
  var import_node_os20 = require("node:os");
21668
21668
  var import_node_path43 = __toESM(require("node:path"), 1);
@@ -37189,6 +37189,39 @@ function date4(params) {
37189
37189
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
37190
37190
  config(en_default());
37191
37191
 
37192
+ // ../../packages/schemas/dist/plans.js
37193
+ var PLAN_TIERS = ["base", "pro", "team", "ultra"];
37194
+ var planTierSchema = external_exports.enum(PLAN_TIERS);
37195
+ var billingPriceSchema = external_exports.object({
37196
+ amount: external_exports.number().int().nonnegative(),
37197
+ currency: external_exports.string().length(3)
37198
+ });
37199
+ var billingPlansResponseSchema = external_exports.object({
37200
+ data: external_exports.object({
37201
+ plans: external_exports.array(external_exports.object({
37202
+ tier: planTierSchema,
37203
+ name: external_exports.string().min(1),
37204
+ limits: external_exports.object({
37205
+ projects: external_exports.number().int(),
37206
+ seats: external_exports.number().int()
37207
+ }),
37208
+ prices: external_exports.object({
37209
+ month: billingPriceSchema.optional(),
37210
+ year: billingPriceSchema.optional()
37211
+ })
37212
+ }))
37213
+ })
37214
+ });
37215
+ var createCheckoutSessionRequestSchema = external_exports.object({
37216
+ tier: planTierSchema,
37217
+ interval: external_exports.enum(["month", "year"])
37218
+ });
37219
+ var billingUrlResponseSchema = external_exports.object({
37220
+ data: external_exports.object({
37221
+ url: external_exports.string().url()
37222
+ })
37223
+ });
37224
+
37192
37225
  // ../../packages/schemas/dist/artifact-checks.js
37193
37226
  var artifactKindSchema = external_exports.enum([
37194
37227
  "document",
@@ -37394,7 +37427,16 @@ var openApiOperationIds = {
37394
37427
  confirmFirstWrite: "confirmFirstWrite",
37395
37428
  resolveArtifactKindRoute: "resolveArtifactKindRoute",
37396
37429
  resolveDeliveryForArtifactKind: "resolveDeliveryForArtifactKind",
37397
- recordCapabilityUse: "recordCapabilityUse"
37430
+ recordCapabilityUse: "recordCapabilityUse",
37431
+ resolveAccount: "resolveAccount",
37432
+ linkAccountIdentity: "linkAccountIdentity",
37433
+ getMyAccount: "getMyAccount",
37434
+ getMyEntitlement: "getMyEntitlement",
37435
+ listBillingPlans: "listBillingPlans",
37436
+ createCheckoutSession: "createCheckoutSession",
37437
+ createBillingPortalSession: "createBillingPortalSession",
37438
+ syncBilling: "syncBilling",
37439
+ redeemAppsumoCode: "redeemAppsumoCode"
37398
37440
  };
37399
37441
 
37400
37442
  // ../../packages/schemas/dist/session.js
@@ -37414,10 +37456,13 @@ var operatorSessionSchema = external_exports.object({
37414
37456
  // Default 'project' for backward-compat: tokens minted before this field existed parse
37415
37457
  // cleanly into the project branch of the middleware (which mirrors today's behavior).
37416
37458
  scope: external_exports.enum(["project", "operator"]).default("project"),
37459
+ accountId: external_exports.string().uuid().optional(),
37460
+ identitySubject: external_exports.string().min(1).optional(),
37461
+ purpose: external_exports.enum(["session", "identity_assertion"]).default("session"),
37417
37462
  // Billing entitlement carried on the session. Optional because a GitHub session never has one
37418
37463
  // and a Firebase session has one only once the claims exist. `determinedAt` is what makes it
37419
37464
  // falsifiable: the token lives for 7 days, so a value that can go stale needs a freshness bound
37420
- // enforced by the reader (readEffectivePlan), not by the cookie.
37465
+ // enforced by the reader, not by the cookie.
37421
37466
  entitlement: external_exports.object({
37422
37467
  plan: external_exports.string(),
37423
37468
  status: external_exports.enum(["active", "none"]),
@@ -38064,6 +38109,24 @@ var TASK_NOTES_JOURNAL_SECTIONS = [
38064
38109
  ];
38065
38110
  var JOURNAL_HEADING_RE = new RegExp(`^##[ \\t]+(${TASK_NOTES_JOURNAL_SECTIONS.map((s) => s.heading).join("|")})\\b[ \\t]*(?:[\u2014\u2013-][ \\t]*(\\S.*?))?[ \\t]*$`);
38066
38111
 
38112
+ // ../../packages/schemas/dist/appsumo.js
38113
+ var APPSUMO_CODE_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
38114
+ var APPSUMO_ALPHABET_SET = new Set(APPSUMO_CODE_ALPHABET);
38115
+ var redeemAppsumoCodeRequestSchema = external_exports.object({
38116
+ code: external_exports.string().min(1).max(64)
38117
+ });
38118
+ var redeemAppsumoCodeResponseSchema = external_exports.object({
38119
+ data: external_exports.object({
38120
+ outcome: external_exports.enum(["redeemed", "already_redeemed_by_you"]),
38121
+ codes: external_exports.number().int().min(1).max(4),
38122
+ tier: planTierSchema,
38123
+ limits: external_exports.object({
38124
+ projects: external_exports.number().int().nonnegative(),
38125
+ seats: external_exports.number().int().nonnegative()
38126
+ })
38127
+ })
38128
+ });
38129
+
38067
38130
  // ../../packages/schemas/dist/integration-route-defaults.js
38068
38131
  var DEFAULT_INTEGRATION_ROUTES = {
38069
38132
  github: {
@@ -38665,9 +38728,12 @@ var mrrlinProjectSummarySchema = external_exports.object({
38665
38728
  clientName: external_exports.string().trim().max(80).nullable().optional(),
38666
38729
  scopeDescription: external_exports.string().trim().max(240).nullable().optional()
38667
38730
  });
38731
+ var mrrlinProjectOperatorInputSchema = external_exports.string().regex(/^@[!-~]+$/, "operator must be '@' followed by printable ASCII with no whitespace");
38668
38732
  var mrrlinProjectUpsertSchema = mrrlinProjectSummarySchema.omit({
38669
38733
  onboardingKickoffState: true,
38670
38734
  slug: true
38735
+ }).extend({
38736
+ github: mrrlinGithubBindingSchema.extend({ operator: mrrlinProjectOperatorInputSchema })
38671
38737
  });
38672
38738
  var mrrlinProjectRenameSchema = external_exports.object({
38673
38739
  displayName: external_exports.string().trim().min(1).max(120).optional(),
@@ -39091,13 +39157,61 @@ var projectSnapshotResponseSchema = external_exports.object({
39091
39157
  var projectSummaryResponseSchema = external_exports.object({
39092
39158
  data: mrrlinProjectSummarySchema
39093
39159
  });
39160
+ var projectListItemSchema = mrrlinProjectSummarySchema.extend({
39161
+ viewerRole: external_exports.enum(["owner", "collaborator"]).optional(),
39162
+ // True when this caller would get 402 (owner plan inactive, project over limit, or no seat) on
39163
+ // the project's routes. Lets the web skip paused projects when picking a default and offer the
39164
+ // ones that still open. Absent when the API runs without a session (auth disabled).
39165
+ paused: external_exports.boolean().optional()
39166
+ });
39094
39167
  var projectSummaryListResponseSchema = external_exports.object({
39095
- data: external_exports.array(mrrlinProjectSummarySchema),
39168
+ data: external_exports.array(projectListItemSchema),
39096
39169
  entitlement: external_exports.object({
39097
39170
  plan: external_exports.string(),
39098
39171
  status: external_exports.union([external_exports.literal("active"), external_exports.literal("none")])
39099
39172
  })
39100
39173
  });
39174
+ var accountEntitlementSchema = external_exports.object({
39175
+ accountId: external_exports.string(),
39176
+ standing: external_exports.enum(["entitled", "collaborator", "none"]),
39177
+ lapsed: external_exports.boolean(),
39178
+ tier: planTierSchema.nullable(),
39179
+ source: external_exports.enum(["stripe", "appsumo", "grant"]).nullable(),
39180
+ stripe: external_exports.object({
39181
+ status: external_exports.string(),
39182
+ tier: planTierSchema.nullable(),
39183
+ interval: external_exports.enum(["month", "year"]).nullable(),
39184
+ currentPeriodEnd: external_exports.string().nullable(),
39185
+ cancelAtPeriodEnd: external_exports.boolean()
39186
+ }).nullable(),
39187
+ appsumo: external_exports.object({
39188
+ codes: external_exports.number().int(),
39189
+ tier: planTierSchema
39190
+ }).nullable(),
39191
+ grant: external_exports.object({
39192
+ tier: planTierSchema,
39193
+ reason: external_exports.string()
39194
+ }).nullable(),
39195
+ limits: external_exports.object({
39196
+ projects: external_exports.number().int(),
39197
+ seats: external_exports.number().int()
39198
+ }).nullable(),
39199
+ usage: external_exports.object({
39200
+ projects: external_exports.number().int(),
39201
+ seats: external_exports.number().int()
39202
+ }),
39203
+ collaboratorProjects: external_exports.number().int(),
39204
+ upgradePath: external_exports.enum(["stripe", "appsumo", "none"]),
39205
+ tiers: external_exports.array(external_exports.object({
39206
+ tier: planTierSchema,
39207
+ projects: external_exports.number().int(),
39208
+ seats: external_exports.number().int(),
39209
+ selfServe: external_exports.boolean()
39210
+ }))
39211
+ });
39212
+ var accountEntitlementResponseSchema = external_exports.object({
39213
+ data: accountEntitlementSchema
39214
+ });
39101
39215
  var taskResponseSchema = external_exports.object({
39102
39216
  data: mrrlinTaskSchema
39103
39217
  });
@@ -40021,6 +40135,47 @@ function resolveProjectClientScope(project) {
40021
40135
  scopeDescription
40022
40136
  };
40023
40137
  }
40138
+ var resolvedAccountSchema = external_exports.object({
40139
+ accountId: external_exports.string().uuid(),
40140
+ principal: external_exports.string().min(1),
40141
+ emails: external_exports.array(external_exports.string().email()),
40142
+ providers: external_exports.array(external_exports.enum(["github", "firebase"]))
40143
+ });
40144
+ var resolveAccountResponseSchema = external_exports.object({
40145
+ data: external_exports.discriminatedUnion("outcome", [
40146
+ resolvedAccountSchema.extend({ outcome: external_exports.literal("resolved") }),
40147
+ resolvedAccountSchema.extend({ outcome: external_exports.literal("created") }),
40148
+ external_exports.object({
40149
+ outcome: external_exports.literal("link_required"),
40150
+ accountId: external_exports.string().uuid(),
40151
+ principal: external_exports.null(),
40152
+ emails: external_exports.array(external_exports.string()).length(0),
40153
+ providers: external_exports.array(external_exports.enum(["github", "firebase"])).min(1)
40154
+ }),
40155
+ external_exports.object({
40156
+ outcome: external_exports.literal("refused"),
40157
+ accountId: external_exports.string().uuid().nullable().optional(),
40158
+ principal: external_exports.null().optional(),
40159
+ emails: external_exports.array(external_exports.string()).optional(),
40160
+ providers: external_exports.array(external_exports.enum(["github", "firebase"])).optional()
40161
+ })
40162
+ ])
40163
+ });
40164
+ var linkAccountIdentityRequestSchema = external_exports.object({
40165
+ assertion: external_exports.string().min(1)
40166
+ });
40167
+ var accountSummaryResponseSchema = external_exports.object({
40168
+ data: external_exports.object({
40169
+ accountId: external_exports.string().uuid(),
40170
+ principal: external_exports.string().min(1),
40171
+ emails: external_exports.array(external_exports.string().email()),
40172
+ identities: external_exports.array(external_exports.object({
40173
+ provider: external_exports.enum(["github", "firebase"]),
40174
+ login: external_exports.string().nullable(),
40175
+ email: external_exports.string().nullable()
40176
+ }))
40177
+ })
40178
+ });
40024
40179
 
40025
40180
  // ../../packages/client/dist/agent-token-provider.js
40026
40181
  var AgentTokenProviderError = class extends Error {
@@ -41143,6 +41298,60 @@ function createMrrlinClient(config2) {
41143
41298
  await request(`/operator/agent-credentials/${encodeURIComponent(credentialId)}`, {
41144
41299
  method: "DELETE"
41145
41300
  });
41301
+ },
41302
+ async resolveAccount() {
41303
+ const body = await request("/auth/account/resolve", {
41304
+ method: "POST"
41305
+ });
41306
+ return resolveAccountResponseSchema.parse(body);
41307
+ },
41308
+ async linkAccountIdentity(assertion) {
41309
+ const body = await request("/auth/account/link", {
41310
+ body: JSON.stringify({ assertion }),
41311
+ headers: { "content-type": "application/json" },
41312
+ method: "POST"
41313
+ });
41314
+ return resolveAccountResponseSchema.parse(body);
41315
+ },
41316
+ async getMyAccount() {
41317
+ const body = await request("/me/account");
41318
+ return accountSummaryResponseSchema.parse(body);
41319
+ },
41320
+ async getMyEntitlement() {
41321
+ const body = await request("/me/entitlement");
41322
+ return accountEntitlementResponseSchema.parse(body).data;
41323
+ },
41324
+ async listBillingPlans() {
41325
+ const body = await request("/billing/plans");
41326
+ return billingPlansResponseSchema.parse(body).data.plans;
41327
+ },
41328
+ async createCheckoutSession(input) {
41329
+ const body = await request("/billing/checkout-session", {
41330
+ body: JSON.stringify(input),
41331
+ headers: { "content-type": "application/json" },
41332
+ method: "POST"
41333
+ });
41334
+ return billingUrlResponseSchema.parse(body).data;
41335
+ },
41336
+ async createBillingPortalSession() {
41337
+ const body = await request("/billing/portal-session", {
41338
+ method: "POST"
41339
+ });
41340
+ return billingUrlResponseSchema.parse(body).data;
41341
+ },
41342
+ async syncBilling() {
41343
+ const body = await request("/billing/sync", {
41344
+ method: "POST"
41345
+ });
41346
+ return accountEntitlementResponseSchema.parse(body).data;
41347
+ },
41348
+ async redeemAppsumoCode(code) {
41349
+ const body = await request("/appsumo/redeem", {
41350
+ body: JSON.stringify({ code }),
41351
+ headers: { "content-type": "application/json" },
41352
+ method: "POST"
41353
+ });
41354
+ return redeemAppsumoCodeResponseSchema.parse(body).data;
41146
41355
  }
41147
41356
  };
41148
41357
  }
@@ -44556,7 +44765,7 @@ function firstString(...values) {
44556
44765
  return null;
44557
44766
  }
44558
44767
  function runCodexExec(input, deps) {
44559
- const spawn6 = deps?.spawn ?? import_node_child_process6.spawn;
44768
+ const spawn7 = deps?.spawn ?? import_node_child_process6.spawn;
44560
44769
  const executable = input.codexExecutable ?? "codex";
44561
44770
  const sandbox = input.sandbox ?? "read-only";
44562
44771
  const fullPrompt = input.developerInstructions.trim() ? `${input.developerInstructions.trim()}
@@ -44602,7 +44811,7 @@ ${input.prompt}` : input.prompt;
44602
44811
  }
44603
44812
  let child;
44604
44813
  try {
44605
- child = spawn6(spawnCmd, spawnArgs, options);
44814
+ child = spawn7(spawnCmd, spawnArgs, options);
44606
44815
  } catch (err) {
44607
44816
  finish({ ok: false, error: `Failed to spawn codex exec: ${errMessage(err)}` });
44608
44817
  return;
@@ -44645,7 +44854,7 @@ function errMessage(err) {
44645
44854
  // ../../packages/agent-client/dist/providers/claude/exec.js
44646
44855
  var import_node_child_process7 = require("node:child_process");
44647
44856
  function runClaudeExec(input, deps) {
44648
- const spawn6 = deps?.spawn ?? import_node_child_process7.spawn;
44857
+ const spawn7 = deps?.spawn ?? import_node_child_process7.spawn;
44649
44858
  const executable = input.codexExecutable ?? "claude";
44650
44859
  const args = ["--print", "--output-format", "json", "--strict-mcp-config"];
44651
44860
  if (input.mcpConfig) {
@@ -44689,7 +44898,7 @@ function runClaudeExec(input, deps) {
44689
44898
  }
44690
44899
  let child;
44691
44900
  try {
44692
- child = spawn6(spawnCmd, spawnArgs, options);
44901
+ child = spawn7(spawnCmd, spawnArgs, options);
44693
44902
  } catch (err) {
44694
44903
  finish({ ok: false, error: `Failed to spawn ${executable} exec: ${errMessage2(err)}` });
44695
44904
  return;
@@ -44757,7 +44966,7 @@ function errMessage2(err) {
44757
44966
  // ../../packages/agent-client/dist/providers/agy/exec.js
44758
44967
  var import_node_child_process8 = require("node:child_process");
44759
44968
  function runAgyExec(input, deps) {
44760
- const spawn6 = deps?.spawn ?? import_node_child_process8.spawn;
44969
+ const spawn7 = deps?.spawn ?? import_node_child_process8.spawn;
44761
44970
  const executable = input.codexExecutable ?? "agy";
44762
44971
  const args = ["--output-format", "json"];
44763
44972
  if (input.sandbox === "read-only") {
@@ -44810,7 +45019,7 @@ function runAgyExec(input, deps) {
44810
45019
  }
44811
45020
  let child;
44812
45021
  try {
44813
- child = spawn6(spawnCmd, spawnArgs, options);
45022
+ child = spawn7(spawnCmd, spawnArgs, options);
44814
45023
  } catch (err) {
44815
45024
  finish({ ok: false, error: `Failed to spawn ${executable} exec: ${err instanceof Error ? err.message : String(err)}` });
44816
45025
  return;
@@ -46058,7 +46267,7 @@ var DEFAULT_STATUS_TIMEOUT_MS = 1e4;
46058
46267
  function errMessage3(err) {
46059
46268
  return err instanceof Error ? err.message : String(err);
46060
46269
  }
46061
- function runExternalAgentsStatus(bin, args, timeoutMs, spawn6) {
46270
+ function runExternalAgentsStatus(bin, args, timeoutMs, spawn7) {
46062
46271
  return new Promise((resolve2) => {
46063
46272
  let settled = false;
46064
46273
  const timerRef = { id: void 0 };
@@ -46071,7 +46280,7 @@ function runExternalAgentsStatus(bin, args, timeoutMs, spawn6) {
46071
46280
  const options = { stdio: ["ignore", "pipe", "pipe"], env: process.env, shell: false };
46072
46281
  let child;
46073
46282
  try {
46074
- child = spawn6(bin, args, options);
46283
+ child = spawn7(bin, args, options);
46075
46284
  } catch (err) {
46076
46285
  finish({ stdout: "", error: `spawn ${bin} failed: ${errMessage3(err)}` });
46077
46286
  return;
@@ -46095,13 +46304,13 @@ function runExternalAgentsStatus(bin, args, timeoutMs, spawn6) {
46095
46304
  });
46096
46305
  }
46097
46306
  async function fetchRegistrySnapshot(deps) {
46098
- const spawn6 = deps?.spawn ?? import_node_child_process10.spawn;
46307
+ const spawn7 = deps?.spawn ?? import_node_child_process10.spawn;
46099
46308
  const { command, prefixArgs } = resolveExternalAgentsCliInvocation(deps?.externalAgentsBin);
46100
46309
  const { stdout, error: error51 } = await runExternalAgentsStatus(
46101
46310
  command,
46102
46311
  [...prefixArgs, "status", "--json"],
46103
46312
  deps?.statusTimeoutMs ?? DEFAULT_STATUS_TIMEOUT_MS,
46104
- spawn6
46313
+ spawn7
46105
46314
  );
46106
46315
  if (error51) return { ok: false, error: error51 };
46107
46316
  try {
@@ -46145,7 +46354,7 @@ function estimateTokenCount(text) {
46145
46354
  function errMessage4(err) {
46146
46355
  return err instanceof Error ? err.message : String(err);
46147
46356
  }
46148
- function runExternalAgents(bin, args, label, timeoutMs, spawn6) {
46357
+ function runExternalAgents(bin, args, label, timeoutMs, spawn7) {
46149
46358
  return new Promise((resolve2) => {
46150
46359
  let settled = false;
46151
46360
  const timerRef = { id: void 0 };
@@ -46163,7 +46372,7 @@ function runExternalAgents(bin, args, label, timeoutMs, spawn6) {
46163
46372
  };
46164
46373
  let child;
46165
46374
  try {
46166
- child = spawn6(bin, args, options);
46375
+ child = spawn7(bin, args, options);
46167
46376
  } catch (err) {
46168
46377
  finish({ code: null, stdout: "", error: `spawn ${bin} failed: ${errMessage4(err)}` });
46169
46378
  return;
@@ -46183,7 +46392,7 @@ function runExternalAgents(bin, args, label, timeoutMs, spawn6) {
46183
46392
  });
46184
46393
  }
46185
46394
  async function pickPanel(input, deps) {
46186
- const spawn6 = deps?.spawn ?? import_node_child_process11.spawn;
46395
+ const spawn7 = deps?.spawn ?? import_node_child_process11.spawn;
46187
46396
  const { command, prefixArgs } = resolveExternalAgentsCliInvocation(deps?.externalAgentsBin);
46188
46397
  const args = [
46189
46398
  "pick",
@@ -46196,7 +46405,7 @@ async function pickPanel(input, deps) {
46196
46405
  "--exclude-providers",
46197
46406
  input.excludeProvider
46198
46407
  ];
46199
- const r = await runExternalAgents(command, [...prefixArgs, ...args], "pick", input.timeoutMs, spawn6);
46408
+ const r = await runExternalAgents(command, [...prefixArgs, ...args], "pick", input.timeoutMs, spawn7);
46200
46409
  if (r.error) return { ok: false, error: r.error };
46201
46410
  if (r.code === 3) return { ok: true, agents: [] };
46202
46411
  if (r.code !== 0) return { ok: false, error: `external-agents pick exited ${r.code}` };
@@ -46230,10 +46439,10 @@ function parseDispatch(agentId, stdout, exitCode) {
46230
46439
  return { ok: true, text: parsed.text, usage };
46231
46440
  }
46232
46441
  async function dispatchHead(agentId, prompt, timeoutMs, deps) {
46233
- const spawn6 = deps?.spawn ?? import_node_child_process11.spawn;
46442
+ const spawn7 = deps?.spawn ?? import_node_child_process11.spawn;
46234
46443
  const { command, prefixArgs } = resolveExternalAgentsCliInvocation(deps?.externalAgentsBin);
46235
46444
  const args = ["dispatch", agentId, "--json", prompt];
46236
- const r = await runExternalAgents(command, [...prefixArgs, ...args], "dispatch", timeoutMs, spawn6);
46445
+ const r = await runExternalAgents(command, [...prefixArgs, ...args], "dispatch", timeoutMs, spawn7);
46237
46446
  if (r.error) return { ok: false, error: r.error };
46238
46447
  return parseDispatch(agentId, r.stdout, r.code);
46239
46448
  }
@@ -57560,12 +57769,155 @@ async function verifyProviderReadiness(provider, run3, opts = {}) {
57560
57769
  return { ready, checks, details };
57561
57770
  }
57562
57771
 
57772
+ // src/browser-interceptor.ts
57773
+ var import_node_readline = __toESM(require("node:readline"), 1);
57774
+ var import_node_child_process14 = require("node:child_process");
57775
+ var INTERNAL_HOST_PATTERNS = [
57776
+ /^(?:.*\.)?mrrlin\.(?:com|internal|local)$/i,
57777
+ /^(?:localhost|127\.0\.0\.1)(?::\d+)?$/i
57778
+ ];
57779
+ var INTERNAL_ROUTE_PREFIXES = [
57780
+ "/wiki",
57781
+ "/deliverables",
57782
+ "/specs",
57783
+ "/items",
57784
+ "/memory",
57785
+ "/tasks",
57786
+ "/autopilot",
57787
+ "/settings"
57788
+ ];
57789
+ function isInternalMrrlinUrl(urlString) {
57790
+ if (!urlString || typeof urlString !== "string") {
57791
+ return { isInternal: false };
57792
+ }
57793
+ const trimmed = urlString.trim();
57794
+ try {
57795
+ const isRelative = trimmed.startsWith("/");
57796
+ const parsedPathname = isRelative ? (trimmed.split("?")[0] ?? "").split("#")[0] ?? "" : "";
57797
+ const parsed = isRelative ? { pathname: parsedPathname, hostname: "localhost" } : new URL(trimmed);
57798
+ const isInternalHost = isRelative || INTERNAL_HOST_PATTERNS.some((p) => p.test(parsed.hostname));
57799
+ if (!isInternalHost) {
57800
+ return { isInternal: false };
57801
+ }
57802
+ const pathname = (parsed.pathname ?? "").toLowerCase();
57803
+ const matchedPrefix = INTERNAL_ROUTE_PREFIXES.find(
57804
+ (prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`)
57805
+ );
57806
+ if (matchedPrefix) {
57807
+ let suggestedTool = "get_wiki_page / search_wiki_pages";
57808
+ if (matchedPrefix === "/items" || matchedPrefix === "/deliverables" || matchedPrefix === "/tasks") {
57809
+ suggestedTool = "get_task / list_tasks";
57810
+ } else if (matchedPrefix === "/autopilot") {
57811
+ suggestedTool = "list_inbox_items (filtering kind='handoff') / list_tasks";
57812
+ }
57813
+ return {
57814
+ isInternal: true,
57815
+ reason: `Route '${matchedPrefix}' belongs to internal Mrrlin domain/state.`,
57816
+ suggestedTool
57817
+ };
57818
+ }
57819
+ } catch {
57820
+ }
57821
+ return { isInternal: false };
57822
+ }
57823
+ function formatInternalRouteRejectionMessage(url2, suggestedTool) {
57824
+ return `[Preflight Guard] Refused to navigate browser to internal route "${url2}". Internal entities must be accessed via fast typed MCP tools directly against the database/API. Suggested tool: ${suggestedTool}. Do NOT open Chromium for internal data retrieval. If browser rendering is strictly required for visual UI testing, pass force_internal: true.`;
57825
+ }
57826
+ function interceptJsonRpcLine(rawLine) {
57827
+ const trimmed = rawLine.trim();
57828
+ if (!trimmed) return null;
57829
+ try {
57830
+ const msg = JSON.parse(trimmed);
57831
+ if (msg && msg.jsonrpc === "2.0" && msg.method === "tools/call" && msg.params?.name === "browser_navigate") {
57832
+ const args = msg.params.arguments;
57833
+ const url2 = typeof args?.url === "string" ? args.url : "";
57834
+ const forceInternal = Boolean(args?.force_internal);
57835
+ if (!forceInternal && url2) {
57836
+ const check2 = isInternalMrrlinUrl(url2);
57837
+ if (check2.isInternal) {
57838
+ const rejectionText = formatInternalRouteRejectionMessage(
57839
+ url2,
57840
+ check2.suggestedTool ?? "get_wiki_page / get_task"
57841
+ );
57842
+ return JSON.stringify({
57843
+ jsonrpc: "2.0",
57844
+ id: msg.id,
57845
+ result: {
57846
+ isError: true,
57847
+ content: [
57848
+ {
57849
+ type: "text",
57850
+ text: rejectionText
57851
+ }
57852
+ ]
57853
+ }
57854
+ });
57855
+ }
57856
+ }
57857
+ }
57858
+ } catch {
57859
+ }
57860
+ return null;
57861
+ }
57862
+ function wireBrowserServeProxy(streams) {
57863
+ const { input, output: output3, childIn, childOut } = streams;
57864
+ const rl = import_node_readline.default.createInterface({
57865
+ input,
57866
+ crlfDelay: Infinity,
57867
+ terminal: false
57868
+ });
57869
+ rl.on("line", (line) => {
57870
+ const intercepted = interceptJsonRpcLine(line);
57871
+ if (intercepted) {
57872
+ output3.write(intercepted + "\n");
57873
+ } else {
57874
+ childIn.write(line + "\n");
57875
+ }
57876
+ });
57877
+ rl.on("close", () => {
57878
+ try {
57879
+ childIn.end();
57880
+ } catch {
57881
+ }
57882
+ });
57883
+ childOut.on("data", (chunk) => {
57884
+ output3.write(chunk);
57885
+ });
57886
+ }
57887
+ async function runBrowserServeProxy(opts) {
57888
+ const input = opts.input ?? process.stdin;
57889
+ const output3 = opts.output ?? process.stdout;
57890
+ const child = (0, import_node_child_process14.spawn)(opts.command, opts.args, {
57891
+ stdio: ["pipe", "pipe", "inherit"],
57892
+ env: { ...process.env, ...opts.env }
57893
+ });
57894
+ if (!child.stdin || !child.stdout) {
57895
+ throw new Error("Failed to open stdio pipes to @playwright/mcp child process");
57896
+ }
57897
+ wireBrowserServeProxy({
57898
+ input,
57899
+ output: output3,
57900
+ childIn: child.stdin,
57901
+ childOut: child.stdout
57902
+ });
57903
+ return new Promise((resolve2) => {
57904
+ child.on("close", (code) => {
57905
+ resolve2(code ?? 0);
57906
+ });
57907
+ child.on("error", (err) => {
57908
+ process.stderr.write(`[browser-serve proxy error]: ${err.message}
57909
+ `);
57910
+ resolve2(1);
57911
+ });
57912
+ });
57913
+ }
57914
+
57563
57915
  // src/director-bridge.ts
57564
57916
  var import_node_fs23 = __toESM(require("node:fs"), 1);
57565
57917
  var import_node_http = __toESM(require("node:http"), 1);
57566
57918
  var import_node_os17 = __toESM(require("node:os"), 1);
57567
57919
  var import_node_path38 = __toESM(require("node:path"), 1);
57568
- var import_node_child_process21 = require("node:child_process");
57920
+ var import_node_child_process22 = require("node:child_process");
57569
57921
  var import_node_crypto16 = __toESM(require("node:crypto"), 1);
57570
57922
 
57571
57923
  // src/turn-replay-buffer.ts
@@ -58110,14 +58462,14 @@ function createTurnLock() {
58110
58462
  }
58111
58463
 
58112
58464
  // src/self-update.ts
58113
- var import_node_child_process15 = require("node:child_process");
58465
+ var import_node_child_process16 = require("node:child_process");
58114
58466
  var import_node_crypto10 = require("node:crypto");
58115
58467
  var import_node_fs12 = require("node:fs");
58116
58468
  var import_node_path21 = __toESM(require("node:path"), 1);
58117
58469
  var import_semver3 = __toESM(require_semver2(), 1);
58118
58470
 
58119
58471
  // src/codex-auth-preflight.ts
58120
- var import_node_child_process14 = require("node:child_process");
58472
+ var import_node_child_process15 = require("node:child_process");
58121
58473
  var import_node_fs11 = require("node:fs");
58122
58474
  var import_node_os12 = __toESM(require("node:os"), 1);
58123
58475
  var import_node_path20 = __toESM(require("node:path"), 1);
@@ -58208,7 +58560,7 @@ function runCodexAuthRefreshSmokeForBridgeUpdate(opts = {}) {
58208
58560
  CODEX_AUTH_SMOKE_PROMPT
58209
58561
  ];
58210
58562
  const command = commandForSmoke(executable, model);
58211
- const execFileSync5 = opts.execFileSyncImpl ?? import_node_child_process14.execFileSync;
58563
+ const execFileSync5 = opts.execFileSyncImpl ?? import_node_child_process15.execFileSync;
58212
58564
  try {
58213
58565
  execFileSync5(executable, args, {
58214
58566
  cwd,
@@ -58364,7 +58716,7 @@ function resolveBinPath(opts) {
58364
58716
  }
58365
58717
  const whichSync = opts.whichSync ?? ((name) => {
58366
58718
  try {
58367
- return (0, import_node_child_process15.execFileSync)("which", [name], { encoding: "utf8", timeout: 3e3 }).trim() || null;
58719
+ return (0, import_node_child_process16.execFileSync)("which", [name], { encoding: "utf8", timeout: 3e3 }).trim() || null;
58368
58720
  } catch {
58369
58721
  return null;
58370
58722
  }
@@ -58695,7 +59047,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
58695
59047
  }
58696
59048
 
58697
59049
  // src/_generated/version.ts
58698
- var PKG_VERSION = "0.4.98";
59050
+ var PKG_VERSION = "0.4.100";
58699
59051
 
58700
59052
  // src/director-closure.ts
58701
59053
  var CLOSURE_SNAPSHOT_TIMEOUT_MS = 2e3;
@@ -60822,7 +61174,7 @@ async function collectAgentPoolSnapshot(deps) {
60822
61174
  }
60823
61175
 
60824
61176
  // src/external-agents-spawn.ts
60825
- var import_node_child_process16 = require("node:child_process");
61177
+ var import_node_child_process17 = require("node:child_process");
60826
61178
  function runExternalAgentsCli(args, opts) {
60827
61179
  let command;
60828
61180
  let prefixArgs;
@@ -60853,7 +61205,7 @@ function runExternalAgentsCli(args, opts) {
60853
61205
  };
60854
61206
  let spawned;
60855
61207
  try {
60856
- spawned = (0, import_node_child_process16.spawn)(command, [...prefixArgs, ...args], { stdio: stdioConfig });
61208
+ spawned = (0, import_node_child_process17.spawn)(command, [...prefixArgs, ...args], { stdio: stdioConfig });
60857
61209
  } catch {
60858
61210
  done(1);
60859
61211
  return;
@@ -60965,14 +61317,14 @@ function startAgentPoolLoop(deps) {
60965
61317
  }
60966
61318
 
60967
61319
  // src/provider-readiness-loop.ts
60968
- var import_node_child_process17 = require("node:child_process");
61320
+ var import_node_child_process18 = require("node:child_process");
60969
61321
  var DEFAULT_INTERVAL_MS3 = 6e4;
60970
61322
  function providerReadinessLoopDisabled(env = process.env) {
60971
61323
  return env["MRRLIN_BRIDGE_PROVIDER_READINESS_DISABLE"] === "1";
60972
61324
  }
60973
61325
  function defaultRunnerFor(command) {
60974
61326
  return (args) => {
60975
- const r = (0, import_node_child_process17.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3 });
61327
+ const r = (0, import_node_child_process18.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3 });
60976
61328
  return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
60977
61329
  };
60978
61330
  }
@@ -61015,7 +61367,7 @@ function startProviderReadinessLoop(deps) {
61015
61367
  }
61016
61368
 
61017
61369
  // src/execution-consumer.ts
61018
- var import_node_child_process19 = require("node:child_process");
61370
+ var import_node_child_process20 = require("node:child_process");
61019
61371
  var import_node_crypto14 = __toESM(require("node:crypto"), 1);
61020
61372
  var import_node_path31 = __toESM(require("node:path"), 1);
61021
61373
  var import_node_util2 = require("node:util");
@@ -61871,7 +62223,7 @@ async function awaitTurnWithDeadline(opts) {
61871
62223
  }
61872
62224
 
61873
62225
  // src/worktree.ts
61874
- var import_node_child_process18 = require("node:child_process");
62226
+ var import_node_child_process19 = require("node:child_process");
61875
62227
  var import_node_crypto13 = require("node:crypto");
61876
62228
  var import_node_fs17 = require("node:fs");
61877
62229
  var import_node_path30 = require("node:path");
@@ -61899,7 +62251,7 @@ async function withCheckoutLock(locksDir, slug, fn) {
61899
62251
  function worktreeBranch(runId) {
61900
62252
  return `mrrlin/run-${runId}`;
61901
62253
  }
61902
- var defaultGitExec = (args, env) => (0, import_node_child_process18.execFileSync)("git", args, { encoding: "utf8", timeout: 3e4, env });
62254
+ var defaultGitExec = (args, env) => (0, import_node_child_process19.execFileSync)("git", args, { encoding: "utf8", timeout: 3e4, env });
61903
62255
  function disabledGitHooksPath(locksDir, scope) {
61904
62256
  const scopeKey = (0, import_node_crypto13.createHash)("sha256").update(scope).digest("hex").slice(0, 32);
61905
62257
  return (0, import_node_path30.resolve)(locksDir, "..", "disabled-git-hooks", scopeKey);
@@ -61936,7 +62288,7 @@ function withDisabledGitHooksEnv(env, hooksDir) {
61936
62288
  };
61937
62289
  }
61938
62290
  function git(checkout, args, hooksDir) {
61939
- return (0, import_node_child_process18.execFileSync)("git", ["-C", checkout, "-c", `core.hooksPath=${hooksDir}`, ...args], {
62291
+ return (0, import_node_child_process19.execFileSync)("git", ["-C", checkout, "-c", `core.hooksPath=${hooksDir}`, ...args], {
61940
62292
  encoding: "utf8",
61941
62293
  timeout: 3e4,
61942
62294
  env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
@@ -62624,7 +62976,7 @@ var BLAST_RADIUS_FLOOR_PATTERNS = [/^supabase\/migrations\//, /^packages\/db\/sr
62624
62976
  function isBlastRadiusFloorPath(path29) {
62625
62977
  return BLAST_RADIUS_FLOOR_PATTERNS.some((re) => re.test(path29));
62626
62978
  }
62627
- var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process19.execFile);
62979
+ var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process20.execFile);
62628
62980
  async function defaultListRunDiffPaths(opts) {
62629
62981
  const parse8 = (stdout) => stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
62630
62982
  try {
@@ -68961,14 +69313,14 @@ async function renderPairingQrSvg(payload) {
68961
69313
  }
68962
69314
 
68963
69315
  // src/executor-server.ts
68964
- var import_node_child_process20 = require("node:child_process");
69316
+ var import_node_child_process21 = require("node:child_process");
68965
69317
  function defaultReadinessRunner(provider) {
68966
69318
  if (provider !== "codex" && provider !== "claude" && provider !== "agy") {
68967
69319
  throw new Error(`unsupported executor provider: ${String(provider)}`);
68968
69320
  }
68969
69321
  const command = provider === "claude" ? "claude" : provider === "agy" ? "agy" : "codex";
68970
69322
  return (args) => {
68971
- const r = (0, import_node_child_process20.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3, shell: true });
69323
+ const r = (0, import_node_child_process21.spawnSync)(command, args, { encoding: "utf8", timeout: 8e3, shell: true });
68972
69324
  return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
68973
69325
  };
68974
69326
  }
@@ -69111,7 +69463,7 @@ function createSelfReviewTurn(deps) {
69111
69463
 
69112
69464
  // src/director-reseed.ts
69113
69465
  var import_node_fs21 = require("node:fs");
69114
- var import_node_readline = require("node:readline");
69466
+ var import_node_readline2 = require("node:readline");
69115
69467
  var import_node_path35 = require("node:path");
69116
69468
  function estimateTokens(s) {
69117
69469
  return Buffer.byteLength(s, "utf8");
@@ -69264,7 +69616,7 @@ async function readSessionRows(logsDir, files, sessionIds) {
69264
69616
  const filePath = (0, import_node_path35.join)(logsDir, f);
69265
69617
  try {
69266
69618
  const stream = (0, import_node_fs21.createReadStream)(filePath, { encoding: "utf8" });
69267
- const rl = (0, import_node_readline.createInterface)({ input: stream, crlfDelay: Infinity });
69619
+ const rl = (0, import_node_readline2.createInterface)({ input: stream, crlfDelay: Infinity });
69268
69620
  try {
69269
69621
  for await (const line of rl) {
69270
69622
  if (line.trim() === "") continue;
@@ -69837,7 +70189,7 @@ function neutralCheckoutCwd(stateDir) {
69837
70189
  import_node_fs23.default.mkdirSync(dir, { recursive: true });
69838
70190
  if (!import_node_fs23.default.existsSync(import_node_path38.default.join(dir, ".git"))) {
69839
70191
  try {
69840
- (0, import_node_child_process21.spawnSync)("git", ["init", "-b", "main"], { cwd: dir, stdio: "ignore" });
70192
+ (0, import_node_child_process22.spawnSync)("git", ["init", "-b", "main"], { cwd: dir, stdio: "ignore" });
69841
70193
  } catch {
69842
70194
  }
69843
70195
  }
@@ -70348,7 +70700,7 @@ function resolveDefaultBranch(checkoutPath) {
70348
70700
  if (!checkoutPath) return "main";
70349
70701
  const runGit = (args) => {
70350
70702
  try {
70351
- return (0, import_node_child_process21.execFileSync)("git", ["-C", checkoutPath, ...args], {
70703
+ return (0, import_node_child_process22.execFileSync)("git", ["-C", checkoutPath, ...args], {
70352
70704
  encoding: "utf8",
70353
70705
  stdio: ["ignore", "pipe", "ignore"],
70354
70706
  timeout: 15e3,
@@ -72116,7 +72468,7 @@ function parseConfig() {
72116
72468
  }
72117
72469
  function scanForOtherBridges() {
72118
72470
  try {
72119
- const result = (0, import_node_child_process21.spawnSync)("pgrep", ["-f", "mrrlin-mcp director-bridge"], {
72471
+ const result = (0, import_node_child_process22.spawnSync)("pgrep", ["-f", "mrrlin-mcp director-bridge"], {
72120
72472
  encoding: "utf8"
72121
72473
  });
72122
72474
  if (result.status !== 0) return [];
@@ -74828,13 +75180,13 @@ function augmentProcessPathWithCommonDirs() {
74828
75180
  }
74829
75181
  augmentProcessPathWithCommonDirs();
74830
75182
  function pm2Runner(args) {
74831
- const r = (0, import_node_child_process22.spawnSync)("pm2", args, { encoding: "utf8" });
75183
+ const r = (0, import_node_child_process23.spawnSync)("pm2", args, { encoding: "utf8" });
74832
75184
  process.stderr.write(r.stdout ?? "");
74833
75185
  process.stderr.write(r.stderr ?? "");
74834
75186
  return { code: r.status ?? 1, stdout: r.stdout ?? "" };
74835
75187
  }
74836
75188
  function whichBin(bin) {
74837
- const r = (0, import_node_child_process22.spawnSync)("which", [bin], { encoding: "utf8" });
75189
+ const r = (0, import_node_child_process23.spawnSync)("which", [bin], { encoding: "utf8" });
74838
75190
  const out = (r.stdout ?? "").trim();
74839
75191
  return r.status === 0 && out ? out.split("\n")[0] ?? null : null;
74840
75192
  }
@@ -74849,7 +75201,7 @@ function bootHookStatus() {
74849
75201
  { label: "com.PM2", plist: import_node_path43.default.join(agents, `pm2.${(0, import_node_os20.userInfo)().username}.plist`) }
74850
75202
  ];
74851
75203
  for (const candidate of candidates) {
74852
- const printed = (0, import_node_child_process22.spawnSync)("launchctl", ["print", `gui/${uid}/${candidate.label}`], { encoding: "utf8" });
75204
+ const printed = (0, import_node_child_process23.spawnSync)("launchctl", ["print", `gui/${uid}/${candidate.label}`], { encoding: "utf8" });
74853
75205
  if (printed.status !== 0) continue;
74854
75206
  if (!(0, import_node_fs25.existsSync)(candidate.plist)) continue;
74855
75207
  const out = printed.stdout ?? "";
@@ -75063,8 +75415,8 @@ async function main() {
75063
75415
  );
75064
75416
  }
75065
75417
  const { command: command2, args, env } = browserServeArgs();
75066
- const r = (0, import_node_child_process22.spawnSync)(command2, args, { stdio: "inherit", env: { ...process.env, ...env } });
75067
- process.exitCode = r.status ?? 1;
75418
+ const exitCode = await runBrowserServeProxy({ command: command2, args, env });
75419
+ process.exitCode = exitCode;
75068
75420
  return;
75069
75421
  }
75070
75422
  case "browser-status": {
@@ -75074,7 +75426,7 @@ async function main() {
75074
75426
  }
75075
75427
  case "external-agents-serve": {
75076
75428
  const { command: command2, args } = externalAgentsServeArgs();
75077
- const r = (0, import_node_child_process22.spawnSync)(command2, args, { stdio: "inherit", env: process.env });
75429
+ const r = (0, import_node_child_process23.spawnSync)(command2, args, { stdio: "inherit", env: process.env });
75078
75430
  process.exitCode = r.status ?? 1;
75079
75431
  return;
75080
75432
  }
@@ -75151,7 +75503,7 @@ async function main() {
75151
75503
  );
75152
75504
  }
75153
75505
  const realProviderRunner = (command2) => (args) => {
75154
- const r = (0, import_node_child_process22.spawnSync)(command2, args, { encoding: "utf8", timeout: 8e3 });
75506
+ const r = (0, import_node_child_process23.spawnSync)(command2, args, { encoding: "utf8", timeout: 8e3 });
75155
75507
  return { status: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
75156
75508
  };
75157
75509
  for (const provider of ["codex", "claude", "agy"]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrrlin-dev/mcp",
3
- "version": "0.4.98",
3
+ "version": "0.4.100",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mrrlin-mcp": "dist/bin.cjs"