@antonbabenko/deliberation-mcp 3.6.1 → 3.6.2

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/index.js +25 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -283,9 +283,9 @@ var require_provider = __commonJS({
283
283
  break;
284
284
  }
285
285
  }
286
- for (const ln of lines) {
287
- const t = ln.replace(MD_EMPHASIS, "").trim();
288
- if (TOKEN_LINE_RE.test(t)) return (
286
+ const nonEmpty = lines.map((l) => l.replace(MD_EMPHASIS, "").trim()).filter((t) => t !== "");
287
+ for (const t of [nonEmpty[0], nonEmpty[nonEmpty.length - 1]]) {
288
+ if (t && TOKEN_LINE_RE.test(t)) return (
289
289
  /** @type {any} */
290
290
  normVerdict(t)
291
291
  );
@@ -1118,7 +1118,7 @@ var require_sessions = __commonJS({
1118
1118
  var DEFAULT_MAX_AGE_DAYS = 30;
1119
1119
  function scrubSecrets(text) {
1120
1120
  if (typeof text !== "string" || text.length === 0) return text;
1121
- return text.replace(/\bsk-or-[A-Za-z0-9_-]{20,}/g, "[REDACTED]").replace(/\bsk-[A-Za-z0-9_-]{20,}/g, "[REDACTED]").replace(/\bxai-[A-Za-z0-9_-]{20,}/g, "[REDACTED]").replace(/\bgh[pousr]_[A-Za-z0-9]{20,}/g, "[REDACTED]").replace(/\bAKIA[0-9A-Z]{16}\b/g, "[REDACTED]").replace(/\bAIza[0-9A-Za-z_-]{35,}/g, "[REDACTED]").replace(/\bBearer\s+[A-Za-z0-9._~+/-]{20,}={0,2}/g, "Bearer [REDACTED]");
1121
+ return text.replace(/\bsk-or-[A-Za-z0-9_-]{20,}/g, "[REDACTED]").replace(/\bsk-[A-Za-z0-9_-]{20,}/g, "[REDACTED]").replace(/\bxai-[A-Za-z0-9_-]{20,}/g, "[REDACTED]").replace(/\bgh[pousr]_[A-Za-z0-9]{20,}/g, "[REDACTED]").replace(/\bAKIA[0-9A-Z]{16}\b/g, "[REDACTED]").replace(/\bAIza[0-9A-Za-z_-]{35,}/g, "[REDACTED]").replace(/\b([a-z][a-z0-9+.-]*:\/\/[^\s:@/]+:)[^\s@/]{6,}@/gi, "$1[REDACTED]@").replace(/\bToken\s+[A-Za-z0-9._~+/-]{20,}={0,2}/g, "Token [REDACTED]").replace(/\bBearer\s+[A-Za-z0-9._~+/-]{20,}={0,2}/g, "Bearer [REDACTED]");
1122
1122
  }
1123
1123
  function capText(text) {
1124
1124
  if (typeof text !== "string") return text;
@@ -2202,6 +2202,7 @@ var require_gemini = __commonJS({
2202
2202
  var DEFAULT_RECOVERY_GRACE_MS = 12e4;
2203
2203
  var MAX_MS = 6e5;
2204
2204
  var VALID_SANDBOX_VALUES = /* @__PURE__ */ new Set(["read-only", "workspace-write"]);
2205
+ var THREAD_ID_RE = /^[A-Za-z0-9_][A-Za-z0-9_-]{0,127}$/;
2205
2206
  function goDuration(ms) {
2206
2207
  return Math.ceil(ms / 1e3) + "s";
2207
2208
  }
@@ -2225,10 +2226,14 @@ ${prompt}`;
2225
2226
  return args;
2226
2227
  }
2227
2228
  var ADVISORY_ENV_SCRUB = ["GITHUB_TOKEN", "GH_TOKEN", "GIT_ASKPASS", "SSH_AUTH_SOCK"];
2229
+ var CREDENTIAL_NAME_RE = /(?:^|_)(?:KEY|TOKEN|SECRET|SECRETS|PASSWORD|PASSWD|CREDENTIAL|CREDENTIALS)$|API_KEY|ACCESS_KEY|SESSION_TOKEN|PRIVATE_KEY/i;
2228
2230
  function advisoryEnv(env) {
2229
2231
  const out = { ...env };
2230
2232
  delete out.DELIBERATION_DISABLE_OS_SANDBOX;
2231
2233
  for (const k of ADVISORY_ENV_SCRUB) delete out[k];
2234
+ for (const k of Object.keys(out)) {
2235
+ if (CREDENTIAL_NAME_RE.test(k)) delete out[k];
2236
+ }
2232
2237
  return out;
2233
2238
  }
2234
2239
  function seatbeltLiteral(p) {
@@ -2349,7 +2354,8 @@ ${prompt}`;
2349
2354
  real = fs.realpathSync(resolved);
2350
2355
  } catch (_) {
2351
2356
  }
2352
- return map[real] ?? map[resolved] ?? map[cwd] ?? null;
2357
+ const candidate = map[real] ?? map[resolved] ?? map[cwd] ?? null;
2358
+ return typeof candidate === "string" && THREAD_ID_RE.test(candidate) ? candidate : null;
2353
2359
  } catch (_) {
2354
2360
  return null;
2355
2361
  }
@@ -2674,8 +2680,8 @@ ${prompt}`;
2674
2680
  return;
2675
2681
  }
2676
2682
  const threadId2 = args.threadId.trim();
2677
- if (threadId2 === "" || threadId2 === "latest" || threadId2 === "unknown") {
2678
- if (shouldRespond) sendError(id, -32602, "Invalid params: 'threadId' must be an explicit conversation id, not '" + threadId2 + "'");
2683
+ if (!THREAD_ID_RE.test(threadId2) || threadId2 === "latest" || threadId2 === "unknown") {
2684
+ if (shouldRespond) sendError(id, -32602, "Invalid params: 'threadId' must be an explicit conversation id (alphanumeric/underscore start, then [A-Za-z0-9_-], 1..128 chars)");
2679
2685
  return;
2680
2686
  }
2681
2687
  if (!isNonEmptyString(args.prompt)) {
@@ -2772,6 +2778,7 @@ ${prompt}`;
2772
2778
  module2.exports.READ_ONLY_GUARD = READ_ONLY_GUARD;
2773
2779
  module2.exports.applyReadOnlyGuard = applyReadOnlyGuard;
2774
2780
  module2.exports.advisoryEnv = advisoryEnv;
2781
+ module2.exports.THREAD_ID_RE = THREAD_ID_RE;
2775
2782
  module2.exports.buildSeatbeltProfile = buildSeatbeltProfile;
2776
2783
  module2.exports.buildSpawnCommand = buildSpawnCommand;
2777
2784
  module2.exports.diffGitState = diffGitState;
@@ -2806,7 +2813,7 @@ var require_lock = __commonJS({
2806
2813
  try {
2807
2814
  fs.mkdirSync(lockDir);
2808
2815
  const markerPath = path.join(lockDir, markerName);
2809
- fs.writeFileSync(markerPath, JSON.stringify({ pid: process.pid, token, t: Date.now() }));
2816
+ fs.writeFileSync(markerPath, JSON.stringify({ pid: process.pid, token, t: Date.now() }), { mode: 384 });
2810
2817
  return { lockDir, markerPath, token };
2811
2818
  } catch (e) {
2812
2819
  if (e.code !== "EEXIST") throw e;
@@ -2900,7 +2907,7 @@ var require_cache = __commonJS({
2900
2907
  function writeCache(file, data) {
2901
2908
  mkdirSync(path.dirname(file), { recursive: true });
2902
2909
  const tmp = `${file}.tmp.${process.pid}.${Date.now()}`;
2903
- writeFileSync(tmp, JSON.stringify(data));
2910
+ writeFileSync(tmp, JSON.stringify(data), { mode: 384 });
2904
2911
  renameSync(tmp, file);
2905
2912
  }
2906
2913
  var _inflight = /* @__PURE__ */ new Map();
@@ -3071,6 +3078,8 @@ var require_glob = __commonJS({
3071
3078
  if (!matches(includeRes, relPosix)) continue;
3072
3079
  files.push({ rel: relPosix, abs: realTarget, size: st.size });
3073
3080
  totalBytes += st.size;
3081
+ if (files.length > maxFiles) throw new Error(`directory expansion exceeded maxFiles=${maxFiles}. Narrow include or raise the limit.`);
3082
+ if (totalBytes > maxBytes) throw new Error(`directory expansion exceeded maxBytes=${maxBytes} bytes. Narrow include or raise the limit.`);
3074
3083
  } else if (ent.isDirectory()) {
3075
3084
  if (matches(excludeRes, relPosix) || matches(excludeRes, relPosix + "/**")) continue;
3076
3085
  descend(absChild, relPosix);
@@ -3085,6 +3094,8 @@ var require_glob = __commonJS({
3085
3094
  }
3086
3095
  files.push({ rel: relPosix, abs: absChild, size: st.size });
3087
3096
  totalBytes += st.size;
3097
+ if (files.length > maxFiles) throw new Error(`directory expansion exceeded maxFiles=${maxFiles}. Narrow include or raise the limit.`);
3098
+ if (totalBytes > maxBytes) throw new Error(`directory expansion exceeded maxBytes=${maxBytes} bytes. Narrow include or raise the limit.`);
3088
3099
  }
3089
3100
  }
3090
3101
  }
@@ -3409,7 +3420,8 @@ ${ref.inline_text}` });
3409
3420
  res = await f(`${base}/files`, {
3410
3421
  method: "POST",
3411
3422
  headers: { "Authorization": `Bearer ${apiKey}` },
3412
- body: form
3423
+ body: form,
3424
+ redirect: "error"
3413
3425
  });
3414
3426
  } catch (err) {
3415
3427
  const e = new Error(`File upload network error: ${err && err.message || err}`);
@@ -3599,7 +3611,8 @@ ${ref.inline_text}` });
3599
3611
  "Authorization": `Bearer ${apiKey}`
3600
3612
  },
3601
3613
  body: JSON.stringify(payload),
3602
- signal: controller.signal
3614
+ signal: controller.signal,
3615
+ redirect: "error"
3603
3616
  });
3604
3617
  } catch (err) {
3605
3618
  const name = err && err.name;
@@ -4326,7 +4339,7 @@ var require_openrouter = __commonJS({
4326
4339
  const timer = setTimeout(() => controller.abort(), t);
4327
4340
  let res;
4328
4341
  try {
4329
- res = await f(url, { method: "POST", headers, body: JSON.stringify(payload), signal: controller.signal });
4342
+ res = await f(url, { method: "POST", headers, body: JSON.stringify(payload), signal: controller.signal, redirect: "error" });
4330
4343
  } catch (err) {
4331
4344
  const msg = String(err && err.message || err);
4332
4345
  if (err && err.name === "AbortError" || /abort/i.test(msg)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antonbabenko/deliberation-mcp",
3
- "version": "3.6.1",
3
+ "version": "3.6.2",
4
4
  "description": "Deliberation for Claude Code and any MCP host - GPT, Gemini, Grok, and OpenRouter expert subagents.",
5
5
  "mcpName": "io.github.antonbabenko/deliberation",
6
6
  "repository": { "type": "git", "url": "git+https://github.com/antonbabenko/deliberation.git", "directory": "server/mcp" },