{
  "name": "codegen-cli-tool",
  "description": "Build a CLI tool from a specification",
  "dataset": "terminal-bench-local",
  "difficulty": "medium",
  "instruction": "Create a Python command-line tool called wordstats.py that analyzes text files. It should accept the following usage:\n\n  python3 wordstats.py <file> [--top N] [--min-length N] [--sort alpha|freq] [--ignore-case]\n\nBehavior:\n- Read the given file and count word frequencies\n- Words are sequences of alphanumeric characters (split on non-alphanumeric)\n- --top N: Show only the top N words (default: show all)\n- --min-length N: Only count words with at least N characters (default: 1)\n- --sort alpha|freq: Sort by alphabetical or frequency, default freq (descending). Ties in freq sort alphabetically.\n- --ignore-case: Treat words case-insensitively (output lowercase)\n\nOutput format: one word per line as 'word: count'\nIf file doesn't exist, print 'Error: file not found' to stderr and exit 1.",
  "setup_files": {
    "sample.txt": "The quick brown fox jumps over the lazy dog.\nThe dog barked at the fox, and the fox ran away.\nQuick brown foxes are quicker than the lazy dogs.",
    "test_wordstats.py": "import subprocess\nimport sys\nimport os\n\npassed = 0\nfailed = 0\n\ndef check(desc, got, expected):\n    global passed, failed\n    got = got.strip()\n    expected = expected.strip()\n    if got == expected:\n        passed += 1\n    else:\n        print(f\"FAIL {desc}:\")\n        print(f\"  got:      {repr(got[:200])}\")\n        print(f\"  expected: {repr(expected[:200])}\")\n        failed += 1\n\ndef run(*args):\n    r = subprocess.run([sys.executable, 'wordstats.py'] + list(args), capture_output=True, text=True, timeout=10)\n    return r.stdout.strip(), r.stderr.strip(), r.returncode\n\n# Test 1: Basic freq sort (ignore case)\nout, _, _ = run('sample.txt', '--ignore-case', '--sort', 'freq', '--top', '5')\nlines = out.strip().split('\\n')\ncheck('top word', lines[0], 'the: 6')\n# 'fox' appears 3 times (the fox, the fox, the fox)\ncheck('line count', str(len(lines)), '5')\n\n# Test 2: Alpha sort, ignore case\nout, _, _ = run('sample.txt', '--ignore-case', '--sort', 'alpha', '--top', '3')\nlines = out.strip().split('\\n')\ncheck('alpha first', lines[0].split(':')[0].strip(), 'and')\ncheck('alpha second', lines[1].split(':')[0].strip(), 'are')\ncheck('alpha third', lines[2].split(':')[0].strip(), 'at')\n\n# Test 3: Min length filter\nout, _, _ = run('sample.txt', '--ignore-case', '--min-length', '5', '--sort', 'freq')\nlines = [l for l in out.strip().split('\\n') if l.strip()]\n# No word shorter than 5 chars should appear\nfor line in lines:\n    word = line.split(':')[0].strip()\n    check(f'min-length {word}', str(len(word) >= 5), 'True')\n\n# Test 4: File not found\n_, err, code = run('nonexistent.txt')\ncheck('not found exit', str(code), '1')\ncheck('not found msg', str('not found' in err.lower()), 'True')\n\n# Test 5: Case sensitivity (without --ignore-case)\nout, _, _ = run('sample.txt', '--sort', 'alpha', '--top', '3')\nlines = out.strip().split('\\n')\n# 'Quick' and 'quick' should be separate\ncheck('case sensitive', str(any('Quick' in l for l in out.split('\\n'))), 'True')\n\n# Test 6: Default (no flags except file)\nout, _, code = run('sample.txt')\ncheck('default exit', str(code), '0')\ncheck('default has output', str(len(out) > 0), 'True')\n\nprint(f\"{passed}/{passed+failed} tests passed\")\nif failed > 0:\n    sys.exit(1)\n"
  },
  "verify": "cd $BENCH_WORK_DIR && python3 test_wordstats.py",
  "timeout": 240000,
  "tags": ["code-generation", "python", "cli", "from-spec"]
}
