@theronap/agnoclast-mcp 0.9.174 → 0.9.175

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/lib/diagnose.mjs +23 -1
  2. package/package.json +1 -1
package/lib/diagnose.mjs CHANGED
@@ -542,6 +542,26 @@ export function outageReport(outcome, { tool, requestId = null, version = CLIENT
542
542
  return null
543
543
  }
544
544
 
545
+ // ⚠ "COULD NOT CONNECT" IS ALSO WHAT A LAPTOP WITH NO NETWORK LOOKS LIKE. The first real report (2026-09-25)
546
+ // was ×12 `connect` outages from one Mac between 09:34 and 11:39 — hooks running during DarkWake /
547
+ // Maintenance Sleep with the network half up, while production was healthy. So a thrown connect/timeout
548
+ // is only filed when the INTERNET is reachable and Agnoclast is not. The probe hits a neutral anycast host
549
+ // with its own short budget; if that fails too, the fault is local and nothing is filed. A response of any
550
+ // kind (infra 4xx/5xx, 503) proves the network worked, so those paths never probe.
551
+ const REACHABILITY_URL = 'https://1.1.1.1/cdn-cgi/trace'
552
+ const REACHABILITY_TIMEOUT_MS = 2500
553
+ let reachabilityProbe = async () => {
554
+ try {
555
+ const r = await fetch(REACHABILITY_URL, { method: 'GET', signal: AbortSignal.timeout(REACHABILITY_TIMEOUT_MS) })
556
+ try { await r.body?.cancel() } catch { /* nothing to drain */ }
557
+ return true
558
+ } catch {
559
+ return false
560
+ }
561
+ }
562
+ /** Tests: replace the internet-reachability probe. Returns the previous one. */
563
+ export function setReachabilityProbe(fn) { const prev = reachabilityProbe; reachabilityProbe = fn; return prev }
564
+
545
565
  /** Auto-filing is off under `bun test` unless the test points the spool somewhere (never the real home). */
546
566
  function autofileEnabled(env = process.env) {
547
567
  if (env.CORTEX_AUTOFILE === '0') return false
@@ -601,7 +621,9 @@ export async function fetchCortex(url, opts = {}, policy = {}) {
601
621
  } catch (e) {
602
622
  if (hook && e?.retryClass) {
603
623
  const r = outageReport({ thrownClass: e.retryClass }, { tool: toolForUrl(url) })
604
- if (r) spoolReport(r)
624
+ // Awaited, not fire-and-forget: hook processes are short-lived and would exit before a detached
625
+ // probe answered. Bounded by REACHABILITY_TIMEOUT_MS, and only on a path that is already failing.
626
+ try { if (r && await reachabilityProbe()) spoolReport(r) } catch { /* filing must never change the error */ }
605
627
  }
606
628
  throw e
607
629
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theronap/agnoclast-mcp",
3
- "version": "0.9.174",
3
+ "version": "0.9.175",
4
4
  "description": "Connect your AI assistant to Cortex — your org's projects, activity, gaps, and directives, scoped to you.",
5
5
  "type": "module",
6
6
  "bin": {