@mrrlin-dev/mcp 0.3.41 → 0.3.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +206 -22
- package/package.json +5 -4
package/dist/bin.cjs
CHANGED
|
@@ -20672,12 +20672,18 @@ function browserPaths(homeDir = import_node_os.default.homedir()) {
|
|
|
20672
20672
|
const root = import_node_path.default.join(homeDir, ".mrrlin", "browser");
|
|
20673
20673
|
return { root, browsersPath: import_node_path.default.join(root, "browsers"), profilePath: import_node_path.default.join(root, "profile") };
|
|
20674
20674
|
}
|
|
20675
|
-
function resolvePackageBin(pkg) {
|
|
20675
|
+
function resolvePackageBin(pkg, binName) {
|
|
20676
20676
|
const require2 = moduleRequire();
|
|
20677
20677
|
const pkgJsonPath = require2.resolve(`${pkg}/package.json`);
|
|
20678
20678
|
const pkgJson = require2(`${pkg}/package.json`);
|
|
20679
20679
|
const bin = pkgJson.bin;
|
|
20680
|
-
|
|
20680
|
+
let rel;
|
|
20681
|
+
if (binName && bin && typeof bin !== "string") {
|
|
20682
|
+
rel = bin[binName];
|
|
20683
|
+
if (!rel) throw new Error(`${pkg} has no bin entry named ${binName}`);
|
|
20684
|
+
} else {
|
|
20685
|
+
rel = typeof bin === "string" ? bin : bin ? Object.values(bin)[0] : void 0;
|
|
20686
|
+
}
|
|
20681
20687
|
if (!rel) throw new Error(`${pkg} has no bin entry to resolve a CLI from`);
|
|
20682
20688
|
return import_node_path.default.join(import_node_path.default.dirname(pkgJsonPath), rel);
|
|
20683
20689
|
}
|
|
@@ -20691,6 +20697,13 @@ function browserServeArgs(homeDir = import_node_os.default.homedir()) {
|
|
|
20691
20697
|
env: { PLAYWRIGHT_BROWSERS_PATH: browsersPath }
|
|
20692
20698
|
};
|
|
20693
20699
|
}
|
|
20700
|
+
function externalAgentsServeArgs() {
|
|
20701
|
+
return {
|
|
20702
|
+
command: process.execPath,
|
|
20703
|
+
// node
|
|
20704
|
+
args: [resolvePackageBin("@mrrlin-dev/external-agents", "external-agents-mcp")]
|
|
20705
|
+
};
|
|
20706
|
+
}
|
|
20694
20707
|
async function installBrowser(opts = {}) {
|
|
20695
20708
|
const homeDir = opts.homeDir ?? import_node_os.default.homedir();
|
|
20696
20709
|
const { browsersPath } = browserPaths(homeDir);
|
|
@@ -20747,8 +20760,9 @@ function mrrlinTable(binPath, distribution, serveEnv) {
|
|
|
20747
20760
|
}
|
|
20748
20761
|
return { ...base, startup_timeout_sec: 30 };
|
|
20749
20762
|
}
|
|
20750
|
-
function externalAgentsTable() {
|
|
20751
|
-
|
|
20763
|
+
function externalAgentsTable(binPath, distribution) {
|
|
20764
|
+
const base = distribution === "npm" ? { command: "mrrlin-mcp", args: ["external-agents-serve"] } : { command: "node", args: [binPath, "external-agents-serve"] };
|
|
20765
|
+
return { ...base, startup_timeout_sec: 30 };
|
|
20752
20766
|
}
|
|
20753
20767
|
function browserTable(binPath, distribution, homeDir) {
|
|
20754
20768
|
const base = distribution === "npm" ? { command: "mrrlin-mcp", args: ["browser-serve"] } : { command: "node", args: [binPath, "browser-serve"] };
|
|
@@ -20773,8 +20787,22 @@ function managedBlocks(options, distribution) {
|
|
|
20773
20787
|
},
|
|
20774
20788
|
{
|
|
20775
20789
|
id: "external-agents",
|
|
20776
|
-
expected: externalAgentsTable(),
|
|
20777
|
-
blockRe: blockRegex("external-agents")
|
|
20790
|
+
expected: externalAgentsTable(options.binPath, distribution),
|
|
20791
|
+
blockRe: blockRegex("external-agents"),
|
|
20792
|
+
// Match ONLY the exact shape this installer used to write: a bare command, optionally with
|
|
20793
|
+
// empty args / a startup_timeout_sec, and NOTHING else. An extra key means the operator
|
|
20794
|
+
// customized the block — most plausibly a hand-added `env` carrying provider API keys, which
|
|
20795
|
+
// renderBlock() would silently drop on rewrite (it renders strictly from `expected`). Such a
|
|
20796
|
+
// block must fall through to CODEX_CONFIG_CONFLICT so replacing it takes an explicit --force,
|
|
20797
|
+
// rather than losing an operator's credentials during a routine update. We deliberately do
|
|
20798
|
+
// NOT carry the env forward instead: KNOWN_MRRLIN_ENV_KEYS treats any foreign key as
|
|
20799
|
+
// operator-authored and never-preserve, so a carried key would turn the NEXT bare re-run into
|
|
20800
|
+
// a conflict and break idempotency.
|
|
20801
|
+
isLegacyOurs: (actual) => {
|
|
20802
|
+
const legacyKeys = /* @__PURE__ */ new Set(["command", "args", "startup_timeout_sec"]);
|
|
20803
|
+
if (!Object.keys(actual).every((key) => legacyKeys.has(key))) return false;
|
|
20804
|
+
return actual.command === "external-agents-mcp" && (actual.args === void 0 || Array.isArray(actual.args) && actual.args.length === 0);
|
|
20805
|
+
}
|
|
20778
20806
|
}
|
|
20779
20807
|
];
|
|
20780
20808
|
}
|
|
@@ -20917,6 +20945,12 @@ async function installCodex(options) {
|
|
|
20917
20945
|
if (action === "noop") action = "env-preserved";
|
|
20918
20946
|
continue;
|
|
20919
20947
|
}
|
|
20948
|
+
if (block.isLegacyOurs?.(existingTable)) {
|
|
20949
|
+
content = replaceBlock(content, block.blockRe, renderBlock(block));
|
|
20950
|
+
action = "replaced";
|
|
20951
|
+
mutated = true;
|
|
20952
|
+
continue;
|
|
20953
|
+
}
|
|
20920
20954
|
if (!options.force) {
|
|
20921
20955
|
const err = {
|
|
20922
20956
|
code: "CODEX_CONFIG_CONFLICT",
|
|
@@ -36358,6 +36392,7 @@ var openApiOperationIds = {
|
|
|
36358
36392
|
listInboxItems: "listInboxItems",
|
|
36359
36393
|
decideInboxItem: "decideInboxItem",
|
|
36360
36394
|
markInboxItemRead: "markInboxItemRead",
|
|
36395
|
+
markInboxItemsReadByIds: "markInboxItemsReadByIds",
|
|
36361
36396
|
markAllInboxItemsRead: "markAllInboxItemsRead",
|
|
36362
36397
|
searchKnowledge: "searchKnowledge",
|
|
36363
36398
|
updateExecutionRun: "updateExecutionRun",
|
|
@@ -37496,16 +37531,116 @@ var mrrlinSchedulerPendingReasonSchema = external_exports.enum([
|
|
|
37496
37531
|
"verification_due",
|
|
37497
37532
|
"wake_floor_passed"
|
|
37498
37533
|
]);
|
|
37534
|
+
var mrrlinAutonomousStepSchema = external_exports.enum([
|
|
37535
|
+
"noop",
|
|
37536
|
+
"needs_human",
|
|
37537
|
+
"enqueue_spec_draft",
|
|
37538
|
+
"enqueue_consensus",
|
|
37539
|
+
"auto_approve_spec_and_run",
|
|
37540
|
+
"create_execution_run"
|
|
37541
|
+
]);
|
|
37542
|
+
var mrrlinAutonomousStepReasonSchema = external_exports.enum([
|
|
37543
|
+
"task_terminal",
|
|
37544
|
+
"active_run_exists",
|
|
37545
|
+
"blocked_by_active",
|
|
37546
|
+
"draft_running",
|
|
37547
|
+
"consensus_running",
|
|
37548
|
+
"spec_missing",
|
|
37549
|
+
"spec_draft_failed",
|
|
37550
|
+
"spec_not_specs_folder",
|
|
37551
|
+
"awaiting_clarification",
|
|
37552
|
+
"consensus_blocked",
|
|
37553
|
+
"consensus_disabled_spec_not_ready",
|
|
37554
|
+
"spec_approval_pending",
|
|
37555
|
+
"non_code_execution_unsupported"
|
|
37556
|
+
]);
|
|
37557
|
+
var mrrlinAutonomousStepVerdictSchema = external_exports.object({
|
|
37558
|
+
step: mrrlinAutonomousStepSchema,
|
|
37559
|
+
reason: mrrlinAutonomousStepReasonSchema.nullable(),
|
|
37560
|
+
// Additive: when reason is "spec_draft_failed" or "consensus_blocked" (the two reasons that park
|
|
37561
|
+
// a task until a human intervenes), the attempt_count of the async_jobs row that produced that
|
|
37562
|
+
// outcome — so the operator can see "failed x3" and judge whether a retry mechanism is needed.
|
|
37563
|
+
// null for every other reason/step (not applicable), and also null if the job could not be found.
|
|
37564
|
+
failureCount: external_exports.number().int().min(0).nullable()
|
|
37565
|
+
});
|
|
37499
37566
|
var mrrlinSchedulerPendingTaskSchema = external_exports.object({
|
|
37500
37567
|
dueAt: external_exports.string().datetime(),
|
|
37501
37568
|
reason: mrrlinSchedulerPendingReasonSchema,
|
|
37502
|
-
task: mrrlinTaskSchema
|
|
37569
|
+
task: mrrlinTaskSchema,
|
|
37570
|
+
// Additive: whether the scheduler considers this task due NOW (per `deriveSchedulerDue`), as
|
|
37571
|
+
// opposed to `dueAt` reporting a future trigger or the evaluatedAt fallback when the task has no
|
|
37572
|
+
// trigger at all. Consumers must read this instead of re-deriving due-ness by re-parsing `dueAt`
|
|
37573
|
+
// against "now" — a task with no trigger has `dueAt === evaluatedAt`, which a naive `dueAt <= now`
|
|
37574
|
+
// re-derivation would misclassify as due.
|
|
37575
|
+
due: external_exports.boolean(),
|
|
37576
|
+
// Additive: the REAL admission verdict for this row, computed only inside the tick's bounded
|
|
37577
|
+
// per-cycle slice (`resolveSchedulerProjectLimit`). `null` means "not evaluated this cycle" —
|
|
37578
|
+
// the row is a genuine actionable candidate by the cheap classifier, but beyond the bound the
|
|
37579
|
+
// tick actually looks at, so no real verdict exists yet. Never infer readiness from `null`.
|
|
37580
|
+
verdict: mrrlinAutonomousStepVerdictSchema.nullable()
|
|
37581
|
+
});
|
|
37582
|
+
var mrrlinSchedulerParkedReasonSchema = external_exports.enum([
|
|
37583
|
+
"running",
|
|
37584
|
+
"awaiting_handoff",
|
|
37585
|
+
"awaiting_clarification",
|
|
37586
|
+
"spec_awaiting_approval",
|
|
37587
|
+
"blocked_by_active"
|
|
37588
|
+
]);
|
|
37589
|
+
var mrrlinSchedulerParkedTaskSchema = external_exports.object({
|
|
37590
|
+
task: mrrlinTaskSchema,
|
|
37591
|
+
reason: mrrlinSchedulerParkedReasonSchema,
|
|
37592
|
+
blockedByIds: external_exports.array(mrrlinTaskIdSchema),
|
|
37593
|
+
inboxItemId: external_exports.string().nullable(),
|
|
37594
|
+
runId: mrrlinExecutionRunIdSchema.nullable()
|
|
37595
|
+
});
|
|
37596
|
+
var mrrlinInFlightSchedulerEntrySchema = external_exports.discriminatedUnion("kind", [
|
|
37597
|
+
external_exports.object({
|
|
37598
|
+
kind: external_exports.literal("run"),
|
|
37599
|
+
taskId: mrrlinTaskIdSchema,
|
|
37600
|
+
runId: mrrlinExecutionRunIdSchema,
|
|
37601
|
+
status: external_exports.string(),
|
|
37602
|
+
// Additive: the task's own title, resolved server-side from the same task list the handler
|
|
37603
|
+
// already loaded for this request (no extra query). null only when the task itself could not
|
|
37604
|
+
// be found (should not happen for a `run` entry, whose taskId is required, but the wire
|
|
37605
|
+
// contract stays honest about it rather than assuming).
|
|
37606
|
+
taskTitle: external_exports.string().nullable()
|
|
37607
|
+
}),
|
|
37608
|
+
external_exports.object({
|
|
37609
|
+
kind: external_exports.literal("async_job"),
|
|
37610
|
+
taskId: mrrlinTaskIdSchema.nullable(),
|
|
37611
|
+
jobId: external_exports.string(),
|
|
37612
|
+
toolName: external_exports.enum(["draft_task_spec", "run_spec_consensus"]),
|
|
37613
|
+
// Additive: same resolution as the `run` variant above. null when `taskId` is null (a job
|
|
37614
|
+
// genuinely untied to a visible task) or the task could not be found.
|
|
37615
|
+
taskTitle: external_exports.string().nullable()
|
|
37616
|
+
})
|
|
37617
|
+
]);
|
|
37618
|
+
var mrrlinIneligibleTaskSchema = external_exports.object({
|
|
37619
|
+
task: mrrlinTaskSchema,
|
|
37620
|
+
autonomyLevel: mrrlinAutonomyLevelSchema
|
|
37503
37621
|
});
|
|
37504
37622
|
var schedulerPendingTasksResponseSchema = external_exports.object({
|
|
37505
37623
|
data: external_exports.object({
|
|
37506
37624
|
evaluatedAt: external_exports.string().datetime(),
|
|
37507
37625
|
pending: external_exports.array(mrrlinSchedulerPendingTaskSchema),
|
|
37508
|
-
|
|
37626
|
+
parked: external_exports.array(mrrlinSchedulerParkedTaskSchema),
|
|
37627
|
+
slots: external_exports.number().int(),
|
|
37628
|
+
perProjectLimit: external_exports.number().int().min(1),
|
|
37629
|
+
policy: mrrlinProjectSchedulerPolicySchema,
|
|
37630
|
+
// Additive (see mrrlinInFlightSchedulerEntrySchema doc): the actual runs/jobs occupying
|
|
37631
|
+
// autonomous capacity right now. `slots` is derived from THIS SAME list server-side, so the
|
|
37632
|
+
// count and the list can never disagree.
|
|
37633
|
+
inFlight: external_exports.array(mrrlinInFlightSchedulerEntrySchema),
|
|
37634
|
+
// Additive: tasks the tick never even considers (autonomyLevel outside
|
|
37635
|
+
// policy.eligibleAutonomyLevels), excluding terminal tasks.
|
|
37636
|
+
ineligible: external_exports.array(mrrlinIneligibleTaskSchema),
|
|
37637
|
+
// Additive: how many non-terminal tasks were excluded from BOTH `pending` and `parked` because
|
|
37638
|
+
// their assignee is set and does not match the project operator (github.operator). A COUNT
|
|
37639
|
+
// only, deliberately — the operator asked not to show a list of other people's tasks, just a
|
|
37640
|
+
// disclosure that some exist, so a misconfigured `github.operator` (e.g. it doesn't match the
|
|
37641
|
+
// person actually running the project) is visible as a large number instead of the autopilot
|
|
37642
|
+
// silently doing nothing.
|
|
37643
|
+
excludedByOwnershipCount: external_exports.number().int().min(0)
|
|
37509
37644
|
})
|
|
37510
37645
|
});
|
|
37511
37646
|
var wakeDirectorRequestSchema = external_exports.object({
|
|
@@ -37594,6 +37729,7 @@ var mrrlinInboxItemSchema = external_exports.object({
|
|
|
37594
37729
|
decidedBy: external_exports.string().min(1).nullable(),
|
|
37595
37730
|
dedupKey: external_exports.string().nullable(),
|
|
37596
37731
|
directorSessionId: external_exports.string().min(1).nullable(),
|
|
37732
|
+
groupId: external_exports.string().nullable().default(null),
|
|
37597
37733
|
id: mrrlinInboxItemIdSchema,
|
|
37598
37734
|
kind: mrrlinInboxItemKindSchema,
|
|
37599
37735
|
origin: external_exports.string().nullable().optional(),
|
|
@@ -37616,6 +37752,7 @@ var mrrlinInboxItemCreateSchema = external_exports.object({
|
|
|
37616
37752
|
actionPayload: mrrlinInboxItemActionPayloadSchema.nullable().optional(),
|
|
37617
37753
|
body: external_exports.string().min(1),
|
|
37618
37754
|
directorSessionId: external_exports.string().min(1).optional(),
|
|
37755
|
+
groupId: external_exports.string().min(1).optional(),
|
|
37619
37756
|
id: mrrlinInboxItemIdSchema,
|
|
37620
37757
|
kind: mrrlinInboxItemKindSchema,
|
|
37621
37758
|
origin: external_exports.string().min(1).optional(),
|
|
@@ -37646,6 +37783,7 @@ var mrrlinInboxItemDecideSchema = external_exports.object({
|
|
|
37646
37783
|
}
|
|
37647
37784
|
});
|
|
37648
37785
|
var mrrlinInboxItemListFiltersSchema = external_exports.object({
|
|
37786
|
+
groupId: external_exports.string().optional(),
|
|
37649
37787
|
kind: mrrlinInboxItemKindSchema.optional(),
|
|
37650
37788
|
readState: external_exports.enum(["read", "unread"]).optional(),
|
|
37651
37789
|
status: mrrlinInboxItemStatusSchema.optional(),
|
|
@@ -37662,6 +37800,15 @@ var inboxMarkAllReadResponseSchema = external_exports.object({
|
|
|
37662
37800
|
readAt: external_exports.string().datetime()
|
|
37663
37801
|
})
|
|
37664
37802
|
});
|
|
37803
|
+
var mrrlinInboxItemsMarkReadRequestSchema = external_exports.object({
|
|
37804
|
+
ids: external_exports.array(external_exports.string().min(1)).min(1)
|
|
37805
|
+
});
|
|
37806
|
+
var inboxItemsMarkReadResponseSchema = external_exports.object({
|
|
37807
|
+
data: external_exports.object({
|
|
37808
|
+
markedCount: external_exports.number().int().nonnegative(),
|
|
37809
|
+
readAt: external_exports.string().datetime()
|
|
37810
|
+
})
|
|
37811
|
+
});
|
|
37665
37812
|
var inboxItemResponseSchema = external_exports.object({ data: mrrlinInboxItemSchema });
|
|
37666
37813
|
var inboxItemListResponseSchema = external_exports.object({ data: external_exports.array(mrrlinInboxItemSchema) });
|
|
37667
37814
|
|
|
@@ -38284,6 +38431,14 @@ function createMrrlinClient(config2) {
|
|
|
38284
38431
|
});
|
|
38285
38432
|
return inboxItemReadResponseSchema.parse(body).data;
|
|
38286
38433
|
},
|
|
38434
|
+
async markInboxItemsReadByIds(projectSlug, ids) {
|
|
38435
|
+
const body = await request(`${projectPath(projectSlug)}/inbox/mark-read`, {
|
|
38436
|
+
body: JSON.stringify({ ids }),
|
|
38437
|
+
headers: { "content-type": "application/json" },
|
|
38438
|
+
method: "POST"
|
|
38439
|
+
});
|
|
38440
|
+
return inboxItemsMarkReadResponseSchema.parse(body).data;
|
|
38441
|
+
},
|
|
38287
38442
|
async markAllInboxItemsRead(projectSlug) {
|
|
38288
38443
|
const body = await request(`${projectPath(projectSlug)}/inbox/mark-all-read`, {
|
|
38289
38444
|
method: "POST"
|
|
@@ -38955,7 +39110,7 @@ function startCodexProbe(deps = {}) {
|
|
|
38955
39110
|
}
|
|
38956
39111
|
|
|
38957
39112
|
// src/_generated/version.ts
|
|
38958
|
-
var PKG_VERSION = "0.3.
|
|
39113
|
+
var PKG_VERSION = "0.3.45";
|
|
38959
39114
|
|
|
38960
39115
|
// src/api-base-url.ts
|
|
38961
39116
|
var DEFAULT_API_BASE_URL = "http://127.0.0.1:8787";
|
|
@@ -39248,6 +39403,19 @@ async function collectAgentPoolSnapshot(deps) {
|
|
|
39248
39403
|
);
|
|
39249
39404
|
}
|
|
39250
39405
|
|
|
39406
|
+
// src/external-agents-bin.ts
|
|
39407
|
+
function resolveExternalAgentsCliInvocation(override) {
|
|
39408
|
+
if (override && override.trim()) return { command: override, prefixArgs: [] };
|
|
39409
|
+
try {
|
|
39410
|
+
return {
|
|
39411
|
+
command: "node",
|
|
39412
|
+
prefixArgs: [resolvePackageBin("@mrrlin-dev/external-agents", "external-agents")]
|
|
39413
|
+
};
|
|
39414
|
+
} catch {
|
|
39415
|
+
return { command: "external-agents", prefixArgs: [] };
|
|
39416
|
+
}
|
|
39417
|
+
}
|
|
39418
|
+
|
|
39251
39419
|
// src/agent-pool-loop.ts
|
|
39252
39420
|
var DEFAULT_INTERVAL_MS2 = 6e4;
|
|
39253
39421
|
function agentPoolLoopDisabled(env = process.env) {
|
|
@@ -39255,7 +39423,7 @@ function agentPoolLoopDisabled(env = process.env) {
|
|
|
39255
39423
|
}
|
|
39256
39424
|
function defaultRunCli(args) {
|
|
39257
39425
|
const cli = process.env["EXTERNAL_AGENTS_CLI"];
|
|
39258
|
-
const
|
|
39426
|
+
const { command, prefixArgs } = cli ? { command: "node", prefixArgs: [cli] } : resolveExternalAgentsCliInvocation();
|
|
39259
39427
|
return new Promise((resolve) => {
|
|
39260
39428
|
let stdout = "";
|
|
39261
39429
|
let settled = false;
|
|
@@ -39266,7 +39434,7 @@ function defaultRunCli(args) {
|
|
|
39266
39434
|
}
|
|
39267
39435
|
};
|
|
39268
39436
|
try {
|
|
39269
|
-
const child = (0, import_node_child_process5.spawn)(
|
|
39437
|
+
const child = (0, import_node_child_process5.spawn)(command, [...prefixArgs, ...args], { stdio: ["ignore", "pipe", "ignore"] });
|
|
39270
39438
|
const timer = setTimeout(() => {
|
|
39271
39439
|
try {
|
|
39272
39440
|
child.kill("SIGKILL");
|
|
@@ -53128,7 +53296,7 @@ var import_node_child_process11 = require("node:child_process");
|
|
|
53128
53296
|
function errMessage3(err) {
|
|
53129
53297
|
return err instanceof Error ? err.message : String(err);
|
|
53130
53298
|
}
|
|
53131
|
-
function runExternalAgents(bin, args, timeoutMs, spawn3) {
|
|
53299
|
+
function runExternalAgents(bin, args, label, timeoutMs, spawn3) {
|
|
53132
53300
|
return new Promise((resolve) => {
|
|
53133
53301
|
let settled = false;
|
|
53134
53302
|
const timerRef = { id: void 0 };
|
|
@@ -53154,20 +53322,20 @@ function runExternalAgents(bin, args, timeoutMs, spawn3) {
|
|
|
53154
53322
|
let stdout = "";
|
|
53155
53323
|
timerRef.id = setTimeout(() => {
|
|
53156
53324
|
child.kill("SIGKILL");
|
|
53157
|
-
finish({ code: null, stdout, error: `external-agents ${
|
|
53325
|
+
finish({ code: null, stdout, error: `external-agents ${label} timed out after ${timeoutMs}ms` });
|
|
53158
53326
|
}, timeoutMs);
|
|
53159
53327
|
child.stdout?.on("data", (chunk) => {
|
|
53160
53328
|
stdout += chunk.toString();
|
|
53161
53329
|
});
|
|
53162
53330
|
child.stderr?.on("data", () => {
|
|
53163
53331
|
});
|
|
53164
|
-
child.on("error", (err) => finish({ code: null, stdout, error: `external-agents ${
|
|
53332
|
+
child.on("error", (err) => finish({ code: null, stdout, error: `external-agents ${label} error: ${errMessage3(err)}` }));
|
|
53165
53333
|
child.on("close", (code) => finish({ code, stdout }));
|
|
53166
53334
|
});
|
|
53167
53335
|
}
|
|
53168
53336
|
async function pickPanel(input, deps) {
|
|
53169
53337
|
const spawn3 = deps?.spawn ?? import_node_child_process11.spawn;
|
|
53170
|
-
const
|
|
53338
|
+
const { command, prefixArgs } = resolveExternalAgentsCliInvocation(deps?.externalAgentsBin);
|
|
53171
53339
|
const args = [
|
|
53172
53340
|
"pick",
|
|
53173
53341
|
"--tier-prefer",
|
|
@@ -53179,7 +53347,7 @@ async function pickPanel(input, deps) {
|
|
|
53179
53347
|
"--exclude-providers",
|
|
53180
53348
|
input.excludeProvider
|
|
53181
53349
|
];
|
|
53182
|
-
const r = await runExternalAgents(
|
|
53350
|
+
const r = await runExternalAgents(command, [...prefixArgs, ...args], "pick", input.timeoutMs, spawn3);
|
|
53183
53351
|
if (r.error) return { ok: false, error: r.error };
|
|
53184
53352
|
if (r.code === 3) return { ok: true, agents: [] };
|
|
53185
53353
|
if (r.code !== 0) return { ok: false, error: `external-agents pick exited ${r.code}` };
|
|
@@ -53188,9 +53356,9 @@ async function pickPanel(input, deps) {
|
|
|
53188
53356
|
}
|
|
53189
53357
|
async function dispatchHead(agentId, prompt, timeoutMs, deps) {
|
|
53190
53358
|
const spawn3 = deps?.spawn ?? import_node_child_process11.spawn;
|
|
53191
|
-
const
|
|
53359
|
+
const { command, prefixArgs } = resolveExternalAgentsCliInvocation(deps?.externalAgentsBin);
|
|
53192
53360
|
const args = ["dispatch", agentId, "--json", prompt];
|
|
53193
|
-
const r = await runExternalAgents(
|
|
53361
|
+
const r = await runExternalAgents(command, [...prefixArgs, ...args], "dispatch", timeoutMs, spawn3);
|
|
53194
53362
|
if (r.error) return { ok: false, error: r.error };
|
|
53195
53363
|
const lines2 = r.stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
|
53196
53364
|
const jsonLine = [...lines2].reverse().find((l) => l[0] === "{");
|
|
@@ -53551,8 +53719,9 @@ async function run(ctx, input) {
|
|
|
53551
53719
|
planId = plans.find((p) => p.specWikiPageId === input.pageId)?.id ?? null;
|
|
53552
53720
|
}
|
|
53553
53721
|
if (taskId) {
|
|
53722
|
+
const scopeId = taskId;
|
|
53723
|
+
const groupId = clarifications.length > 1 ? `II-${scopeId}-gate-group-${(0, import_node_crypto8.createHash)("sha256").update(clarifications.map((c) => c.question).sort().join("\n")).digest("hex").slice(0, 10)}` : void 0;
|
|
53554
53724
|
for (const clarification of clarifications) {
|
|
53555
|
-
const scopeId = taskId;
|
|
53556
53725
|
const id = `II-${scopeId}-gate-${(0, import_node_crypto8.createHash)("sha256").update(clarification.question).digest("hex").slice(0, 10)}`;
|
|
53557
53726
|
try {
|
|
53558
53727
|
const questionOptions = buildGateQuestionOptions(clarification.question, clarification.category);
|
|
@@ -53562,15 +53731,17 @@ async function run(ctx, input) {
|
|
|
53562
53731
|
taskId: scopeId,
|
|
53563
53732
|
body: clarification.question,
|
|
53564
53733
|
origin: "gate",
|
|
53565
|
-
...questionOptions ? { questionOptions } : {}
|
|
53734
|
+
...questionOptions ? { questionOptions } : {},
|
|
53735
|
+
...groupId ? { groupId } : {}
|
|
53566
53736
|
});
|
|
53567
53737
|
} catch {
|
|
53568
53738
|
}
|
|
53569
53739
|
}
|
|
53570
53740
|
filedQuestionCount = clarifications.length;
|
|
53571
53741
|
} else if (planId) {
|
|
53742
|
+
const scopeId = planId;
|
|
53743
|
+
const groupId = clarifications.length > 1 ? `II-${scopeId}-gate-group-${(0, import_node_crypto8.createHash)("sha256").update(clarifications.map((c) => c.question).sort().join("\n")).digest("hex").slice(0, 10)}` : void 0;
|
|
53572
53744
|
for (const clarification of clarifications) {
|
|
53573
|
-
const scopeId = planId;
|
|
53574
53745
|
const id = `II-${scopeId}-gate-${(0, import_node_crypto8.createHash)("sha256").update(clarification.question).digest("hex").slice(0, 10)}`;
|
|
53575
53746
|
try {
|
|
53576
53747
|
const questionOptions = buildGateQuestionOptions(clarification.question, clarification.category);
|
|
@@ -53580,7 +53751,8 @@ async function run(ctx, input) {
|
|
|
53580
53751
|
planId: scopeId,
|
|
53581
53752
|
body: clarification.question,
|
|
53582
53753
|
origin: "gate",
|
|
53583
|
-
...questionOptions ? { questionOptions } : {}
|
|
53754
|
+
...questionOptions ? { questionOptions } : {},
|
|
53755
|
+
...groupId ? { groupId } : {}
|
|
53584
53756
|
});
|
|
53585
53757
|
} catch {
|
|
53586
53758
|
}
|
|
@@ -55854,6 +56026,12 @@ Usage:
|
|
|
55854
56026
|
command install-codex wires for the
|
|
55855
56027
|
[mcp_servers.mrrlin-browser] block.
|
|
55856
56028
|
|
|
56029
|
+
mrrlin-mcp external-agents-serve
|
|
56030
|
+
Launch the bundled @mrrlin-dev/external-agents
|
|
56031
|
+
MCP server (multi-LLM dispatch pool). This is the
|
|
56032
|
+
command install-codex wires for the
|
|
56033
|
+
[mcp_servers.external-agents] block.
|
|
56034
|
+
|
|
55857
56035
|
mrrlin-mcp install-codex Idempotently register Mrrlin in
|
|
55858
56036
|
[--force] ~/.codex/config.toml (or CODEX_HOME). Adds an
|
|
55859
56037
|
[mcp_servers.mrrlin] block. Development
|
|
@@ -56009,6 +56187,12 @@ async function main() {
|
|
|
56009
56187
|
process.exitCode = r.status ?? 1;
|
|
56010
56188
|
return;
|
|
56011
56189
|
}
|
|
56190
|
+
case "external-agents-serve": {
|
|
56191
|
+
const { command: command2, args } = externalAgentsServeArgs();
|
|
56192
|
+
const r = (0, import_node_child_process13.spawnSync)(command2, args, { stdio: "inherit", env: process.env });
|
|
56193
|
+
process.exitCode = r.status ?? 1;
|
|
56194
|
+
return;
|
|
56195
|
+
}
|
|
56012
56196
|
case "install-codex": {
|
|
56013
56197
|
const force = rest.includes("--force");
|
|
56014
56198
|
const binPath = resolveSelfBinPath();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrrlin-dev/mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.45",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mrrlin-mcp": "dist/bin.cjs"
|
|
@@ -21,16 +21,17 @@
|
|
|
21
21
|
"@types/ws": "^8.18.1",
|
|
22
22
|
"esbuild": "^0.24.0",
|
|
23
23
|
"tsx": "^4.22.3",
|
|
24
|
+
"@mrrlin/schemas": "0.0.0",
|
|
24
25
|
"@mrrlin/director-e2e": "0.0.0",
|
|
25
26
|
"@mrrlin/wiki": "0.0.0",
|
|
26
|
-
"@mrrlin/
|
|
27
|
+
"@mrrlin/client": "0.0.0",
|
|
27
28
|
"@mrrlin/codex-client": "0.0.0",
|
|
28
|
-
"@mrrlin/tsconfig": "0.0.0"
|
|
29
|
-
"@mrrlin/client": "0.0.0"
|
|
29
|
+
"@mrrlin/tsconfig": "0.0.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@iarna/toml": "^2.2.5",
|
|
33
33
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
34
|
+
"@mrrlin-dev/external-agents": "^0.32.0",
|
|
34
35
|
"@playwright/mcp": "0.0.76",
|
|
35
36
|
"playwright-core": "1.61.0-alpha-1781023400000",
|
|
36
37
|
"proper-lockfile": "^4.1.2",
|