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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "argusqa-os",
3
- "version": "9.6.3",
3
+ "version": "9.6.4",
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": [
@@ -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: Connect to Chrome via the chrome-devtools MCP client
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
- const baseOrigin = new URL(targetUrl).origin;
226
-
227
- // Step 4: Audit each affected route via crawlRouteCheap
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, baseOrigin, mcp);
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 5: Compute aggregate summary and merge-block decision
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 6: Write GitHub Actions outputs and step summary
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 7: Emit JSON result to stdout for downstream pipeline steps
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)
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.3' },
450
+ { name: 'argus', version: '9.6.4' },
451
451
  { capabilities: { tools: {} } },
452
452
  );
453
453
 
@@ -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.