npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

uluka

v2.1.0

Published

Security Evaluation CLI - Verify that code does what it claims to do

Readme

Uluka

Security Claim Verification CLI — Verify that code does what it claims to do

Uluka is the only tool that verifies security claims match reality. It extracts security claims from code comments, README files, JSDoc, and function signatures, then verifies them against the actual implementation. It complements tools like Semgrep and CodeQL by importing their findings and adding claim verification on top.

Features

  • Claim Detection — Discovers security claims in code comments, README, JSDoc, and function names across JavaScript, TypeScript, Python, Java, and more
  • Automatic Claim Discovery — Infers security claims from function names (authenticate*, encrypt*) and middleware patterns (helmet, cors, rateLimit)
  • Evidence-Based Verification — Validates claims using deterministic rule-based verifiers including encryption, authentication, input validation, and more
  • SARIF Import — Import findings from Semgrep, CodeQL, Gitleaks, and any SARIF 2.1.0 tool via --import or stdin piping
  • Multi-Tool Correlation — Cross-references findings across tools with confidence boosting when multiple tools agree
  • LLM-Powered Analysis — Optional Claude integration for nuanced claim reasoning and catch-all verification
  • Multi-Language Support — Works with JavaScript, TypeScript, Python, Java, Go, Ruby, PHP, C#, and more
  • Flexible Output — Terminal-friendly text with source badges, JSON with source breakdowns, or multi-run SARIF for security dashboards
  • Configurable Rules — Customize severity levels, disable specific rules, configure trusted sources, and control verification behavior via .ulukarc
  • Input Validation Verifier — Detects Zod, Joi, express-validator, and class-validator with route-to-validation linking
  • Cross-File Data Flow Analysis — Traces tainted user input (req.body, req.params, req.query) across module boundaries to security-sensitive sinks (db.query, eval, exec) with sanitizer-aware filtering
  • Incremental Analysis — Content-hash caching via --incremental flag for fast re-analysis of large codebases; only changed files are re-analyzed
  • Claude Code Hooks — Native hook integration for post-tool-use scanning and pre-commit blocking via uluka hook scan and uluka hook pre-commit

Installation

Global Installation (recommended for CLI usage)

npm install -g uluka

Local Installation (for project-specific usage)

npm install --save-dev uluka

Requirements

  • Node.js >= 18.0.0

Quick Start

Scan for Security Claims

uluka scan src/

Discovers all security-related claims in your codebase:

Found 5 security claims:
  - Encryption: "uses AES-256-GCM encryption" (src/auth/encrypt.ts:12)
  - Authentication: "requires JWT with RS256" (src/api/middleware.ts:34)
  - Authorization: "admin-only endpoint" (src/api/admin.ts:8)

Verify Claims Against Implementation

uluka verify src/

Validates each claim and shows verification status:

Verification Results:
  ✓ Encryption claim verified (found crypto.createCipheriv with aes-256-gcm)
  ✓ Authentication claim verified (JWT signature validation with RS256 present)
  ✗ Authorization claim FAILED (no role check found before handler execution)

Ecosystem Integration

Uluka works best alongside existing security tools, not as a replacement.

Import Semgrep Results

semgrep --sarif -o semgrep.sarif .
uluka verify src/ --import semgrep.sarif

Import CodeQL Results

codeql database analyze db --format=sarif-latest --output=codeql.sarif
uluka verify src/ --import codeql.sarif

Pipe via stdin

semgrep --sarif . | uluka verify src/ --import -

Import Multiple Tools

uluka verify src/ --import semgrep.sarif --import codeql.sarif

Import-Only Mode

uluka verify --import-only --import semgrep.sarif --format sarif

Imported findings appear with source badges in terminal output (e.g., [semgrep], [codeql]) and as separate runs in SARIF output.

Data Flow Analysis

Uluka traces tainted user input through your codebase to detect unsanitized data reaching security-sensitive sinks.

What It Detects

  • Taint sources: req.body, req.params, req.query, req.headers
  • Sinks: db.query, eval, exec, fs.readFile, res.send, innerHTML
  • Cross-file flows: Tainted data passed to imported functions that contain sinks
  • Sanitizer awareness: Flows through Zod .parse(), Joi .validate(), express-validator are not flagged

Example

uluka verify src/
✗ Unsanitized data flow detected
  Source: req.body.id (handler.ts:5)
  Sink: db.query (database.ts:12)
  Severity: high
  Remediation: Validate or sanitize user input before passing to db.query

Incremental Analysis

For large codebases, use the --incremental flag to cache results and only re-analyze changed files.

# First run: full analysis, results cached
uluka verify src/ --incremental

# Second run: only changed files re-analyzed
uluka verify src/ --incremental

# Clear the cache
uluka cache clear

# Check cache status
uluka cache status

Cache uses SHA-256 content hashing (not timestamps) and validates integrity on read. Configure the cache directory in .ulukarc:

cache:
  directory: .uluka-cache  # default

Claude Code Hooks

Uluka integrates with Claude Code as a post-tool-use hook or pre-commit hook.

Post-Tool-Use Hook

Add to .claude/settings.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "uluka hook scan --files $FILEPATH"
          }
        ]
      }
    ]
  }
}

Pre-Commit Hook

uluka hook pre-commit

Blocks commits with critical security findings. Use --force to report findings without blocking.

Output Format

Hook output is structured JSON (no ANSI colors) for machine consumption:

{
  "summary": {
    "filesScanned": 3,
    "findingsCount": 1,
    "criticalCount": 0,
    "highCount": 1
  },
  "findings": [...],
  "warnings": []
}

See docs/hooks.md for complete setup guide.

Configure Trusted Sources

In .ulukarc:

integrations:
  trustedSources:
    - semgrep
    - codeql
    - gitleaks
  imports:
    - path: ./reports/semgrep.sarif
      tool: semgrep

Confidence Filtering

Filter findings by confidence level:

uluka verify src/ --min-confidence high

When multiple tools report the same finding, confidence is automatically boosted.

CLI Commands

uluka scan [path]

Scan project for security claims in code comments.

Arguments:

  • path — Directory or file to scan (default: current directory)

Options:

  • --format <type> — Output format: terminal (default), json, or sarif
  • --severity <level> — Filter by severity: error, warning, or info
  • --output <file> — Write results to file instead of stdout
  • --config <path> — Path to custom config file
  • --import <file> — Import SARIF file (repeatable)
  • --min-confidence <level> — Filter by confidence: high, medium, or low
  • --verbose — Show detailed claim metadata and locations
  • --quiet — Minimal output (errors only)

Examples:

# Scan current directory
uluka scan

# Scan specific directory with JSON output
uluka scan src/ --format json

# Save results to SARIF file for security tools
uluka scan . --format sarif --output uluka-report.sarif

# Show only high-severity findings
uluka scan --severity error

uluka verify [path]

Verify security claims against code implementation.

Arguments:

  • path — Directory or file to verify (default: current directory)

Options:

  • --llm — Enable Claude-powered verification (requires ANTHROPIC_API_KEY)
  • --format <type> — Output format: terminal (default), json, or sarif
  • --severity <level> — Filter by severity: error, warning, or info
  • --output <file> — Write results to file instead of stdout
  • --config <path> — Path to custom config file
  • --import <file> — Import SARIF file (repeatable)
  • --import-only — Only process imported findings, skip native scanning
  • --min-confidence <level> — Filter by confidence: high, medium, or low
  • --verbose — Show verification evidence and LLM insights
  • --quiet — Minimal output (errors only)
  • --incremental — Use cached results, only re-analyze changed files
  • --cache-dir <path> — Custom cache directory path

Examples:

# Verify claims in current directory
uluka verify

# Enable LLM-powered verification
export ANTHROPIC_API_KEY="sk-ant-..."
uluka verify --llm

# Verify with detailed evidence
uluka verify src/ --verbose

# Generate JSON report for CI/CD
uluka verify . --format json --output verification-report.json

uluka init

Create a .ulukarc configuration file via interactive wizard.

Options:

  • --yes — Skip confirmation prompts (use defaults)

Example:

uluka init

Guides you through configuring:

  • LLM verification settings
  • Rule severity customization
  • API key storage preferences
  • Output format defaults

uluka config validate

Validate .ulukarc configuration file syntax and schema.

Example:

uluka config validate

Checks for:

  • Valid YAML/JSON syntax
  • Required fields present
  • Correct data types
  • Valid enum values

uluka cache clear

Clear the incremental analysis cache.

Example:

uluka cache clear

uluka cache status

Show cache statistics (file count, total size, directory).

Example:

uluka cache status

uluka hook scan [path]

Scan files and output structured JSON for hook consumption.

Options:

  • --files <paths...> — Specific files to scan
  • --incremental — Use cached results for unchanged files
  • --cache-dir <path> — Custom cache directory path

Example:

uluka hook scan src/ --files src/auth.ts src/db.ts

uluka hook pre-commit [path]

Pre-commit hook that blocks on critical findings.

Options:

  • --force — Report findings but do not block commit

Example:

uluka hook pre-commit

LLM-Powered Verification

Uluka can optionally use Claude (Anthropic's AI) for nuanced claim analysis and verification of complex security properties that are difficult to verify with deterministic rules alone.

How to Enable

Use the --llm flag with the verify command:

uluka verify --llm

API Key Requirement

LLM verification requires an Anthropic API key. Set the ANTHROPIC_API_KEY environment variable:

export ANTHROPIC_API_KEY="sk-ant-api03-..."

Where to get an API key:

  1. Visit the Anthropic Console
  2. Sign up or log in
  3. Navigate to API Keys section
  4. Create a new API key

Alternatively, store your API key in .ulukarc (see Configuration section below).

Cost Considerations

LLM verification is opt-in via the --llm flag. Without this flag, Uluka uses only deterministic rule-based verifiers with zero API costs.

When enabled:

  • Deterministic verifiers run first (free, instant)
  • LLM provides supplemental insights for rule-verified claims
  • LLM handles claims that don't match any deterministic verifier
  • Typical cost: $0.01-0.05 per medium-sized file analyzed

How It Works

  1. Deterministic-first approach: Rule-based verifiers (EncryptionVerifier, AuthVerifier, etc.) run first and are the source of truth
  2. Supplemental insights: LLM reviews rule-verified claims and provides additional context or warnings
  3. Catch-all verification: Claims that don't match any rule-based verifier are analyzed by the LLM
  4. Graceful degradation: If LLM times out or fails, rule-based results are still returned with a warning

Example output with --llm --verbose:

✓ Encryption claim verified
  Evidence: crypto.createCipheriv('aes-256-gcm', key, iv)
  LLM Insight: Verified AES-256-GCM usage. Note: IV generation appears deterministic
               (line 45). Consider using crypto.randomBytes() for each encryption.

Configuration

Uluka looks for configuration in .ulukarc, uluka.config.yml, or uluka.config.json in your project root.

Example Configuration (YAML)

# .ulukarc or uluka.config.yml
anthropicApiKey: "sk-ant-api03-..."  # Optional if env var is set

llm:
  enabled: false                      # Default: false (opt-in via --llm flag)
  timeout: 30000                      # Timeout in milliseconds (30 seconds)

rules:
  disabled: []                        # List of rule IDs to disable
  severity:
    hardcoded-secret: error           # Override severity for specific rules
    weak-crypto: warning
    missing-auth: error

output:
  format: terminal                    # Default output format
  verbose: false                      # Show detailed evidence by default

integrations:
  trustedSources:                     # Tools whose findings are fully trusted
    - semgrep
    - codeql
  imports:                            # Auto-import these SARIF files on every run
    - path: ./reports/semgrep.sarif
      tool: semgrep

discovery:
  enabled: true                       # Enable automatic claim discovery
  minConfidence: medium               # Minimum confidence for discovered claims

Example Configuration (JSON)

{
  "anthropicApiKey": "sk-ant-api03-...",
  "llm": {
    "enabled": false,
    "timeout": 30000
  },
  "rules": {
    "disabled": [],
    "severity": {
      "hardcoded-secret": "error",
      "weak-crypto": "warning"
    }
  },
  "output": {
    "format": "terminal",
    "verbose": false
  }
}

Configuration Precedence

Settings are resolved in this order (highest priority first):

  1. CLI flags--llm, --format, --severity, etc.
  2. .ulukarc file — Project-specific configuration
  3. Environment variablesANTHROPIC_API_KEY
  4. Defaults — Built-in sensible defaults

Example: If .ulukarc sets format: json but you run uluka verify --format terminal, the CLI flag wins and output will be in terminal format.

Generating Configuration

Use the interactive wizard to create a config file:

uluka init

This guides you through all options and creates a validated .ulukarc file.

Programmatic Usage

Uluka can be used as a library in your Node.js or TypeScript projects.

Basic Example

import { VerificationEngine, type Claim, type UlukaConfig } from 'uluka';

const config: UlukaConfig = {
  llm: { enabled: false }
};

const engine = new VerificationEngine(config);

const claim: Claim = {
  type: 'encryption',
  description: 'uses AES-256-GCM encryption',
  location: {
    file: 'src/auth.ts',
    line: 42,
    column: 5
  },
  metadata: {}
};

const result = await engine.verify(claim);

console.log(result.status);        // 'verified' | 'failed' | 'inconclusive'
console.log(result.evidence);      // Array of evidence objects
console.log(result.llmInsight);    // Optional LLM supplemental analysis

TypeScript Type Definitions

Uluka includes full TypeScript type definitions. Key types:

import type {
  Claim,
  VerifiedClaim,
  VerificationStatus,
  CodeLocation,
  UlukaConfig,
  ValidatedConfig,
  VerificationReport,
  Finding
} from 'uluka';

Advanced Usage

import { ClaimVerifier, ConfigSchema } from 'uluka';

// Validate config with Zod schema
const validatedConfig = ConfigSchema.parse(rawConfig);

// Create custom verifier
const verifier = new ClaimVerifier(validatedConfig);
const claims = [/* ... */];

for (const claim of claims) {
  const verified = await verifier.verify(claim);
  // Handle result...
}

Examples

Example 1: Verifying Encryption Claims

Code with security claim:

/**
 * Encrypts user data before storage.
 * @security-claim encryption: "uses AES-256-GCM encryption"
 */
export async function encryptData(data: string): Promise<Buffer> {
  const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
  return Buffer.concat([cipher.update(data, 'utf8'), cipher.final()]);
}

Verification result:

$ uluka verify src/encryption.ts --verbose

✓ Encryption claim verified
  Location: src/encryption.ts:12
  Evidence:
    - Found crypto.createCipheriv call at line 14
    - Algorithm: aes-256-gcm (matches claim)
    - Key size: 256 bits (verified)

Example 2: Catching Broken Authentication

Code with outdated claim:

/**
 * Protected admin endpoint.
 * @security-claim authentication: "requires JWT with RS256 signature"
 */
app.post('/admin/users', (req, res) => {
  // TODO: Add auth middleware
  const users = db.getAllUsers();
  res.json(users);
});

Verification result:

$ uluka verify src/api.ts

✗ Authentication claim FAILED
  Location: src/api.ts:8
  Issue: No JWT verification found in request handler or middleware chain
  Severity: error

Example 3: LLM-Powered Insight

Code with complex security claim:

/**
 * @security-claim authorization: "enforces RBAC with hierarchical permissions"
 */
function checkPermission(user: User, resource: string): boolean {
  return user.roles.some(role =>
    permissions[role]?.includes(resource)
  );
}

Verification result with LLM:

$ uluka verify src/auth.ts --llm --verbose

✓ Authorization claim verified
  Evidence: Role-based access check found with permissions lookup
  LLM Insight: RBAC implementation found, but hierarchical permission inheritance
               is not implemented. Current logic only checks direct role-to-resource
               mappings without parent role resolution.

License

MIT License

Copyright (c) 2026 Uluka Contributors

See LICENSE file for full license text.

Contributing

Contributions are welcome! Please:

  1. Open an issue to discuss significant changes
  2. Ensure all tests pass: npm test
  3. Follow existing code style and patterns
  4. Add tests for new features

Support

  • Issues: GitHub Issues
  • Documentation: This README and inline TypeScript types
  • API Reference: Generated TypeScript declarations in dist/index.d.ts

Built with TypeScript, powered by Claude AI (optional), designed for security-conscious developers.