@mrrlin-dev/mcp 0.4.64 → 0.4.66

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 +264 -80
  2. package/package.json +3 -3
package/dist/bin.cjs CHANGED
@@ -21566,6 +21566,37 @@ function isExternalAgentsWrapper(table) {
21566
21566
  return false;
21567
21567
  }
21568
21568
  async function verifyProviderReadiness(provider, run3, opts = {}) {
21569
+ if (provider === "agy") {
21570
+ let cliResult2;
21571
+ try {
21572
+ cliResult2 = run3(["--version"]);
21573
+ if (cliResult2.status === 0) {
21574
+ return {
21575
+ ready: true,
21576
+ checks: { cli: true, version: true, auth: false, mcpReachable: false },
21577
+ details: []
21578
+ };
21579
+ } else if (cliResult2.status === null) {
21580
+ return {
21581
+ ready: false,
21582
+ checks: { cli: false, version: false, auth: false, mcpReachable: false },
21583
+ details: ["cli: `agy` binary not found on PATH"]
21584
+ };
21585
+ } else {
21586
+ return {
21587
+ ready: false,
21588
+ checks: { cli: true, version: false, auth: false, mcpReachable: false },
21589
+ details: [`cli: \`agy --version\` exited with code ${cliResult2.status}`]
21590
+ };
21591
+ }
21592
+ } catch (_e) {
21593
+ return {
21594
+ ready: false,
21595
+ checks: { cli: false, version: false, auth: false, mcpReachable: false },
21596
+ details: ["cli: `agy` binary not found on PATH"]
21597
+ };
21598
+ }
21599
+ }
21569
21600
  const checks = { cli: false, version: false, auth: false, mcpReachable: false };
21570
21601
  const details = [];
21571
21602
  let cliResult;
@@ -37215,7 +37246,7 @@ var mrrlinOperatorSettingsSchema = external_exports.object({
37215
37246
  // claude-director-and-runner design.md D4/D6: the operator's one selected agent-provider seat,
37216
37247
  // governing Director chat, the execution runner, and consensus/arbiter reviewer exclusion alike.
37217
37248
  // Not null, defaults to 'codex' at the DB layer, so every row already has a real value.
37218
- agentProvider: external_exports.enum(["codex", "claude"]).default("codex"),
37249
+ agentProvider: external_exports.enum(["codex", "claude", "agy"]).default("codex"),
37219
37250
  createdAt: external_exports.string().datetime(),
37220
37251
  updatedAt: external_exports.string().datetime()
37221
37252
  });
@@ -37223,7 +37254,7 @@ var mrrlinOperatorSettingsUpdateSchema = external_exports.object({
37223
37254
  consensusEnabled: external_exports.boolean().optional(),
37224
37255
  autonomyPaused: external_exports.boolean().optional(),
37225
37256
  activeProjectSlug: external_exports.string().min(1).nullable().optional(),
37226
- agentProvider: external_exports.enum(["codex", "claude"]).optional()
37257
+ agentProvider: external_exports.enum(["codex", "claude", "agy"]).optional()
37227
37258
  }).strict().refine((value) => Object.keys(value).length > 0, {
37228
37259
  message: "OperatorSettingsUpdate requires at least one field"
37229
37260
  });
@@ -37238,7 +37269,7 @@ var operatorPresenceRequestSchema = external_exports.object({ projectSlug: exter
37238
37269
  var mrrlinConsensusConfigSchema = external_exports.object({ consensusEnabled: external_exports.boolean() });
37239
37270
  var consensusConfigResponseSchema = external_exports.object({ data: mrrlinConsensusConfigSchema });
37240
37271
  var mrrlinAgentProviderConfigSchema = external_exports.object({
37241
- agentProvider: external_exports.enum(["codex", "claude"])
37272
+ agentProvider: external_exports.enum(["codex", "claude", "agy"])
37242
37273
  });
37243
37274
  var agentProviderConfigResponseSchema = external_exports.object({ data: mrrlinAgentProviderConfigSchema });
37244
37275
  var agentPoolSnapshotSchema = external_exports.object({
@@ -37273,6 +37304,40 @@ var agentCapabilitiesSchema = external_exports.object({
37273
37304
  sandboxModes: external_exports.array(external_exports.enum(["read-only", "workspace-write", "danger-full-access"])),
37274
37305
  poolProviderLabels: external_exports.array(external_exports.string())
37275
37306
  });
37307
+ var AGENT_CAPABILITIES = {
37308
+ codex: {
37309
+ listsModels: true,
37310
+ readsRateLimits: true,
37311
+ models: [],
37312
+ modelCatalog: [],
37313
+ sandboxModes: ["read-only", "workspace-write", "danger-full-access"],
37314
+ poolProviderLabels: ["openai"]
37315
+ },
37316
+ claude: {
37317
+ listsModels: false,
37318
+ readsRateLimits: false,
37319
+ // Aliases the Claude CLI documents for `--model` (`claude --help`), and what each resolved to
37320
+ // on 2026-09-04 per the CLI's own `system.init.model` frame. Keep in step with
37321
+ // packages/agent-client/src/providers/claude/models.ts — the parity test enforces equality.
37322
+ models: ["fable", "opus", "sonnet", "haiku"],
37323
+ modelCatalog: [
37324
+ { id: "fable", displayName: "Fable 5.1", description: "claude-fable-5-1" },
37325
+ { id: "opus", displayName: "Opus 5", description: "claude-opus-5" },
37326
+ { id: "sonnet", displayName: "Sonnet 5", description: "claude-sonnet-5" },
37327
+ { id: "haiku", displayName: "Haiku 4.5", description: "claude-haiku-4-5-20251001" }
37328
+ ],
37329
+ sandboxModes: ["read-only", "workspace-write", "danger-full-access"],
37330
+ poolProviderLabels: ["anthropic"]
37331
+ },
37332
+ agy: {
37333
+ listsModels: false,
37334
+ readsRateLimits: false,
37335
+ models: [],
37336
+ modelCatalog: [],
37337
+ sandboxModes: ["workspace-write"],
37338
+ poolProviderLabels: ["antigravity"]
37339
+ }
37340
+ };
37276
37341
  var providerReadinessResultSchema = external_exports.object({
37277
37342
  ready: external_exports.boolean(),
37278
37343
  checks: external_exports.object({
@@ -37285,7 +37350,8 @@ var providerReadinessResultSchema = external_exports.object({
37285
37350
  });
37286
37351
  var providerReadinessSchema = external_exports.object({
37287
37352
  codex: providerReadinessResultSchema,
37288
- claude: providerReadinessResultSchema
37353
+ claude: providerReadinessResultSchema,
37354
+ agy: providerReadinessResultSchema
37289
37355
  });
37290
37356
  var providerReadinessResponseSchema = external_exports.object({
37291
37357
  data: external_exports.object({ readiness: providerReadinessSchema.nullable() })
@@ -37384,7 +37450,7 @@ var mrrlinAsyncJobSchema = external_exports.object({
37384
37450
  updatedAt: external_exports.string(),
37385
37451
  // model-tier-planning-and-arbiter task 1.8: the seat minted at claim (or inherited from a
37386
37452
  // prior attempt on this same lease); NULL only before the first beginAttempt call pins it.
37387
- agentSeat: external_exports.enum(["codex", "claude"]).nullable().default(null)
37453
+ agentSeat: external_exports.enum(["codex", "claude", "agy"]).nullable().default(null)
37388
37454
  }).strict();
37389
37455
  var asyncJobResponseSchema = external_exports.object({ data: mrrlinAsyncJobSchema });
37390
37456
  var asyncJobMaybeResponseSchema = external_exports.object({ data: mrrlinAsyncJobSchema.nullable() });
@@ -37404,7 +37470,7 @@ var mrrlinAsyncJobBeginAttemptSchema = external_exports.object({
37404
37470
  requestedHash: external_exports.string().min(1),
37405
37471
  // task 1.8: the caller has already resolved (inherited or minted) a seat for this job by the
37406
37472
  // time it begins an attempt — required, not optional, so persistence can never be skipped.
37407
- agentSeat: external_exports.enum(["codex", "claude"])
37473
+ agentSeat: external_exports.enum(["codex", "claude", "agy"])
37408
37474
  });
37409
37475
  var mrrlinAsyncJobTerminalizeSchema = external_exports.object({
37410
37476
  leaseId: external_exports.string().min(1),
@@ -38010,7 +38076,7 @@ var mrrlinTaskSchema = external_exports.object({
38010
38076
  // Output-optional (not .default) so existing task fixtures/mocks need no churn; DB rows always
38011
38077
  // resolve it via taskRowToTask. Null reads as the pre-existing default provider and is never
38012
38078
  // backfilled -- it is NOT a mismatch against whatever provider is currently selected.
38013
- directorThreadProvider: external_exports.enum(["codex", "claude"]).nullable().optional(),
38079
+ directorThreadProvider: external_exports.enum(["codex", "claude", "agy"]).nullable().optional(),
38014
38080
  // agnostic-delivery: asserted before the work, not the deliverable-gate's differently-meaning
38015
38081
  // `attemptOutcome` asserted after it (design.md). Required at spec approval (task 3.2's API
38016
38082
  // gate), never at creation -- null on every task until then, forever on legacy tasks. Shape-only
@@ -38358,7 +38424,7 @@ var mrrlinTaskUpdateSchema = external_exports.object({
38358
38424
  category: taxonomyCategorySchema.optional(),
38359
38425
  directorSessionId: external_exports.string().min(1).optional(),
38360
38426
  directorThreadId: external_exports.string().min(1).nullable().optional(),
38361
- directorThreadProvider: external_exports.enum(["codex", "claude"]).nullable().optional(),
38427
+ directorThreadProvider: external_exports.enum(["codex", "claude", "agy"]).nullable().optional(),
38362
38428
  declaredOutcome: mrrlinDeclaredOutcomeSchema.nullable().optional(),
38363
38429
  dueDate: external_exports.string().date().nullable().optional(),
38364
38430
  impact: mrrlinTaskImpactSchema.optional(),
@@ -38679,7 +38745,7 @@ var mrrlinRunPrerequisiteSchema = external_exports.object({
38679
38745
  });
38680
38746
  var mrrlinExecutionRunSchema = external_exports.object({
38681
38747
  actor: external_exports.string().min(1),
38682
- agentSeat: external_exports.enum(["codex", "claude"]).nullable(),
38748
+ agentSeat: external_exports.enum(["codex", "claude", "agy"]).nullable(),
38683
38749
  baseSha: external_exports.string().min(1).nullable(),
38684
38750
  branch: external_exports.string().min(1).nullable(),
38685
38751
  blockingReason: mrrlinRunBlockingReasonCodeSchema.nullable(),
@@ -38739,7 +38805,7 @@ var mrrlinTaskStateSchema = external_exports.object({
38739
38805
  // claude-director-and-runner design.md D5: which provider's CLI produced retiredThreadId.
38740
38806
  // Output-optional so existing task_state fixtures/mocks need no churn; null reads as the
38741
38807
  // pre-existing default provider and is never backfilled.
38742
- retiredThreadProvider: external_exports.enum(["codex", "claude"]).nullable().optional(),
38808
+ retiredThreadProvider: external_exports.enum(["codex", "claude", "agy"]).nullable().optional(),
38743
38809
  updatedAt: external_exports.string().datetime()
38744
38810
  });
38745
38811
  var mrrlinTaskStateUpsertSchema = external_exports.object({
@@ -38781,7 +38847,7 @@ var mrrlinExecutionRunCreateSchema = external_exports.object({
38781
38847
  worktreeId: external_exports.string().min(1).optional()
38782
38848
  });
38783
38849
  var mrrlinExecutionRunUpdateSchema = external_exports.object({
38784
- agentSeat: external_exports.enum(["codex", "claude"]).nullable().optional(),
38850
+ agentSeat: external_exports.enum(["codex", "claude", "agy"]).nullable().optional(),
38785
38851
  baseSha: external_exports.string().min(1).nullable().optional(),
38786
38852
  branch: external_exports.string().min(1).nullable().optional(),
38787
38853
  blockingReason: mrrlinRunBlockingReasonCodeSchema.nullable().optional(),
@@ -40355,8 +40421,33 @@ var ClaudeAgentHandle = class {
40355
40421
  }
40356
40422
  };
40357
40423
 
40424
+ // ../../packages/agent-client/dist/providers/agy/adapter.js
40425
+ var AgyProviderAdapter = class {
40426
+ id = "agy";
40427
+ capabilities() {
40428
+ return AGENT_CAPABILITIES.agy;
40429
+ }
40430
+ // Stub adapter: real process spawning and JSONL stdio streaming will be implemented in agy-stdio-streaming
40431
+ async acquireWarm() {
40432
+ return {
40433
+ startThread: () => Promise.resolve({ threadId: "mock-thread-id" }),
40434
+ resumeThread: () => Promise.resolve({ threadId: "mock-thread-id" }),
40435
+ startTurn: () => Promise.resolve({ turnId: "mock-turn-id" }),
40436
+ interruptTurn: () => Promise.resolve(),
40437
+ onEvent: () => () => {
40438
+ },
40439
+ onActivity: () => () => {
40440
+ },
40441
+ listModels: () => Promise.resolve([]),
40442
+ readRateLimits: () => Promise.resolve(null)
40443
+ };
40444
+ }
40445
+ releaseWarm() {
40446
+ }
40447
+ };
40448
+
40358
40449
  // ../../packages/agent-client/dist/registry.js
40359
- var KNOWN_PROVIDERS = { codex: true, claude: true };
40450
+ var KNOWN_PROVIDERS = { codex: true, claude: true, agy: true };
40360
40451
  var KNOWN_PROVIDER_IDS = Object.keys(KNOWN_PROVIDERS);
40361
40452
  function readProviderFromEnv(env) {
40362
40453
  const raw = env.MRRLIN_AGENT_PROVIDER;
@@ -40377,6 +40468,9 @@ function resolveProvider(env, persisted) {
40377
40468
  if (id === "claude") {
40378
40469
  return new ClaudeProviderAdapter();
40379
40470
  }
40471
+ if (id === "agy") {
40472
+ return new AgyProviderAdapter();
40473
+ }
40380
40474
  throw new Error(`not-yet-wired: ${id}`);
40381
40475
  }
40382
40476
 
@@ -40720,6 +40814,8 @@ async function mintResolvedSeat(provider, opts) {
40720
40814
  const providerId = provider.id;
40721
40815
  let strongModel;
40722
40816
  let weakModel;
40817
+ let pinRetired;
40818
+ let retiredPin;
40723
40819
  const strongEnvValue = process.env[providerId === "codex" ? CODEX_STRONG_MODEL_ENV : CLAUDE_STRONG_MODEL_ENV]?.trim();
40724
40820
  if (opts?.handle && capabilities.listsModels) {
40725
40821
  try {
@@ -40733,6 +40829,8 @@ async function mintResolvedSeat(provider, opts) {
40733
40829
  strongModel = picked;
40734
40830
  if (strongEnvValue) {
40735
40831
  logFallback(providerId, "strong", "live-default (env pin retired)", strongModel);
40832
+ pinRetired = true;
40833
+ retiredPin = strongEnvValue;
40736
40834
  }
40737
40835
  } else {
40738
40836
  throw new Error("empty model list");
@@ -40780,7 +40878,8 @@ async function mintResolvedSeat(provider, opts) {
40780
40878
  return {
40781
40879
  id: providerId,
40782
40880
  capabilities,
40783
- models: { strong: strongModel, weak: weakModel }
40881
+ models: { strong: strongModel, weak: weakModel },
40882
+ ...pinRetired ? { pinRetired: true, retiredPin } : {}
40784
40883
  };
40785
40884
  }
40786
40885
 
@@ -42846,7 +42945,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
42846
42945
  }
42847
42946
 
42848
42947
  // src/_generated/version.ts
42849
- var PKG_VERSION = "0.4.64";
42948
+ var PKG_VERSION = "0.4.66";
42850
42949
 
42851
42950
  // src/api-base-url-migrate.ts
42852
42951
  var import_node_fs5 = __toESM(require("node:fs"), 1);
@@ -46215,11 +46314,12 @@ async function runProviderReadinessCycle(deps) {
46215
46314
  try {
46216
46315
  const verify = deps.verify ?? verifyProviderReadiness;
46217
46316
  const runnerFor = deps.runnerFor ?? defaultRunnerFor;
46218
- const [codex, claude] = await Promise.all([
46317
+ const [codex, claude, agy] = await Promise.all([
46219
46318
  verify("codex", runnerFor("codex")),
46220
- verify("claude", runnerFor("claude"))
46319
+ verify("claude", runnerFor("claude")),
46320
+ verify("agy", runnerFor("agy"))
46221
46321
  ]);
46222
- await deps.push({ codex, claude });
46322
+ await deps.push({ codex, claude, agy });
46223
46323
  } catch (err) {
46224
46324
  deps.onError?.(err);
46225
46325
  }
@@ -46260,7 +46360,7 @@ function setSelectedProvider(value) {
46260
46360
  // src/execution-consumer.ts
46261
46361
  var import_node_child_process13 = require("node:child_process");
46262
46362
  var import_node_crypto7 = __toESM(require("node:crypto"), 1);
46263
- var import_node_path20 = __toESM(require("node:path"), 1);
46363
+ var import_node_path21 = __toESM(require("node:path"), 1);
46264
46364
  var import_node_util = require("node:util");
46265
46365
 
46266
46366
  // src/consensus/deliverable-gate-outcome.ts
@@ -47867,6 +47967,132 @@ function effortDisabled(env = process.env) {
47867
47967
  return (env.MRRLIN_EXEC_EFFORT_DISABLE ?? "").trim() === "1";
47868
47968
  }
47869
47969
 
47970
+ // src/operator-token.ts
47971
+ var import_node_fs13 = require("node:fs");
47972
+ var import_node_os10 = __toESM(require("node:os"), 1);
47973
+ var import_node_path20 = __toESM(require("node:path"), 1);
47974
+ function operatorDir() {
47975
+ const base = process.env.CODEX_HOME ? import_node_path20.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path20.default.join(import_node_os10.default.homedir(), ".mrrlin");
47976
+ return base;
47977
+ }
47978
+ function operatorTokenPath() {
47979
+ return import_node_path20.default.join(operatorDir(), "operator-token");
47980
+ }
47981
+ function readOperatorToken() {
47982
+ try {
47983
+ const token = (0, import_node_fs13.readFileSync)(operatorTokenPath(), "utf8").trim();
47984
+ return token.length > 0 ? token : null;
47985
+ } catch {
47986
+ return null;
47987
+ }
47988
+ }
47989
+ function persistOperatorToken(token) {
47990
+ const dir = operatorDir();
47991
+ (0, import_node_fs13.mkdirSync)(dir, { recursive: true, mode: 448 });
47992
+ (0, import_node_fs13.writeFileSync)(operatorTokenPath(), `${token.trim()}
47993
+ `, { encoding: "utf8", mode: 384 });
47994
+ }
47995
+ function agentCredentialPath() {
47996
+ return import_node_path20.default.join(operatorDir(), "agent-credential");
47997
+ }
47998
+ function persistAgentSecret(secret) {
47999
+ const dir = operatorDir();
48000
+ (0, import_node_fs13.mkdirSync)(dir, { recursive: true, mode: 448 });
48001
+ (0, import_node_fs13.writeFileSync)(agentCredentialPath(), `${secret.trim()}
48002
+ `, { encoding: "utf8", mode: 384 });
48003
+ }
48004
+ function readAgentSecret() {
48005
+ const fromEnv = process.env.MRRLIN_AGENT_SECRET?.trim();
48006
+ if (fromEnv) return fromEnv;
48007
+ try {
48008
+ const raw = (0, import_node_fs13.readFileSync)(agentCredentialPath(), "utf8").trim();
48009
+ return raw || void 0;
48010
+ } catch {
48011
+ return void 0;
48012
+ }
48013
+ }
48014
+
48015
+ // src/pin-retirement-notifier.ts
48016
+ var notifiedPins = /* @__PURE__ */ new Set();
48017
+ var inFlightPins = /* @__PURE__ */ new Set();
48018
+ function getDedupKey(providerId, pinnedModel) {
48019
+ return pinnedModel ? `${providerId}:${pinnedModel}` : providerId;
48020
+ }
48021
+ async function notifyPinRetirement(info, opts) {
48022
+ if (info.providerId === "claude") {
48023
+ return;
48024
+ }
48025
+ const dedupKey = getDedupKey(info.providerId, info.pinnedModel);
48026
+ if (notifiedPins.has(dedupKey) || inFlightPins.has(dedupKey)) {
48027
+ return;
48028
+ }
48029
+ inFlightPins.add(dedupKey);
48030
+ try {
48031
+ const apiBaseUrl = opts?.apiBaseUrl ?? process.env.MRRLIN_API_BASE_URL ?? "http://127.0.0.1:8787";
48032
+ const projectSlug = info.projectSlug ?? process.env.MRRLIN_REPORT_PROJECT_SLUG?.trim() ?? "mrrlin";
48033
+ const token = opts?.token !== void 0 ? opts.token : process.env.MRRLIN_API_TOKEN?.trim() || readOperatorToken();
48034
+ const fetchImpl = opts?.fetch ?? globalThis.fetch;
48035
+ const endpoint = `${apiBaseUrl.replace(/\/+$/, "")}/projects/${encodeURIComponent(
48036
+ projectSlug
48037
+ )}/tasks`;
48038
+ const headers = {
48039
+ "content-type": "application/json",
48040
+ "x-mrrlin-actor": "mrrlin-bridge",
48041
+ "x-mrrlin-director-session-id": "pin-retirement-signal"
48042
+ };
48043
+ if (token) {
48044
+ headers.authorization = `Bearer ${token}`;
48045
+ }
48046
+ const body = {
48047
+ title: `[Bug] Retired strong-model pin: ${info.providerId} (${info.pinnedModel})`,
48048
+ type: "bug",
48049
+ category: "bug",
48050
+ subcategory: "reported",
48051
+ domain: "code",
48052
+ impact: "medium",
48053
+ notes: `The pinned strong model "${info.pinnedModel}" for provider "${info.providerId}" was not found in the provider's live model list (retired by provider). Falling back to live default model "${info.fallbackModel}". Please update the operator pin in ~/.mrrlin/ecosystem.config.cjs or the corresponding environment variable (MRRLIN_${info.providerId.toUpperCase()}_STRONG_MODEL).`,
48054
+ operatorSeedRequest: `The pinned strong model "${info.pinnedModel}" for provider "${info.providerId}" has been retired. Fallback in use: "${info.fallbackModel}". Update the strong model pin.`,
48055
+ autonomyLevel: "human_review",
48056
+ autonomyReason: "Needs human review before automation."
48057
+ };
48058
+ const response = await fetchImpl(endpoint, {
48059
+ method: "POST",
48060
+ headers,
48061
+ body: JSON.stringify(body)
48062
+ });
48063
+ if (response.ok) {
48064
+ notifiedPins.add(dedupKey);
48065
+ } else {
48066
+ console.warn(
48067
+ `[pin-retirement-notifier] received non-2xx status (${response.status}) from ${endpoint}`
48068
+ );
48069
+ }
48070
+ } catch (err) {
48071
+ console.warn(
48072
+ `[pin-retirement-notifier] failed to report retirement for provider "${info.providerId}":`,
48073
+ err
48074
+ );
48075
+ } finally {
48076
+ inFlightPins.delete(dedupKey);
48077
+ }
48078
+ }
48079
+ async function notifyPinRetirementIfRetired(seat, opts) {
48080
+ if (!seat.pinRetired) {
48081
+ return;
48082
+ }
48083
+ const pinnedModel = seat.retiredPin ?? (seat.id === "codex" ? process.env.MRRLIN_CODEX_STRONG_MODEL : seat.id === "claude" ? process.env.MRRLIN_CLAUDE_STRONG_MODEL : void 0) ?? "unknown";
48084
+ const fallbackModel = seat.models?.strong ?? "unknown";
48085
+ await notifyPinRetirement(
48086
+ {
48087
+ providerId: seat.id,
48088
+ pinnedModel,
48089
+ fallbackModel,
48090
+ projectSlug: opts?.projectSlug
48091
+ },
48092
+ opts
48093
+ );
48094
+ }
48095
+
47870
48096
  // src/execution-consumer.ts
47871
48097
  var DEFAULT_STALE_SECONDS = 300;
47872
48098
  var DEFAULT_MAX_LEASE_RECLAIMS = 3;
@@ -48594,6 +48820,7 @@ async function driveRun(deps, projectSlug, runId) {
48594
48820
  resolvedProviderId = claimed.agentSeat;
48595
48821
  } else {
48596
48822
  const seat = await mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()));
48823
+ void notifyPinRetirementIfRetired(seat, { projectSlug });
48597
48824
  resolvedProviderId = seat.id;
48598
48825
  await deps.client.updateExecutionRun(projectSlug, runId, { agentSeat: seat.id }).catch((err) => {
48599
48826
  console.warn(
@@ -49861,8 +50088,8 @@ async function runBackstopSweep(deps, drive = (slug, id) => driveRun(deps, slug,
49861
50088
  function isRunRecoverableByThisBridge(run3, worktreeRoot) {
49862
50089
  if (!worktreeRoot) return true;
49863
50090
  if (!run3.worktreeId) return false;
49864
- const relative = import_node_path20.default.relative(import_node_path20.default.resolve(worktreeRoot), import_node_path20.default.resolve(run3.worktreeId));
49865
- return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path20.default.isAbsolute(relative);
50091
+ const relative = import_node_path21.default.relative(import_node_path21.default.resolve(worktreeRoot), import_node_path21.default.resolve(run3.worktreeId));
50092
+ return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path21.default.isAbsolute(relative);
49866
50093
  }
49867
50094
  async function deployGateHandoff(deps, projectSlug, task, runId, reason, leaseId) {
49868
50095
  await deps.client.updateExecutionRun(projectSlug, runId, { status: "failed", finishedAt: (/* @__PURE__ */ new Date()).toISOString(), leaseId: leaseId ?? void 0 }).catch(() => {
@@ -49911,9 +50138,9 @@ function getAsyncToolDescriptor(toolName) {
49911
50138
  }
49912
50139
 
49913
50140
  // src/bridge-log.ts
49914
- var import_node_fs13 = require("node:fs");
50141
+ var import_node_fs14 = require("node:fs");
49915
50142
  var import_promises7 = require("node:fs/promises");
49916
- var import_node_path21 = require("node:path");
50143
+ var import_node_path22 = require("node:path");
49917
50144
 
49918
50145
  // src/redact.ts
49919
50146
  var REDACTED = "[REDACTED]";
@@ -50189,14 +50416,14 @@ function resolvePromptsEnabled(env = process.env) {
50189
50416
  }
50190
50417
  function createBridgeLogger(stateDir, env = process.env) {
50191
50418
  if (!resolveBridgeLogEnabled(env)) return NOOP_LOGGER;
50192
- const logsDir = (0, import_node_path21.join)(stateDir, "logs");
50419
+ const logsDir = (0, import_node_path22.join)(stateDir, "logs");
50193
50420
  try {
50194
- (0, import_node_fs13.mkdirSync)(logsDir, { recursive: true });
50421
+ (0, import_node_fs14.mkdirSync)(logsDir, { recursive: true });
50195
50422
  } catch {
50196
50423
  return NOOP_LOGGER;
50197
50424
  }
50198
50425
  const includePrompts = resolvePromptsEnabled(env);
50199
- const fileFor = () => (0, import_node_path21.join)(logsDir, `bridge-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.jsonl`);
50426
+ const fileFor = () => (0, import_node_path22.join)(logsDir, `bridge-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.jsonl`);
50200
50427
  const MAX_TRACKED_SESSIONS = 64;
50201
50428
  const contextSlugBySession = /* @__PURE__ */ new Map();
50202
50429
  const rememberContextSlug = (sessionId, payload) => {
@@ -50237,10 +50464,10 @@ function createBridgeLogger(stateDir, env = process.env) {
50237
50464
  return { isGap, isNewTurn };
50238
50465
  };
50239
50466
  const gainDay = (sessionId) => {
50240
- const sessionsPath = (0, import_node_path21.join)(logsDir, ".sessions.json");
50467
+ const sessionsPath = (0, import_node_path22.join)(logsDir, ".sessions.json");
50241
50468
  let sessionsObj = {};
50242
50469
  try {
50243
- const parsed = JSON.parse((0, import_node_fs13.readFileSync)(sessionsPath, "utf8"));
50470
+ const parsed = JSON.parse((0, import_node_fs14.readFileSync)(sessionsPath, "utf8"));
50244
50471
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) sessionsObj = parsed;
50245
50472
  } catch {
50246
50473
  sessionsObj = {};
@@ -50250,8 +50477,8 @@ function createBridgeLogger(stateDir, env = process.env) {
50250
50477
  if (idsToday.includes(sessionId)) return;
50251
50478
  sessionsObj[day] = [...idsToday, sessionId];
50252
50479
  const tmpPath = `${sessionsPath}.tmp`;
50253
- (0, import_node_fs13.writeFileSync)(tmpPath, JSON.stringify(sessionsObj));
50254
- (0, import_node_fs13.renameSync)(tmpPath, sessionsPath);
50480
+ (0, import_node_fs14.writeFileSync)(tmpPath, JSON.stringify(sessionsObj));
50481
+ (0, import_node_fs14.renameSync)(tmpPath, sessionsPath);
50255
50482
  };
50256
50483
  const write = (dir, rec) => {
50257
50484
  try {
@@ -50342,7 +50569,7 @@ function createBridgeLogger(stateDir, env = process.env) {
50342
50569
  ...recordingObligationUnresolved ? { recordingObligationUnresolved } : {},
50343
50570
  ...recordingObligationMultiResolve ? { recordingObligationMultiResolve } : {}
50344
50571
  }) + "\n";
50345
- (0, import_node_fs13.appendFileSync)(fileFor(), line);
50572
+ (0, import_node_fs14.appendFileSync)(fileFor(), line);
50346
50573
  if (rec.sessionId !== null) gainDay(rec.sessionId);
50347
50574
  } catch {
50348
50575
  }
@@ -50355,7 +50582,7 @@ function createBridgeLogger(stateDir, env = process.env) {
50355
50582
  };
50356
50583
  }
50357
50584
  async function findSessionDays(stateDir, sessionId) {
50358
- const sessionsPath = (0, import_node_path21.join)(stateDir, "logs", ".sessions.json");
50585
+ const sessionsPath = (0, import_node_path22.join)(stateDir, "logs", ".sessions.json");
50359
50586
  let sessionsObj;
50360
50587
  try {
50361
50588
  const parsed = JSON.parse(await (0, import_promises7.readFile)(sessionsPath, "utf8"));
@@ -50537,12 +50764,12 @@ async function runAsyncBackstopSweep(deps, drive = (slug, jobId) => driveAsyncJo
50537
50764
  }
50538
50765
 
50539
50766
  // src/state-dir.ts
50540
- var import_node_os10 = __toESM(require("node:os"), 1);
50541
- var import_node_path22 = __toESM(require("node:path"), 1);
50767
+ var import_node_os11 = __toESM(require("node:os"), 1);
50768
+ var import_node_path23 = __toESM(require("node:path"), 1);
50542
50769
  function resolveStateDir(env = process.env) {
50543
50770
  const codexHome = env.CODEX_HOME;
50544
- if (codexHome) return import_node_path22.default.join(codexHome, "mrrlin", "director-bridge");
50545
- return import_node_path22.default.join(import_node_os10.default.homedir(), ".mrrlin", "director-bridge");
50771
+ if (codexHome) return import_node_path23.default.join(codexHome, "mrrlin", "director-bridge");
50772
+ return import_node_path23.default.join(import_node_os11.default.homedir(), ".mrrlin", "director-bridge");
50546
50773
  }
50547
50774
 
50548
50775
  // src/consensus/deliverable-gate.ts
@@ -50797,51 +51024,6 @@ function agentIdleMs(provider) {
50797
51024
  return seconds * 1e3;
50798
51025
  }
50799
51026
 
50800
- // src/operator-token.ts
50801
- var import_node_fs14 = require("node:fs");
50802
- var import_node_os11 = __toESM(require("node:os"), 1);
50803
- var import_node_path23 = __toESM(require("node:path"), 1);
50804
- function operatorDir() {
50805
- const base = process.env.CODEX_HOME ? import_node_path23.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path23.default.join(import_node_os11.default.homedir(), ".mrrlin");
50806
- return base;
50807
- }
50808
- function operatorTokenPath() {
50809
- return import_node_path23.default.join(operatorDir(), "operator-token");
50810
- }
50811
- function readOperatorToken() {
50812
- try {
50813
- const token = (0, import_node_fs14.readFileSync)(operatorTokenPath(), "utf8").trim();
50814
- return token.length > 0 ? token : null;
50815
- } catch {
50816
- return null;
50817
- }
50818
- }
50819
- function persistOperatorToken(token) {
50820
- const dir = operatorDir();
50821
- (0, import_node_fs14.mkdirSync)(dir, { recursive: true, mode: 448 });
50822
- (0, import_node_fs14.writeFileSync)(operatorTokenPath(), `${token.trim()}
50823
- `, { encoding: "utf8", mode: 384 });
50824
- }
50825
- function agentCredentialPath() {
50826
- return import_node_path23.default.join(operatorDir(), "agent-credential");
50827
- }
50828
- function persistAgentSecret(secret) {
50829
- const dir = operatorDir();
50830
- (0, import_node_fs14.mkdirSync)(dir, { recursive: true, mode: 448 });
50831
- (0, import_node_fs14.writeFileSync)(agentCredentialPath(), `${secret.trim()}
50832
- `, { encoding: "utf8", mode: 384 });
50833
- }
50834
- function readAgentSecret() {
50835
- const fromEnv = process.env.MRRLIN_AGENT_SECRET?.trim();
50836
- if (fromEnv) return fromEnv;
50837
- try {
50838
- const raw = (0, import_node_fs14.readFileSync)(agentCredentialPath(), "utf8").trim();
50839
- return raw || void 0;
50840
- } catch {
50841
- return void 0;
50842
- }
50843
- }
50844
-
50845
51027
  // src/thread-index.ts
50846
51028
  var import_node_fs15 = require("node:fs");
50847
51029
  var import_node_path24 = __toESM(require("node:path"), 1);
@@ -57007,6 +57189,7 @@ function createBridgeMessageHandler(deps) {
57007
57189
  return;
57008
57190
  }
57009
57191
  const compactionSeat = await mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()));
57192
+ void notifyPinRetirementIfRetired(compactionSeat);
57010
57193
  const result = await deps.runCompaction({
57011
57194
  history,
57012
57195
  provider: compactionSeat.id,
@@ -57378,6 +57561,7 @@ function createBridgeMessageHandler(deps) {
57378
57561
  }
57379
57562
  pendingTurnSessions.add(directorSessionId);
57380
57563
  const turnSeat = await mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()));
57564
+ void notifyPinRetirementIfRetired(turnSeat);
57381
57565
  const turnProviderCapabilities = turnSeat.capabilities;
57382
57566
  const codexClient = await deps.acquireCodex(turnSeat.id);
57383
57567
  let thread = deps.threads.get(directorSessionId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrrlin-dev/mcp",
3
- "version": "0.4.64",
3
+ "version": "0.4.66",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mrrlin-mcp": "dist/bin.cjs"
@@ -25,8 +25,8 @@
25
25
  "@mrrlin/agent-client": "0.0.0",
26
26
  "@mrrlin/director-e2e": "0.0.0",
27
27
  "@mrrlin/tsconfig": "0.0.0",
28
- "@mrrlin/schemas": "0.0.0",
29
- "@mrrlin/wiki": "0.0.0"
28
+ "@mrrlin/wiki": "0.0.0",
29
+ "@mrrlin/schemas": "0.0.0"
30
30
  },
31
31
  "dependencies": {
32
32
  "@iarna/toml": "^2.2.5",