argusqa-os 9.6.3 → 9.6.4
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 +1 -1
- package/src/cli/pr-validate.js +29 -8
- package/src/mcp-server.js +2 -2
- package/src/utils/mcp-client.js +2 -0
package/package.json
CHANGED
package/src/cli/pr-validate.js
CHANGED
|
@@ -123,6 +123,20 @@ export function writeStepSummary(markdown) {
|
|
|
123
123
|
fs.appendFileSync(summaryPath, markdown);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
// ── Preflight reachability check ──────────────────────────────────────────────
|
|
127
|
+
|
|
128
|
+
async function checkTargetReachable(url) {
|
|
129
|
+
try {
|
|
130
|
+
// fetch throws only on network errors (ECONNREFUSED, ETIMEDOUT, DNS failure).
|
|
131
|
+
// HTTP error status codes (4xx/5xx) still mean the server is up — Argus should
|
|
132
|
+
// audit those pages, so we only gate on network-level failures.
|
|
133
|
+
await fetch(url, { method: 'HEAD', signal: AbortSignal.timeout(10000) });
|
|
134
|
+
return { ok: true };
|
|
135
|
+
} catch (err) {
|
|
136
|
+
return { ok: false, error: err.message };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
126
140
|
// ── Route loader ──────────────────────────────────────────────────────────────
|
|
127
141
|
|
|
128
142
|
async function loadRoutes() {
|
|
@@ -217,20 +231,27 @@ async function main() {
|
|
|
217
231
|
|
|
218
232
|
console.log(`[argus] Auditing ${affected.length} route(s): ${affected.map(r => r.path).join(', ')}`);
|
|
219
233
|
|
|
220
|
-
// Step 3:
|
|
234
|
+
// Step 3: Verify target is reachable before spending time on Chrome startup
|
|
235
|
+
console.log(`[argus] Verifying target is reachable: ${targetUrl}`);
|
|
236
|
+
const reachable = await checkTargetReachable(targetUrl);
|
|
237
|
+
if (!reachable.ok) {
|
|
238
|
+
throw new Error(`Target URL not reachable (${targetUrl}): ${reachable.error}. Make sure your app is running and accessible from the runner before this action fires.`);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Step 4: Connect to Chrome via the chrome-devtools MCP client
|
|
221
242
|
console.log('[argus] Connecting to Chrome on port 9222...');
|
|
222
243
|
mcp = await createMcpClient();
|
|
223
244
|
console.log('[argus] Chrome connected.');
|
|
224
245
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
246
|
+
// Step 5: Audit each affected route via crawlRouteCheap
|
|
247
|
+
// Preserve path prefix (e.g. /project/ in GitHub Pages) — .origin would strip it
|
|
248
|
+
const baseUrl = targetUrl.replace(/\/$/, '');
|
|
228
249
|
for (const route of affected) {
|
|
229
250
|
const url = new URL(route.path, targetUrl).href;
|
|
230
251
|
console.log(`[argus] → Auditing ${url}`);
|
|
231
252
|
|
|
232
253
|
try {
|
|
233
|
-
const raw = await crawlRouteCheap(route,
|
|
254
|
+
const raw = await crawlRouteCheap(route, baseUrl, mcp);
|
|
234
255
|
const findings = Array.isArray(raw.errors) ? raw.errors : [];
|
|
235
256
|
allFindings.push(...findings);
|
|
236
257
|
|
|
@@ -255,7 +276,7 @@ async function main() {
|
|
|
255
276
|
}
|
|
256
277
|
}
|
|
257
278
|
|
|
258
|
-
// Step
|
|
279
|
+
// Step 6: Compute aggregate summary and merge-block decision
|
|
259
280
|
const summary = {
|
|
260
281
|
critical: allFindings.filter(f => f.severity === 'critical').length,
|
|
261
282
|
warning: allFindings.filter(f => f.severity === 'warning').length,
|
|
@@ -267,11 +288,11 @@ async function main() {
|
|
|
267
288
|
blockOn === 'warning' ? summary.critical + summary.warning > 0 :
|
|
268
289
|
false;
|
|
269
290
|
|
|
270
|
-
// Step
|
|
291
|
+
// Step 7: Write GitHub Actions outputs and step summary
|
|
271
292
|
writeGithubOutputs({ blocked, summary, affectedRoutes: affected });
|
|
272
293
|
writeStepSummary(buildStepSummary({ blocked, summary, affectedRoutes: affected, perRoute, findings: allFindings, changedFiles: files, blockOn }));
|
|
273
294
|
|
|
274
|
-
// Step
|
|
295
|
+
// Step 8: Emit JSON result to stdout for downstream pipeline steps
|
|
275
296
|
const result = {
|
|
276
297
|
prUrl, targetUrl,
|
|
277
298
|
affectedRoutes: affected.map(r => r.path),
|
package/src/mcp-server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Argus MCP Server (v9.6.
|
|
3
|
+
* Argus MCP Server (v9.6.4)
|
|
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.
|
|
450
|
+
{ name: 'argus', version: '9.6.4' },
|
|
451
451
|
{ capabilities: { tools: {} } },
|
|
452
452
|
);
|
|
453
453
|
|
package/src/utils/mcp-client.js
CHANGED
|
@@ -133,6 +133,8 @@ export async function createMcpClient() {
|
|
|
133
133
|
capabilities: {},
|
|
134
134
|
clientInfo: { name: 'argus', version: '1.0.0' },
|
|
135
135
|
});
|
|
136
|
+
// MCP 2024-11-05 spec: client MUST send this notification before any tool calls
|
|
137
|
+
proc.stdin.write(JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized', params: {} }) + '\n');
|
|
136
138
|
|
|
137
139
|
/**
|
|
138
140
|
* Call an MCP tool by name with params.
|