issuewatcher-mcp 0.2.0 → 0.2.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.
- package/README.md +7 -1
- package/build/scoring/score.js +29 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,7 +48,13 @@ Pick your app:
|
|
|
48
48
|
claude mcp add issuewatcher -e GITHUB_TOKEN=github_pat_xxxxxxxx -- npx -y issuewatcher-mcp
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
Then run `/mcp` inside Claude Code to see it connected.
|
|
51
|
+
Then run `/mcp` inside Claude Code to see it connected. The server is added for the current project folder; add `--scope user` to have it in every folder.
|
|
52
|
+
|
|
53
|
+
**Windows PowerShell** swallows the `--`, which makes Claude Code fail with `unknown option '-y'`. Put the `--` in quotes:
|
|
54
|
+
|
|
55
|
+
```powershell
|
|
56
|
+
claude mcp add issuewatcher -e "GITHUB_TOKEN=github_pat_xxxxxxxx" '--' npx -y issuewatcher-mcp
|
|
57
|
+
```
|
|
52
58
|
|
|
53
59
|
</details>
|
|
54
60
|
|
package/build/scoring/score.js
CHANGED
|
@@ -32,15 +32,31 @@ function nonLatinShare(text) {
|
|
|
32
32
|
}
|
|
33
33
|
const LABEL_DISMISSED = /(duplicate|invalid|wontfix|won't fix|not a bug)/i;
|
|
34
34
|
const VERSION_IN_TEXT = /\bv?(\d+)\.(\d+)\.(\d+)\b|\bv(\d+)\.(\d+)\b/g;
|
|
35
|
+
const WORKING_VERSION = /(worked|works|working|fine|as it did|did|passes|passed)\s+(in|on|with|until|before)\s+(version\s+)?$|(before|previously|prior to|until|downgrad\w*\s+to|rolled? back to|older than|earlier than)\s+(version\s+)?$/i;
|
|
35
36
|
const clamp = (n) => Math.max(0, Math.min(100, Math.round(n)));
|
|
36
37
|
/** Versions mentioned in free text, as {major, minor}. */
|
|
37
38
|
function mentionedVersions(text) {
|
|
38
39
|
const out = [];
|
|
39
40
|
for (const m of text.matchAll(VERSION_IN_TEXT)) {
|
|
41
|
+
// "worked in 0.3.31" names the version that is fine, not the one that is broken.
|
|
42
|
+
const before = text.slice(Math.max(0, (m.index ?? 0) - 40), m.index ?? 0);
|
|
43
|
+
if (WORKING_VERSION.test(before))
|
|
44
|
+
continue;
|
|
40
45
|
out.push({ major: Number(m[1] ?? m[4]), minor: Number(m[2] ?? m[5]) });
|
|
41
46
|
}
|
|
42
47
|
return out;
|
|
43
48
|
}
|
|
49
|
+
/** Words that may come right before a version without it belonging to some other product. */
|
|
50
|
+
const VERSION_LEAD = new Set("in on since from after with to at for and the version v".split(" "));
|
|
51
|
+
/** Majors a title names ("1.x", "v2", "2.3.1"). "TS 7.0" or "Node 22.x" name another product and are skipped. */
|
|
52
|
+
function titleMajors(title) {
|
|
53
|
+
const out = [];
|
|
54
|
+
for (const m of title.matchAll(/(^|[^\w.])(?:([a-z][\w-]*)\s+)?v?(\d+)\.(?:x|\d+)/gi)) {
|
|
55
|
+
if (!m[2] || VERSION_LEAD.has(m[2].toLowerCase()))
|
|
56
|
+
out.push(Number(m[3]));
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
44
60
|
/**
|
|
45
61
|
* The user's dependencies that this issue is actually about. DefinitelyTyped holds the types
|
|
46
62
|
* for every package, so only an issue about a @types package the user depends on is about
|
|
@@ -107,7 +123,16 @@ export function scoreIssueDetailed(issue, target, opts = {}) {
|
|
|
107
123
|
// Does the report concern a version the user runs?
|
|
108
124
|
const text = `${issue.title}\n${issue.body.slice(0, 4000)}`;
|
|
109
125
|
const versions = mentionedVersions(text);
|
|
110
|
-
|
|
126
|
+
// A title about a newer major than you run (a "1.x regression", you use ^0.3) is probably not about
|
|
127
|
+
// you. Older versions in its body are then comparisons ("worked in 0.3.31"), not matches.
|
|
128
|
+
const titleVersions = titleMajors(issue.title);
|
|
129
|
+
const mineMajors = deps.map((d) => minVersion(d.range)).filter((v) => v !== null);
|
|
130
|
+
const newerMajor = consumer &&
|
|
131
|
+
!runtime?.range.includes("*") &&
|
|
132
|
+
titleVersions.length > 0 &&
|
|
133
|
+
mineMajors.length > 0 &&
|
|
134
|
+
titleVersions.every((m) => mineMajors.every((v) => m > v.major));
|
|
135
|
+
if (consumer && versions.length && !newerMajor) {
|
|
111
136
|
let best = null;
|
|
112
137
|
for (const dep of deps) {
|
|
113
138
|
const mine = minVersion(dep.range);
|
|
@@ -135,6 +160,9 @@ export function scoreIssueDetailed(issue, target, opts = {}) {
|
|
|
135
160
|
add(best.points, "version-match", best.reason);
|
|
136
161
|
}
|
|
137
162
|
}
|
|
163
|
+
if (newerMajor) {
|
|
164
|
+
add(-15, "newer-major", `title is about v${titleVersions[0]}, you use ${deps[0].range}`);
|
|
165
|
+
}
|
|
138
166
|
// Severity signals. Each is recorded individually; the total is capped afterwards.
|
|
139
167
|
let severity = 0;
|
|
140
168
|
const sevParts = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "issuewatcher-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "MCP server that ranks new GitHub issues for your AI assistant: what to pick up, and what may break your projects.",
|
|
5
5
|
"mcpName": "io.github.mac146/issuewatcher",
|
|
6
6
|
"license": "MIT",
|