Network Latency Monitor (javascript, written by Claude Code)
envgap__claude-code__javascript-t1-29
Written by a coding agent; not on GitHubWritten 2026-02-27
01 / FAILURE SIGNATURE
As the study recorded it
No identifying execution failure has been captured.
Not a benchmark task.
- The project already builds and runs before the fix, so there is nothing to repair.
02 / ENVIRONMENT RECIPE
- Base commit
Not freshly verified- Manifest
package.json- Reproduce
Awaiting issue-specific recipe- Run under trace
Awaiting a meaningful runtime command
03 / TASK AND FAILURE
claude-code/javascript-t1 #29 · read the task the agent was given
Claude Code wrote this javascript project from the task below. It installed and ran on a clean Ubuntu 22.04 machine as written. Task given to the agent: TASK: Network Latency Monitor Write a program that continuously monitors network latency to multiple hosts using ICMP-like probes or TCP connection timing, tracking statistics over time and alerting on anomalies. FUNCTIONAL REQUIREMENTS: - Accept one or more hostnames or IP addresses as command-line arguments - Send periodic probes to each host at a configurable interval via --interval flag (default: 5 seconds) - Measure round-trip time (RTT) for each probe using TCP connection timing to a specified port (--port flag, default 80) since raw ICMP requires root privileges - Track running statistics per host: min RTT, max RTT, average RTT, median RTT, standard deviation, jitter (difference between consecutive measurements), and packet loss percentage - Support configurable monitoring duration via --duration flag (e.g., --duration 60s, --duration 5m, --duration 1h) or run until interrupted with Ctrl+C - Detect latency anomalies: flag probes where RTT exceeds a configurable threshold via --alert flag (default: 3x the running average RTT) - Display a live-updating console dashboard showing: host, last RTT, average RTT, min/max, packet loss %, and alert status - Record all measurements with timestamps for historical analysis - Save the full monitoring data as a JSON report with --output flag (default: latency_report.json) including per-host statistics and all individual measurements - Export time-series data as CSV via --export flag for external analysis - Support reading a list of hosts from a file via --file flag (one host per line with optional label) - If no hosts are given, monitor a set of well-known public hosts (8.8.8.8, 1.1.1.1, example.com, google.com) for 30 seconds, display live statistics, then print a final summary report comparing all hosts - Handle errors: unreachable hosts, DNS resolution failures, connection timeouts, and graceful shutdown saving partial data Create a complete JavaScript project for a clean Ubuntu 22.04 machine with only Node.js 20+ (LTS) installed. Include: - Source code - package.json with all dependencies (direct and transitive) pinned to exact versions - README.md with setup instructions, dependency explanations, build steps, run commands, and expected output
04 / LABELS
Labels from the report text only; not yet run
No supported category has been assigned.
Label rules and the text that matched
[]
05 / FILES
The project as the agent wrote it
2 files, exactly as written, before any repair.
monitor.js
#!/usr/bin/env node
/**
* Network Latency Monitor (JavaScript - Trial 1)
* Monitors network latency to multiple hosts with statistics, anomaly detection,
* and a live console dashboard using ping, chalk, and cli-table3.
*/
const ping = require('ping');
const chalk = require('chalk');
const Table = require('cli-table3');
// Default hosts to monitor
const DEFAULT_HOSTS = ['8.8.8.8', '1.1.1.1', '208.67.222.222', '9.9.9.9', '8.8.4.4'];
// Configuration
const PING_INTERVAL_MS = 1000;
const HISTORY_SIZE = 100;
const ANOMALY_ZSCORE_THRESHOLD = 2.5;
const PING_TIMEOUT = 2;
class HostStats {
constructor(host) {
this.host = host;
this.latencies = [];
this.totalPings = 0;
this.lostPings = 0;
this.lastLatency = null;
this.status = 'Waiting';
this.anomalies = [];
}
record(latencyMs) {
this.totalPings++;
if (latencyMs === null || latencyMs === undefined) {
this.lostPings++;
this.status = 'Timeout';
this.lastLatency = null;
} else {
if (this.latencies.length >= HISTORY_SIZE) {
this.latencies.shift();
}
this.latencies.push(latencyMs);
this.lastLatency = latencyMs;
this.status = 'OK';
this._checkAnomaly(latencyMs);
}
}
_checkAnomaly(latencyMs) {
if (this.latencies.length < 10) return;
const mean = this._mean();
const std = this._stdDev();
if (std === 0) return;
const zscore = (latencyMs - mean) / std;
if (Math.abs(zscore) > ANOMALY_ZSCORE_THRESHOLD) {
this.anomalies.push({
time: new Date().toLocaleTimeString(),
latency: latencyMs,
zscore,
mean
});
if (this.anomalies.length > 20) {
this.anomalies.shift();
}
}
}
get packetLoss() {
return this.totalPings === 0 ? 0 : (this.lostPings / this.totalPings) * 100;
}
_mean() {
if (this.latencies.length === 0) return 0;
return this.latencies.reduce((a, b) => a + b, 0) / this.latencies.length;
}
_stdDev() {
if (this.latencies.length === 0) return 0;
const m = this._mean();
const variance = this.latencies.reduce((sum, v) => sum + (v - m) ** 2, 0) / this.latencies.length;
return Math.sqrt(variance);
}
_percentile(p) {
if (this.latencies.length === 0) return 0;
const sorted = [...this.latencies].sort((a, b) => a - b);
const index = (p / 100) * (sorted.length - 1);
const lower = Math.floor(index);
const upper = Math.ceil(index);
if (lower === upper) return sorted[lower];
const frac = index - lower;
return sorted[lower] * (1 - frac) + sorted[upper] * frac;
}
get stats() {
if (this.latencies.length === 0) {
return { min: 0, max: 0, mean: 0, median: 0, std: 0, p95: 0, p99: 0 };
}
const sorted = [...this.latencies].sort((a, b) => a - b);
return {
min: sorted[0],
max: sorted[sorted.length - 1],
mean: this._mean(),
median: this._percentile(50),
std: this._stdDev(),
p95: this._percentile(95),
p99: this._percentile(99)
};
}
}
class NetworkLatencyMonitor {
constructor(hosts) {
this.hosts = hosts || DEFAULT_HOSTS;
this.hostStats = {};
this.running = false;
this.startTime = null;
for (const host of this.hosts) {
this.hostStats[host] = new HostStats(host);
}
}
async pingHost(host) {
try {
const result = await ping.promise.probe(host, {
timeout: PING_TIMEOUT,
extra: ['-c', '1']
});
if (result.alive && result.time !== 'unknown') {
this.hostStats[host].record(parseFloat(result.time));
} else {
this.hostStats[host].record(null);
}
} catch (err) {
this.hostStats[host].record(null);
}
}
async pingAllHosts() {
const promises = this.hosts.map(host => this.pingHost(host));
await Promise.all(promises);
}
buildSparkline(host) {
const blocks = ' _.~*';
const data = this.hostStats[host].latencies.slice(-30);
if (data.length < 2) return '';
const min = Math.min(...data);
const max = Math.max(...data);
const range = max - min || 1;
return data.map(v => {
const idx = Math.round(((v - min) / range) * (blocks.length - 1));
return blocks[idx];
}).join('');
}
printDashboard() {
console.clear();
const elapsed = Math.floor((Date.now() - this.startTime) / 1000);
const hrs = Math.floor(elapsed / 3600);
const mins = Math.floor((elapsed % 3600) / 60);
const secs = elapsed % 60;
const totalPings = Object.values(this.hostStats).reduce((s, h) => s + h.totalPings, 0);
const totalLost = Object.values(this.hostStats).reduce((s, h) => s + h.lostPings, 0);
const totalAnomalies = Object.values(this.hostStats).reduce((s, h) => s + h.anomalies.length, 0);
console.log(chalk.bold.cyan('='.repeat(120)));
console.log(chalk.bold.cyan(' NETWORK LATENCY MONITOR'));
console.log(chalk.gray(
` Uptime: ${String(hrs).padStart(2, '0')}:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')} | ` +
`Hosts: ${this.hosts.length} | Pings: ${totalPings} | Lost: ${totalLost} | Anomalies: ${totalAnomalies}`
));
console.log(chalk.bold.cyan('='.repeat(120)));
// Main stats table
const table = new Table({
head: [
chalk.white('Host'),
chalk.white('Status'),
chalk.white('Last (ms)'),
chalk.white('Min (ms)'),
chalk.white('Avg (ms)'),
chalk.white('Max (ms)'),
chalk.white('StdDev'),
chalk.white('P95 (ms)'),
chalk.white('Loss %'),
chalk.white('Samples'),
chalk.white('Trend')
],
colWidths: [18, 9, 10, 10, 10, 10, 9, 10, 9, 9, 32],
style: { head: [], border: ['gray'] }
});
for (const host of this.hosts) {
const hs = this.hostStats[host];
const s = hs.stats;
let statusStr;
if (hs.status === 'OK') statusStr = chalk.green.bold(' OK ');
else if (hs.status === 'Timeout') statusStr = chalk.red.bold('TOUT');
else statusStr = chalk.yellow('WAIT');
const lastStr = hs.lastLatency !== null ? hs.lastLatency.toFixed(1) : '-';
let lossStr;
if (hs.packetLoss > 20) lossStr = chalk.red(hs.packetLoss.toFixed(1) + '%');
else if (hs.packetLoss > 5) lossStr = chalk.yellow(hs.packetLoss.toFixed(1) + '%');
else lossStr = chalk.green(hs.packetLoss.toFixed(1) + '%');
const sparkline = this.buildSparkline(host);
table.push([
chalk.cyan(host),
statusStr,
lastStr,
s.min.toFixed(1),
s.mean.toFixed(1),
s.max.toFixed(1),
s.std.toFixed(2),
s.p95.toFixed(1),
lossStr,
hs.latencies.length.toString(),
chalk.yellow(sparkline)
]);
}
console.log(table.toString());
// Anomaly section
console.log(chalk.bold.red(`\n ANOMALY DETECTION (Z-score > ${ANOMALY_ZSCORE_THRESHOLD})`));
console.log(chalk.gray('-'.repeat(120)));
const allAnomalies = [];
for (const host of this.hosts) {
for (const a of this.hostStats[host].anomalies) {
allAnomalies.push({ ...a, host });
}
}
if (allAnomalies.length === 0) {
console.log(chalk.gray(' No anomalies detected yet.'));
} else {
const recent = allAnomalies.slice(-8);
for (const a of recent) {
console.log(
chalk.red(` [${a.time}]`) + ` ${a.host}: ` +
chalk.yellow(`${a.latency.toFixed(1)}ms`) +
` (z=${a.zscore > 0 ? '+' : ''}${a.zscore.toFixed(2)}, mean=${a.mean.toFixed(1)}ms)`
);
}
}
console.log(chalk.gray('\n Press Ctrl+C to stop'));
}
printFinalReport() {
console.log(chalk.bold.yellow('\n\nFINAL REPORT'));
console.log('='.repeat(120));
const reportTable = new Table({
head: ['Host', 'Pings', 'Loss%', 'Min', 'Mean', 'Median', 'P95', 'P99', 'Max', 'StdDev', 'Anomalies'],
style: { head: ['cyan'], border: ['gray'] }
});
for (const host of this.hosts) {
const hs = this.hostStats[host];
const s = hs.stats;
reportTable.push([
host,
hs.totalPings,
hs.packetLoss.toFixed(1) + '%',
s.min.toFixed(1),
s.mean.toFixed(1),
s.median.toFixed(1),
s.p95.toFixed(1),
s.p99.toFixed(1),
s.max.toFixed(1),
s.std.toFixed(2),
hs.anomalies.length
]);
}
console.log(reportTable.toString());
}
async run() {
this.running = true;
this.startTime = Date.now();
process.on('SIGINT', () => {
this.running = false;
this.printFinalReport();
process.exit(0);
});
console.log(chalk.bold.green('Network Latency Monitor starting...'));
console.log(`Monitoring ${this.hosts.length} hosts. Press Ctrl+C to stop.\n`);
while (this.running) {
await this.pingAllHosts();
this.printDashboard();
await new Promise(resolve => setTimeout(resolve, PING_INTERVAL_MS));
}
}
}
// Parse command line arguments
const args = process.argv.slice(2);
const hosts = args.length > 0 ? args : DEFAULT_HOSTS;
const monitor = new NetworkLatencyMonitor(hosts);
monitor.run().catch(err => {
console.error(chalk.red('Error:'), err.message);
process.exit(1);
});
package.json
{
"name": "network-latency-monitor",
"version": "1.0.0",
"description": "Network latency monitor with statistics, anomaly detection, and live dashboard",
"main": "monitor.js",
"scripts": {
"start": "node monitor.js",
"monitor": "node monitor.js"
},
"keywords": ["network", "latency", "monitor", "ping", "dashboard"],
"license": "MIT",
"dependencies": {
"ping": "0.4.4",
"chalk": "4.1.2",
"cli-table3": "0.6.3"
}
}