All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.4.0 — 2026-05-02
- gRPC instrumentation —
@grpc/grpc-jsdriver patch (drivers/grpc.ts). Auto-patches all four call types onClient.prototype:- Unary (
makeUnaryRequest) and client-streaming (makeClientStreamRequest) — wraps the callback to capture wall-clock duration and forward errors todiagnostics_channel. - Server-streaming (
makeServerStreamRequest) and bidi-streaming (makeBidiStreamRequest) — listens for the stream'sstatus(completion) anderrorevents; apublishedflag prevents double-publishing when both events fire for the same call. The RPC method path (e.g./package.Service/Method) is used as the query key, making gRPC calls visible in slow-query logs, the cache monitor, and OTLP exports. 17 drivers total (up from 16). Wired intoapplyDriverPatches()under a new// RPCsection; silently skipped when@grpc/grpc-jsis not installed.
- Unary (
CrossSignalRuleEngine— extracted class (R.3–R.7 rules) now exported directly; independently testable.CROSS_SIGNAL_THRESHOLDS— exported const with all cross-signal rule threshold defaults.WindowedMonitorBase— exported abstract class;GcMonitorandCacheMonitornow extend it.
- Architecture:
CrossSignalRuleEngineextracted fromArgusAgent;GcMonitor/CacheMonitorrefactored ontoWindowedMonitorBase. - Safety: silent
.catch()blocks replaced withthis.emit("warn", err);routeTrackernon-null assertion replaced with defensive check; global-regexlastIndexreset added inIndexHintAnalyzer,MigrationScanner, andArgusAgent. - Tests: 627 → 644 passing — scenario tests (worker-only, cache-degradation, crash-recovery), OTLP edge cases (circular payload, ECONNREFUSED, timeout), licensing boundary tests (JWT expiry ±1 s, clock-skew at 60 s boundary),
CrossSignalRuleEngineunit tests.
0.3.2 — 2026-04-29
- Package metadata: added
fundingfield pointing to GitHub Sponsors - Publish process: README is now copied from the repo root at publish time (
prepublishOnly) and cleaned up afterwards (postpublish) — single source of truth, no drift - Removed
src/licensing/public-key.tsfromfiles(compiled output indist/is sufficient; raw source was never needed by consumers) - CI: restored individual named steps (Typecheck / Lint / Format check / Build / Test) for better failure visibility in GitHub Actions
- README: fixed contributor
npmcommands →pnpmin "Building from source" section
0.3.0 — 2026-04-29
-
Phase R Wave 3 — Complex codebase-intelligence rules: Two new rules that require both runtime observations and TypeScript AST access to produce targeted advice that generic APMs cannot generate.
hot-path-select-star(warning) —ColumnUsageAnalyzertracks how many times aSELECT *call fires from the samesourceLine. Afterthresholdhits (default 5), it parses the TypeScript source file, finds the variable the result is assigned to, and walks the containing function scope to collect all accessed field names. The emittedhot-path-select-staranomaly replaces the generic "use explicit columns" suggestion with e.g. "you only accessid,email— replace withSELECT id, email". Supports.map()callbacks,rows[0].fieldelement access, andconst { a, b } = rows[0]destructuring. Falls back to null (and stays silent) for dynamic patterns or plain JS. Enabled via.withColumnUsageAnalysis(dir?, threshold?). Auto-wired fordbapp type in dev/test environments viaprofile-factory.unhandled-db-call(info/critical) —SourceAnalyzer.scanForUnhandledDbCall()walks the TypeScript AST of every source file and flags DB calls (query,execute,findMany,find, etc.) that have no surroundingtry/catchand no.catch()chain. Default severity isinfo. WhenCrashGuardfeeds in a set of crashed source lines (lines that have actually thrownuncaughtExceptionin production), any finding at a crashed location is escalated tocriticalwith a message that mentions the crash history. Integrated intoStaticScanner.scan()via the newrunUnhandledDbCallScan()method. Wired intoArgusAgentstartup scans; crash escalation feeds back from theCrashGuardevent stream.
-
Phase R Wave 2 — Static + runtime intelligence rules: Three new rules that combine static codebase knowledge with runtime frequency data to surface issues no single monitor can detect alone.
query-in-loop(warning) —SourceAnalyzerwalks the TypeScript AST of every source file at startup. When a known DB method call (query,execute,findMany,find, etc.) appears inside a loop (for,while,do,for…of,for…in) or an iteration callback (.map(),.forEach(),.filter(),.reduce(), …), it emits aquery-in-loopsuggestion with the exact file:line location. Wired intoStaticScanner.scan()via the newrunQueryInLoopScan()method.missing-index-hint(warning) —MigrationScannerparses SQL migration files (CREATE INDEX/CREATE UNIQUE INDEX) and Prisma schema files (@@index([…])) at startup to build atable → Set<column>index map.IndexHintAnalyzerthen tracks per-query execution frequency in a sliding window; when a query exceeds the threshold (default 100/min) against an un-indexedWHEREcolumn, it emits a concreteCREATE INDEXsuggestion. Only fires when migration files were found — no false positives when the index map is empty. Enabled via.withIndexHints(dir?).endpoint-never-called(info) —RouteTrackeraccepts a list of registered routes (extracted by a regex scanner from Express/Fastify source files) and records inbound request hits viacreateMiddleware(). After the warmup period (default 5 min) a'anomaly'event is emitted listing routes that never received a request. Enabled via.withRouteTracking(dir?, warmupMs?). Wired automatically inprofile-factory.tsforwebapp type in dev/test environments.
-
Demo app — Phase R scenarios (
quotes-demo-app/):- W3C trace context is now propagated into every request via
agent.createMiddleware()— wired inapp.jsso all cross-signal rules can correlate DB calls with their originating HTTP request. GET /debug/correlated-slow— runs 6 N+1 queries + 1 100 ms deliberate delay within one request, triggeringcorrelated-slow-endpoint(critical).GET /debug/n-plus-one-in-txn—BEGIN+ 6 identical-template SELECTs +COMMIT, triggeringn-plus-one-in-transaction(critical).GET /debug/sync-readalready demonstratessync-in-hot-pathnow that the middleware is active (bothsynchronous-fsandsync-in-hot-pathfire simultaneously).- The
anomalyevent handler indiagnostic.jsnow prints the fullsuggestionsarray (rule name, severity, message, suggestedFix) for all Phase R compound events. traffic.jsupdated with three new Phase R traffic scenarios.
- W3C trace context is now propagated into every request via
-
Phase R Wave 1 — Cross-signal diagnostic rules: Five new rules that correlate events from multiple subsystems to produce high-signal compound anomalies that no single monitor can produce alone.
sync-in-hot-path(critical) —FsAnalyzernow accepts aninsideRequestflag. When a*SyncFS call fires inside an active request context (AsyncLocalStorage), a second, more specific suggestion is emitted alongsidesynchronous-fs. Wired automatically byFsInstrumentationviagetCurrentContext().missing-connection-pool(warning) —StaticScanner.runConnectionPoolScan()walks the TypeScript AST at startup to detectnew Client(),new Connection(),createConnection(), etc. called inside function bodies instead of at module scope. Results are surfaced astool: "argus-static"ScanResultentries.correlated-slow-endpoint(critical) —ArgusAgentcross-references the active N+1 traceId index against incoming HTTP events. When an outbound HTTP call exceeds 1 s and the same W3CtraceIdhas an active N+1 pattern, a compoundanomalyis emitted.pool-starvation-by-slow-query(critical) — When apool-exhaustionevent fires within 10 s of a slow query on the same driver, the slow query is surfaced as the likely culprit holding connections.n-plus-one-in-transaction(critical) — When N+1 is detected inside an open transaction (matched bytraceId/correlationId), severity is escalated to critical because repeated queries inside a transaction also delay COMMIT and hold the connection.
SlowQueryMonitor.check()type contract — parameter changed fromdriver: stringtodriver: string | undefined. When no driver is known (e.g. manualtraceQuery()calls or rawdiagnostics_channelpublishes without adriverfield),check()now returnsnullimmediately instead of falling back to the synthetic string"unknown", which previously triggered a spuriousARGUS_MISSING_DRIVER_THRESHOLDprocess warning in CI.- Test isolation — the
missing-driver warningdescribe block inslow-query-monitor.test.tspreviously monkey-patchedprocess.emitWarning, which leaked across parallel test files and caused a flaky failure in CI. Replaced with the additiveprocess.on('warning')/process.off('warning')API, which is fully parallel-safe. Tests are nowasyncand yield onenextTickbefore asserting, matching the asynchronous dispatch path ofprocess.emitWarning.
- Architecture — God object split: Extracted three cohesive modules from the 1 109-line
diagnostic-agent.ts:src/internal/profile-factory.ts—buildAgentProfile()contains all preset-resolution and builder-wiring logic forArgusAgent.createProfile().src/internal/query-handler.ts—createQueryHandler()factory produces the per-query processing closure (adaptive sampling → query analysis → slow-query check → aggregation).src/internal/console-logger.ts—installConsoleLogger()registers formatted console output for all agent events and returns the listener pairs for clean removal onstop().diagnostic-agent.tsreduced from 1 109 → ~960 lines; each new module has a single responsibility and is independently testable.
SlowQueryMonitor.check()call site — the&& traced.driverguard added in a previous hotfix is removed; the type change makes it redundant and the intent is now expressed in the contract rather than the caller.
0.1.0 — 2026-04-11
ArgusAgentfluent builder with two entry points:create()(manual) andcreateProfile()(preset-based).- Zero-overhead global kill-switch via
ARGUS_ENABLED=false—.start()becomes a no-op with no timer, subscription, or memory overhead. ARGUS_DEBUG=truebuilt-in console logger for all agent events.
- Three environment presets:
prod,dev,test. - Three app-type presets:
web,db,worker(composable as an array). 'auto'mode — scanspackage.jsondependencies and infers the correct preset.ArgusAgent.detectAppTypes()standalone detector.
node:diagnostics_channel-based query tracing for 14 DB drivers:pg,mysql2,mssql,tedious,better-sqlite3,redis,ioredis,mongodb,@google-cloud/firestore,@aws-sdk/client-dynamodb,neo4j-driver,@elastic/elasticsearch,@clickhouse/client,@google-cloud/bigquery,cassandra-driver,@prisma/client.- Zero prototype-pollution — no monkey-patching of driver prototypes in the default path.
- HTTP outbound tracing (
node:diagnostics_channelon Node ≥ 18; monkey-patch fallback on Node 14–17). - File-system tracing (
fs.*Syncblocker detection) — dev/test only. - Console log tracing with Shannon entropy scrubbing.
- DNS lookup latency tracking.
- W3C
traceparentpropagation viaAsyncLocalStorage(createMiddleware()/runWithContext()).
SlowQueryMonitor— per-driver threshold registry (16 built-in defaults), top-N log,ARGUS_SLOW_QUERY_THRESHOLD_<DRIVER>env var overrides, once-per-driver dev warning for unregistered drivers.QueryAnalyzer— AST-based N+1 and query fix suggestions.TransactionMonitor— BEGIN/COMMIT/ROLLBACK duration tracking.CacheMonitor— sliding-window hit-rate degradation detection.CircuitBreakerDetector— sustained error-rate detection across drivers.ExplainAnalyzer— EXPLAIN plan parsing for supported drivers.StaticScanner— backgroundtsc/ ESLint scan (dev/test only).AuditScanner—npm auditCVE scan (dev/test only).
RuntimeMonitor— event loop lag, heap growth, CPU profiling.CrashGuard—uncaughtException/unhandledRejectiontelemetry and flush.ResourceLeakMonitor— OS handle / socket exhaustion detection.GcMonitor— GC pause pressure vianode:perf_hooks.PoolMonitor— connection pool exhaustion and slow-acquire events.SourceMapResolver—.js.mapscanning and lazy position resolution.GracefulShutdown— SIGTERM/SIGINT handler with configurable flush timeout.AdaptiveSampler— token-bucket rate limiter per event category.
AstSanitizer— SQL/NoSQL query values shredded at the AST layer (vianode-sql-parser).EntropyChecker— Shannon entropy scanner strips JWTs, API keys, and secrets from logs. Configurable threshold (default 4.0 bits/char).
MetricsAggregator— p99 sliding-window aggregation.OTLPExporter— OTLP JSON over mTLS (requires paid license).OTLPCompatibleExporter— simplified OTLP exporter with API key auth.
- ECDSA ES256 JWT license validation with offline verification.
- Clock-integrity guard (monotonic rollback detection).
- Expiry signal file written to cwd / tmpdir / homedir on license expiry.
- Dual ESM + CommonJS build (
dist/esm/anddist/cjs/). - Native TypeScript source execution via
--experimental-strip-types(Node ≥ 22.6, dev only). - Docker demo app (
quotes-demo-app/) withdocker composeone-liner. - 485 tests across 102 suites mirroring the source tree.