argusqa-os 9.6.2 → 9.6.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "argusqa-os",
3
- "version": "9.6.2",
3
+ "version": "9.6.3",
4
4
  "mcpName": "io.github.ironclawdevs27/argus",
5
5
  "description": "Argus — AI-powered automated dev-testing platform using Chrome DevTools MCP and Claude Code",
6
6
  "keywords": [
package/src/mcp-server.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Argus MCP Server (v9.6.2)
3
+ * Argus MCP Server (v9.6.3)
4
4
  *
5
5
  * Exposes Argus as an MCP server so Claude (or any MCP client) can call
6
6
  * argus_audit, argus_audit_full, argus_compare, argus_last_report, and
@@ -447,7 +447,7 @@ async function handleLastReport() {
447
447
  // ── Server bootstrap ──────────────────────────────────────────────────────────
448
448
 
449
449
  const server = new Server(
450
- { name: 'argus', version: '9.6.2' },
450
+ { name: 'argus', version: '9.6.3' },
451
451
  { capabilities: { tools: {} } },
452
452
  );
453
453
 
@@ -57,7 +57,7 @@ const TOOL_TIMEOUT_MS = parseInt(process.env.MCP_TOOL_TIMEOUT_MS ?? '30000', 10)
57
57
  export async function createMcpClient() {
58
58
  // On Windows, npx is npx.cmd — shell:true resolves this cross-platform.
59
59
  const proc = spawn('npx', [
60
- '-y', 'chrome-devtools-mcp@latest',
60
+ '-y', 'chrome-devtools-mcp@1.1.1',
61
61
  `--browser-url=${BROWSER_URL}`,
62
62
  '--headless=true',
63
63
  '--viewport=1920x1080',
@@ -36,8 +36,6 @@ export function parsePrUrl(prUrl) {
36
36
  */
37
37
  export async function fetchPrFiles(prUrl, githubToken) {
38
38
  const { owner, repo, prNumber } = parsePrUrl(prUrl);
39
- const apiUrl =
40
- `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/files?per_page=100`;
41
39
  const headers = {
42
40
  Accept: 'application/vnd.github+json',
43
41
  'X-GitHub-Api-Version': '2022-11-28',
@@ -45,15 +43,41 @@ export async function fetchPrFiles(prUrl, githubToken) {
45
43
  ...(githubToken ? { Authorization: `Bearer ${githubToken}` } : {}),
46
44
  };
47
45
 
48
- const res = await fetch(apiUrl, { headers });
49
- if (!res.ok) {
50
- const body = await res.text().catch(() => '');
51
- throw new Error(`GitHub API ${res.status}: ${body || res.statusText}`);
46
+ const allFiles = [];
47
+ const MAX_PAGES = 3; // caps at 300 files; avoids runaway requests on mega-PRs
48
+
49
+ for (let page = 1; page <= MAX_PAGES; page++) {
50
+ const apiUrl = `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/files?per_page=100&page=${page}`;
51
+ const res = await fetch(apiUrl, { headers });
52
+ if (!res.ok) {
53
+ const body = await res.text().catch(() => '');
54
+ throw new Error(`GitHub API ${res.status}: ${body || res.statusText}`);
55
+ }
56
+ const files = await res.json();
57
+ allFiles.push(...files.map(f => f.filename));
58
+ if (files.length < 100) break; // last page reached
59
+ }
60
+
61
+ if (allFiles.length >= 300) {
62
+ console.log('::warning::PR has 300+ changed files — Argus analyzed the first 300. Routes affected by later files may be missed.');
52
63
  }
53
- const files = await res.json();
54
- return files.map(f => f.filename);
64
+
65
+ return allFiles;
55
66
  }
56
67
 
68
+ /**
69
+ * Files that are never relevant to app routes — CI configs, docs, repo metadata.
70
+ * Changes to ONLY these files cause mapFilesToRoutes to return [] (skip audit).
71
+ */
72
+ const EXCLUDED_PATTERNS = [
73
+ /^\.github\//i,
74
+ /^docs?\//i,
75
+ /\.md$/i,
76
+ /^(LICENSE|CHANGELOG|CONTRIBUTING|CODE_OF_CONDUCT|SECURITY)(\..*)?$/i,
77
+ /^\.gitignore$/i,
78
+ /^\.gitattributes$/i,
79
+ ];
80
+
57
81
  /**
58
82
  * Patterns that indicate an infrastructure-level file whose change can affect
59
83
  * every route — framework configs, root layouts, global stylesheets, package.json.
@@ -88,15 +112,22 @@ export function mapFilesToRoutes(changedFiles, routes) {
88
112
  if (!routes || routes.length === 0) return [];
89
113
  if (!changedFiles || changedFiles.length === 0) return routes;
90
114
 
115
+ // Strip files that are never app-route-relevant (CI configs, docs, repo metadata)
116
+ const appFiles = changedFiles.filter(
117
+ f => !EXCLUDED_PATTERNS.some(re => re.test(f)),
118
+ );
119
+
120
+ // README-only / CI-only PR — skip the audit entirely
121
+ if (appFiles.length === 0) return [];
122
+
91
123
  // Infrastructure change → full audit
92
- if (changedFiles.some(f => INFRA_PATTERNS.some(re => re.test(f)))) {
124
+ if (appFiles.some(f => INFRA_PATTERNS.some(re => re.test(f)))) {
93
125
  return routes;
94
126
  }
95
127
 
96
- // Build a flat set of lowercase slugs from every changed file path
128
+ // Build a flat set of lowercase slugs from app-relevant changed files
97
129
  const fileSlugs = new Set(
98
- changedFiles.flatMap(f =>
99
- // Strip extension, split on separators, keep non-trivial tokens
130
+ appFiles.flatMap(f =>
100
131
  f.toLowerCase()
101
132
  .replace(/\.[^./\\]+$/, '')
102
133
  .split(/[/\\._-]+/)