GZIP Compression Tool (javascript, written by Claude Code)
envgap__claude-code__javascript-t1-37
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 #37 · 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: GZIP Compression Tool Write a program that compresses and decompresses files using the GZIP format with configurable compression levels, integrity verification, and streaming support for large files. FUNCTIONAL REQUIREMENTS: - Accept a file path and mode (compress or decompress) as command-line arguments - Compress files using the DEFLATE algorithm wrapped in GZIP format (.gz extension) - Support configurable compression level via --level flag (1=fastest, 9=best compression; default: 6) - Decompress .gz files back to their original content, preserving the original filename stored in the GZIP header - Process files in streaming chunks to handle files larger than available memory, with configurable buffer size via --buffer flag (default: 64KB) - Display real-time progress during compression/decompression: percentage complete, current speed, and estimated time remaining - Verify file integrity after compression by checking CRC-32 checksums stored in the GZIP header via --verify flag - Support compressing multiple files via --batch flag (each file becomes a separate .gz file) - Preserve original file timestamps in the GZIP header and restore them during decompression - Support keeping or removing the original file via --keep flag (default: keep original) - Print compression summary: original size, compressed size, compression ratio, time taken, and throughput (MB/s) - Save operation log as JSON with --log flag - If no input is given, generate sample files of different types (text, CSV, JSON, binary with random data), compress each, compare compression ratios across file types, decompress, and verify integrity matches - Handle errors: corrupted GZIP files, truncated files, CRC mismatch, disk full, and unsupported GZIP extensions 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.
gzip_tool.js
#!/usr/bin/env node
/**
* GZIP Compression Tool
*
* A command-line utility for compressing and decompressing files using GZIP/DEFLATE
* with streaming support and integrity verification.
*
* Dependencies:
* - zlib (built-in): Node.js standard library for GZIP and DEFLATE compression.
* - commander (12.0.0): Command-line interface framework.
*/
const fs = require("fs");
const path = require("path");
const zlib = require("zlib");
const crypto = require("crypto");
const { Command } = require("commander");
const CHUNK_SIZE = 65536; // 64 KB
/**
* Format byte size into human-readable string.
*/
function formatSize(bytes) {
const units = ["B", "KB", "MB", "GB", "TB"];
let size = bytes;
for (const unit of units) {
if (size < 1024.0) {
return `${size.toFixed(2)} ${unit}`;
}
size /= 1024.0;
}
return `${size.toFixed(2)} PB`;
}
/**
* Compute SHA-256 hash of a file using streaming reads.
*/
function computeSha256(filePath) {
return new Promise((resolve, reject) => {
const hash = crypto.createHash("sha256");
const stream = fs.createReadStream(filePath, { highWaterMark: CHUNK_SIZE });
stream.on("data", (chunk) => hash.update(chunk));
stream.on("end", () => resolve(hash.digest("hex")));
stream.on("error", reject);
});
}
/**
* Compute CRC-32 of a buffer (used for verification).
*/
function crc32(buf, previous) {
const table = crc32.table || (crc32.table = (() => {
const t = new Uint32Array(256);
for (let i = 0; i < 256; i++) {
let c = i;
for (let j = 0; j < 8; j++) {
c = (c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1);
}
t[i] = c;
}
return t;
})());
let crc = (previous !== undefined ? previous : 0) ^ 0xFFFFFFFF;
for (let i = 0; i < buf.length; i++) {
crc = (crc >>> 8) ^ table[(crc ^ buf[i]) & 0xFF];
}
return (crc ^ 0xFFFFFFFF) >>> 0;
}
/**
* Verify the integrity of a GZIP file.
*/
async function verifyGzipIntegrity(filePath) {
const result = {
valid: false,
error: null,
originalSize: 0,
compressedSize: 0,
crc32Match: false,
sizeMatch: false,
};
try {
const stats = fs.statSync(filePath);
result.compressedSize = stats.size;
// Check magic bytes and read trailer
const fd = fs.openSync(filePath, "r");
const magic = Buffer.alloc(2);
fs.readSync(fd, magic, 0, 2, 0);
if (magic[0] !== 0x1f || magic[1] !== 0x8b) {
fs.closeSync(fd);
result.error = "Invalid GZIP magic bytes";
return result;
}
const trailer = Buffer.alloc(8);
fs.readSync(fd, trailer, 0, 8, stats.size - 8);
fs.closeSync(fd);
const storedCrc32 = trailer.readUInt32LE(0);
const storedSize = trailer.readUInt32LE(4);
// Decompress and compute actual CRC-32 and size
const decompressed = await new Promise((resolve, reject) => {
const chunks = [];
const gunzip = zlib.createGunzip();
const input = fs.createReadStream(filePath, { highWaterMark: CHUNK_SIZE });
input.pipe(gunzip);
gunzip.on("data", (chunk) => chunks.push(chunk));
gunzip.on("end", () => resolve(Buffer.concat(chunks)));
gunzip.on("error", reject);
});
let actualCrc = 0;
for (let offset = 0; offset < decompressed.length; offset += CHUNK_SIZE) {
const end = Math.min(offset + CHUNK_SIZE, decompressed.length);
actualCrc = crc32(decompressed.subarray(offset, end), actualCrc === 0 ? undefined : (actualCrc ^ 0xFFFFFFFF) >>> 0);
}
// Simpler: recompute on full buffer
actualCrc = crc32(decompressed);
const actualSize = decompressed.length;
const actualSizeMod = actualSize % (2 ** 32);
result.originalSize = actualSize;
result.crc32Match = actualCrc === storedCrc32;
result.sizeMatch = actualSizeMod === storedSize;
result.valid = result.crc32Match && result.sizeMatch;
} catch (err) {
result.error = err.message;
}
return result;
}
const program = new Command();
program
.name("gzip-tool")
.description("GZIP Compression Tool - Compress and decompress files with GZIP/DEFLATE")
.version("1.0.0");
program
.command("compress")
.description("Compress a file using GZIP/DEFLATE")
.argument("<input>", "Input file path")
.option("-o, --output <path>", "Output file path (defaults to INPUT.gz)")
.option("-l, --level <n>", "Compression level (1=fastest, 9=best)", "6")
.option("-f, --force", "Overwrite output file if it exists", false)
.option("-v, --verbose", "Show detailed compression statistics", false)
.action(async (input, opts) => {
const inputFile = path.resolve(input);
if (!fs.existsSync(inputFile)) {
console.error(`Error: Input file not found: ${inputFile}`);
process.exit(1);
}
const output = opts.output ? path.resolve(opts.output) : inputFile + ".gz";
const level = parseInt(opts.level, 10);
if (level < 1 || level > 9) {
console.error("Error: Compression level must be between 1 and 9.");
process.exit(1);
}
if (fs.existsSync(output) && !opts.force) {
console.error(`Error: Output file '${output}' already exists. Use -f to overwrite.`);
process.exit(1);
}
const inputStats = fs.statSync(inputFile);
const inputSize = inputStats.size;
if (opts.verbose) {
console.log(`Input: ${inputFile} (${formatSize(inputSize)})`);
console.log(`Output: ${output}`);
console.log(`Compression level: ${level}`);
}
const startTime = Date.now();
try {
await new Promise((resolve, reject) => {
const readStream = fs.createReadStream(inputFile, { highWaterMark: CHUNK_SIZE });
const gzip = zlib.createGzip({ level });
const writeStream = fs.createWriteStream(output);
let bytesRead = 0;
readStream.on("data", (chunk) => {
bytesRead += chunk.length;
if (opts.verbose && inputSize > 0) {
const progress = ((bytesRead / inputSize) * 100).toFixed(1);
process.stdout.write(`\rProgress: ${progress}%`);
}
});
writeStream.on("finish", () => {
if (opts.verbose) process.stdout.write("\n");
resolve();
});
writeStream.on("error", reject);
readStream.on("error", reject);
gzip.on("error", reject);
readStream.pipe(gzip).pipe(writeStream);
});
} catch (err) {
console.error(`Error during compression: ${err.message}`);
if (fs.existsSync(output)) fs.unlinkSync(output);
process.exit(1);
}
const elapsed = (Date.now() - startTime) / 1000;
const outputSize = fs.statSync(output).size;
if (opts.verbose) {
const ratio = inputSize > 0 ? ((1 - outputSize / inputSize) * 100).toFixed(1) : "0.0";
console.log(`Compressed size: ${formatSize(outputSize)}`);
console.log(`Compression ratio: ${ratio}%`);
console.log(`Time: ${elapsed.toFixed(3)}s`);
console.log(`SHA-256 (input): ${await computeSha256(inputFile)}`);
console.log(`SHA-256 (output): ${await computeSha256(output)}`);
} else {
console.log(`Compressed '${inputFile}' -> '${output}' (${formatSize(inputSize)} -> ${formatSize(outputSize)})`);
}
});
program
.command("decompress")
.description("Decompress a GZIP file")
.argument("<input>", "Input GZIP file path")
.option("-o, --output <path>", "Output file path")
.option("-f, --force", "Overwrite output file if it exists", false)
.option("-v, --verbose", "Show detailed decompression statistics", false)
.action(async (input, opts) => {
const inputFile = path.resolve(input);
if (!fs.existsSync(inputFile)) {
console.error(`Error: Input file not found: ${inputFile}`);
process.exit(1);
}
let output;
if (opts.output) {
output = path.resolve(opts.output);
} else if (inputFile.endsWith(".gz")) {
output = inputFile.slice(0, -3);
} else {
output = inputFile + ".out";
}
if (fs.existsSync(output) && !opts.force) {
console.error(`Error: Output file '${output}' already exists. Use -f to overwrite.`);
process.exit(1);
}
const inputSize = fs.statSync(inputFile).size;
if (opts.verbose) {
console.log(`Input: ${inputFile} (${formatSize(inputSize)})`);
console.log(`Output: ${output}`);
}
const startTime = Date.now();
let bytesWritten = 0;
try {
await new Promise((resolve, reject) => {
const readStream = fs.createReadStream(inputFile, { highWaterMark: CHUNK_SIZE });
const gunzip = zlib.createGunzip();
const writeStream = fs.createWriteStream(output);
gunzip.on("data", (chunk) => {
bytesWritten += chunk.length;
if (opts.verbose) {
process.stdout.write(`\rDecompressed: ${formatSize(bytesWritten)}`);
}
});
writeStream.on("finish", () => {
if (opts.verbose) process.stdout.write("\n");
resolve();
});
writeStream.on("error", reject);
readStream.on("error", reject);
gunzip.on("error", reject);
readStream.pipe(gunzip).pipe(writeStream);
});
} catch (err) {
console.error(`Error during decompression: ${err.message}`);
if (fs.existsSync(output)) fs.unlinkSync(output);
process.exit(1);
}
const elapsed = (Date.now() - startTime) / 1000;
const outputSize = fs.statSync(output).size;
if (opts.verbose) {
console.log(`Decompressed size: ${formatSize(outputSize)}`);
console.log(`Time: ${elapsed.toFixed(3)}s`);
console.log(`SHA-256 (output): ${await computeSha256(output)}`);
} else {
console.log(`Decompressed '${inputFile}' -> '${output}' (${formatSize(inputSize)} -> ${formatSize(outputSize)})`);
}
});
program
.command("verify")
.description("Verify the integrity of a GZIP file")
.argument("<input>", "Input GZIP file path")
.option("-v, --verbose", "Show detailed verification results", false)
.action(async (input, opts) => {
const inputFile = path.resolve(input);
if (!fs.existsSync(inputFile)) {
console.error(`Error: File not found: ${inputFile}`);
process.exit(1);
}
if (opts.verbose) {
console.log(`Verifying: ${inputFile}`);
}
const result = await verifyGzipIntegrity(inputFile);
if (result.error) {
console.error(`FAILED: ${result.error}`);
process.exit(1);
}
if (opts.verbose) {
console.log(`Compressed size: ${formatSize(result.compressedSize)}`);
console.log(`Original size: ${formatSize(result.originalSize)}`);
console.log(`CRC-32 match: ${result.crc32Match ? "Yes" : "No"}`);
console.log(`Size match: ${result.sizeMatch ? "Yes" : "No"}`);
}
if (result.valid) {
console.log(`OK: '${inputFile}' integrity verified successfully.`);
} else {
console.error(`FAILED: '${inputFile}' integrity check failed.`);
process.exit(1);
}
});
program
.command("info")
.description("Display information about a GZIP file")
.argument("<input>", "Input GZIP file path")
.action(async (input) => {
const inputFile = path.resolve(input);
if (!fs.existsSync(inputFile)) {
console.error(`Error: File not found: ${inputFile}`);
process.exit(1);
}
try {
const stats = fs.statSync(inputFile);
const compressedSize = stats.size;
const fd = fs.openSync(inputFile, "r");
const header = Buffer.alloc(10);
fs.readSync(fd, header, 0, 10, 0);
if (header[0] !== 0x1f || header[1] !== 0x8b) {
fs.closeSync(fd);
console.error("Error: Not a valid GZIP file.");
process.exit(1);
}
const method = header[2];
const flags = header[3];
const mtime = header.readUInt32LE(4);
const trailer = Buffer.alloc(8);
fs.readSync(fd, trailer, 0, 8, compressedSize - 8);
fs.closeSync(fd);
const storedCrc32 = trailer.readUInt32LE(0);
const storedSize = trailer.readUInt32LE(4);
console.log(`File: ${inputFile}`);
console.log(`Compressed size: ${formatSize(compressedSize)}`);
console.log(`Original size: ${formatSize(storedSize)} (mod 2^32)`);
console.log(`Compression method: ${method === 8 ? "DEFLATE" : `Unknown (${method})`}`);
console.log(`CRC-32: 0x${storedCrc32.toString(16).padStart(8, "0")}`);
if (mtime > 0) {
const dt = new Date(mtime * 1000);
console.log(`Modification time: ${dt.toISOString()}`);
}
if (compressedSize > 0 && storedSize > 0) {
const ratio = ((1 - compressedSize / storedSize) * 100).toFixed(1);
console.log(`Compression ratio: ${ratio}%`);
}
} catch (err) {
console.error(`Error reading file info: ${err.message}`);
process.exit(1);
}
});
program.parseAsync(process.argv);
package.json
{
"name": "gzip-compression-tool",
"version": "1.0.0",
"description": "GZIP Compression Tool using zlib + commander",
"main": "gzip_tool.js",
"scripts": {
"start": "node gzip_tool.js"
},
"dependencies": {
"commander": "12.0.0"
}
}