@antonbabenko/deliberation-mcp 3.6.0 → 3.6.1

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 +77 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -231,18 +231,71 @@ var require_provider = __commonJS({
231
231
  var VERDICT_RE = /\bverdict\b[^A-Za-z0-9]*\b(APPROVE|REJECT|REQUEST[_\s]CHANGES)\b/i;
232
232
  var BULLET_RE = /^([-*+•]|`?\[)/;
233
233
  var BRACKET_CAT_RE = /\[\s*([A-Za-z_]+)\s*\]/g;
234
+ var SENTINEL_RE = /^[#>*_`\s]*verdict\s*[:=]\s*[*_`\s]*(APPROVE|REJECT|REQUEST[_\s]CHANGES)\b/i;
235
+ var VERDICT_WORD_RE = /^[#>*_`\s]*verdict[*_`:\s]*$/i;
236
+ var TOKEN_LINE_RE = /^(APPROVE|REJECT|REQUEST[_\s]CHANGES)$/i;
237
+ var MD_EMPHASIS = /[*_`~]/g;
238
+ var FENCE_RE = /^\s*(```|~~~)/;
239
+ var ARTIFACT_RE = /^[*_`~\s:.\-]*$/;
240
+ var STRIP_LEAD = /^[*_`~\s:.\-]+/;
241
+ var STRIP_TRAIL = /[*_`~\s]+$/;
242
+ var HEADING_RE = /^#{1,6}\s/;
243
+ function normVerdict(tok) {
244
+ return tok.replace(/\s+/g, "_").toUpperCase();
245
+ }
234
246
  function parseReview(text) {
235
247
  const raw = safeString(text);
236
- const lines = raw.split(/\r?\n/);
237
- let verdict = null;
238
- const criticalIssues = [];
239
- for (const line of lines) {
240
- if (verdict === null) {
241
- const vm = line.match(VERDICT_RE);
242
- if (vm) verdict = /** @type {ParsedReview["verdict"]} */
243
- vm[1].replace(/\s+/g, "_").toUpperCase();
248
+ const lines = [];
249
+ let inFence = false;
250
+ for (const ln of raw.split(/\r?\n/)) {
251
+ if (FENCE_RE.test(ln)) {
252
+ inFence = !inFence;
253
+ continue;
244
254
  }
245
- const trimmed = line.trim();
255
+ if (!inFence) lines.push(ln);
256
+ }
257
+ return { verdict: resolveVerdict(lines), criticalIssues: resolveIssues(lines) };
258
+ }
259
+ function resolveVerdict(lines) {
260
+ for (const ln of lines) {
261
+ const m = ln.match(SENTINEL_RE);
262
+ if (m) return (
263
+ /** @type {any} */
264
+ normVerdict(m[1])
265
+ );
266
+ }
267
+ for (const ln of lines) {
268
+ const m = ln.match(VERDICT_RE);
269
+ if (m) return (
270
+ /** @type {any} */
271
+ normVerdict(m[1])
272
+ );
273
+ }
274
+ for (let i = 0; i < lines.length; i++) {
275
+ if (!VERDICT_WORD_RE.test(lines[i].trim())) continue;
276
+ for (let j = i + 1; j < lines.length && j <= i + 3; j++) {
277
+ const t = lines[j].replace(MD_EMPHASIS, "").trim();
278
+ if (!t) continue;
279
+ if (TOKEN_LINE_RE.test(t)) return (
280
+ /** @type {any} */
281
+ normVerdict(t)
282
+ );
283
+ break;
284
+ }
285
+ }
286
+ for (const ln of lines) {
287
+ const t = ln.replace(MD_EMPHASIS, "").trim();
288
+ if (TOKEN_LINE_RE.test(t)) return (
289
+ /** @type {any} */
290
+ normVerdict(t)
291
+ );
292
+ }
293
+ return null;
294
+ }
295
+ function resolveIssues(lines) {
296
+ const out = [];
297
+ for (let i = 0; i < lines.length; i++) {
298
+ const trimmed = lines[i].trim();
246
299
  if (!BULLET_RE.test(trimmed)) continue;
247
300
  let chosen = null;
248
301
  for (const mm of trimmed.matchAll(BRACKET_CAT_RE)) {
@@ -258,10 +311,20 @@ var require_provider = __commonJS({
258
311
  /** @type {ReviewCriticalIssue["category"]} */
259
312
  REVIEW_CATEGORIES.includes(cat) ? cat : REVIEW_FALLBACK_CATEGORY
260
313
  );
261
- const description = trimmed.slice((chosen.index || 0) + chosen[0].length).replace(/^[`\s:.\-]+/, "").trim();
262
- if (description) criticalIssues.push({ category, description });
314
+ let description = trimmed.slice(chosen.index + chosen[0].length).replace(STRIP_LEAD, "").replace(STRIP_TRAIL, "").trim();
315
+ if (!description || ARTIFACT_RE.test(description)) {
316
+ for (let j = i + 1; j < lines.length; j++) {
317
+ const nt = lines[j].trim();
318
+ if (!nt) break;
319
+ if (BULLET_RE.test(nt) || HEADING_RE.test(nt)) break;
320
+ if (SENTINEL_RE.test(nt) || VERDICT_WORD_RE.test(nt) || VERDICT_RE.test(nt)) break;
321
+ description = nt.replace(STRIP_LEAD, "").replace(STRIP_TRAIL, "").trim();
322
+ break;
323
+ }
324
+ }
325
+ if (description && !ARTIFACT_RE.test(description)) out.push({ category, description });
263
326
  }
264
- return { verdict, criticalIssues };
327
+ return out;
265
328
  }
266
329
  module2.exports = {
267
330
  toErrorResult,
@@ -324,12 +387,12 @@ ${state.currentPlan}`
324
387
  const peerPrompt = [
325
388
  body,
326
389
  "Review the plan for correctness, security, scope, ambiguity, performance, and ops gaps.",
327
- "End with: **Verdict**: APPROVE | REQUEST_CHANGES | REJECT, then categorized critical issues."
390
+ "End with a line by itself in exactly this form (no markdown, token on the SAME line): VERDICT: APPROVE (or VERDICT: REQUEST_CHANGES, or VERDICT: REJECT). Then list any critical issues, one per line as: - [category] description where category is one of security, correctness, scope, ambiguity, performance, ops."
328
391
  ].join("\n\n");
329
392
  const blindPrompt = [
330
393
  body,
331
394
  "Give your own independent verdict BEFORE seeing peer opinions.",
332
- "End with: **Verdict**: APPROVE | REQUEST_CHANGES | REJECT, then categorized critical issues."
395
+ "End with a line by itself in exactly this form (no markdown, token on the SAME line): VERDICT: APPROVE (or VERDICT: REQUEST_CHANGES, or VERDICT: REJECT). Then list any critical issues, one per line as: - [category] description where category is one of security, correctness, scope, ambiguity, performance, ops."
333
396
  ].join("\n\n");
334
397
  return { peerPrompt, blindPrompt };
335
398
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antonbabenko/deliberation-mcp",
3
- "version": "3.6.0",
3
+ "version": "3.6.1",
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" },