evrex-mcp 0.2.0 → 0.4.0

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 +17 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -143,7 +143,7 @@ async function synthesizeAnswer(question, evidence, client2, options = {}) {
143
143
 
144
144
  // ../../packages/llm-core/src/providers.ts
145
145
  var DEFAULT_MODELS = {
146
- anthropic: "claude-opus-5",
146
+ anthropic: "claude-haiku-4-5",
147
147
  openai: "gpt-4o",
148
148
  google: "gemini-2.0-flash"
149
149
  };
@@ -433,6 +433,12 @@ function toRepoRelative(filePath, root) {
433
433
  }
434
434
  return filePath;
435
435
  }
436
+ function sameFileRef(a, b) {
437
+ if (a === b) return true;
438
+ if (a.endsWith(`/${b}`)) return true;
439
+ if (b.endsWith(`/${a}`)) return true;
440
+ return false;
441
+ }
436
442
  async function resolveRepos() {
437
443
  const override = process.env.EVREX_REPO_PATH;
438
444
  if (override) {
@@ -458,9 +464,14 @@ async function evrexWhy(filePath, question) {
458
464
  const sessions = (await Promise.all(sessionIds.map((id) => evrexApi.session(id)))).filter(
459
465
  (s) => s !== null
460
466
  );
461
- const rejected = sessions.flatMap((s) => s.rejected).slice(0, MAX_ITEMS);
462
- const constraints = sessions.flatMap((s) => s.constraints).slice(0, MAX_ITEMS);
463
- const decisions = sessions.flatMap((s) => s.decisions).slice(0, MAX_ITEMS);
467
+ const target = isAbsolute(filePath) ? toRepoRelative(filePath, root) : filePath;
468
+ const aboutTarget = (item) => (item.files ?? []).some((f) => sameFileRef(toRepoRelative(f, root), target));
469
+ const byRelevance = (items) => [...items].sort(
470
+ (a, b) => Number(aboutTarget(b)) - Number(aboutTarget(a))
471
+ );
472
+ const rejected = byRelevance(sessions.flatMap((s) => s.rejected)).slice(0, MAX_ITEMS);
473
+ const constraints = byRelevance(sessions.flatMap((s) => s.constraints)).slice(0, MAX_ITEMS);
474
+ const decisions = byRelevance(sessions.flatMap((s) => s.decisions)).slice(0, MAX_ITEMS);
464
475
  const parts = [];
465
476
  const heuristic = sessions.some((s) => s.insightsSource === "heuristic");
466
477
  if (rejected.length > 0) {
@@ -479,6 +490,7 @@ async function evrexWhy(filePath, question) {
479
490
  "NOTE: the blocks above were extracted by cue-phrase matching, not by a model reading the conversation \u2014 they may be incomplete or miss context."
480
491
  );
481
492
  }
493
+ const hasBlocks = rejected.length > 0 || constraints.length > 0 || decisions.length > 0;
482
494
  if (synthesisEnabled()) {
483
495
  const answer = await synthesize(text, evidence);
484
496
  parts.push(
@@ -486,7 +498,7 @@ async function evrexWhy(filePath, question) {
486
498
  );
487
499
  } else {
488
500
  parts.push(
489
- "HOW TO USE THIS: treat the constraints and rejected approaches above as binding \u2014 they are what this team already decided, not suggestions. Do not re-propose a rejected approach unless you have new information that specifically invalidates the stated reason, and say so if you do. Answer the user from the evidence below; if it does not actually cover their question, say that rather than inferring."
501
+ hasBlocks ? "HOW TO USE THIS: treat the constraints and rejected approaches above as binding \u2014 they are what this team already decided, not suggestions. Do not re-propose a rejected approach unless you have new information that specifically invalidates the stated reason, and say so if you do. Answer the user from the evidence below; if it does not actually cover their question, say that rather than inferring." : "HOW TO USE THIS: no decisions, constraints or rejected approaches were extracted for this file \u2014 only the raw evidence below. Treat it as history to read, not as settled policy, and say so if it does not cover the question."
490
502
  );
491
503
  }
492
504
  const evidenceLines = evidence.slice(0, MAX_ITEMS).map((e) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evrex-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "MCP server that gives coding agents the recorded reasoning behind a repo: prior decisions, hard constraints, and approaches already rejected.",
5
5
  "keywords": [
6
6
  "mcp",