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

@cisco_open/linting-reports

v1.0.0-rc.5

Published

Persistent storage and web UI for lint job results. The linting reporting service (spectifyr) receives notifications from the linting orchestrator, stores them in SQLite, and exposes a browsable web UI.

Downloads

190

Readme

Linting Reporting Service (spectifyr)

Package: @cisco_open/linting-reports Binary: spectifyr

The linting reporting service stores lint job results produced by the linting orchestrator and exposes them through a browsable web UI. Linting Reports is the user-facing label of this service; on the command line and in configuration, it is named spectifyr.

What is the linting reporting service?

The linting reporting service (spectifyr) is a standalone companion to the linting orchestrator that provides:

  • Persistent Storage: Job results survive orchestrator restarts
  • Web UI: Browse and search lint results in your browser
  • Independent Operation: Can be stopped/started without affecting the orchestrator
  • Production-Ready: Never lose reports with local backup and retry logic

Features

  • ✅ HTTP API for receiving job notifications from the linting orchestrator
  • ✅ SQLite database for persistent storage
  • ✅ API key authentication (Bearer token)
  • ✅ Job listing with filtering and pagination
  • ✅ Detailed job results API
  • ✅ Health check endpoint with version info
  • Web UI - Browse reports in your browser (Phase 3)
  • Manual cleanup CLI - Delete old reports (Phase 4)
  • ✅ Reusable TypeScript client library with retry logic
  • ✅ Runtime version compatibility checking
  • ✅ Payload validation before sending
  • 🚧 PostgreSQL support (future)
  • 🚧 Charts and trends (future)

Project Structure

This is a monorepo containing both the reports service server and a reusable TypeScript client library for integrating with it:

linting-reports/
├── src/
│   ├── server/               # spectifyr HTTP server
│   ├── client/               # Reusable TypeScript client library
│   │   └── CHANGELOG.md      # Detailed client library changelog
│   └── types.ts              # Shared TypeScript types
├── docs/
│   ├── SPECTIFYR_ARCHITECTURE.md
│   └── VERSIONING_STRATEGY.md
├── CHANGELOG.md              # Server changelog (references client)
├── package.json              # Dual versions (server + client)
└── README.md                 # This file

Versioning & Changelogs

We use dual versioning to independently track server and client library versions:

  • Server Version: package.jsonversion field (e.g., 0.2.2)

    • Changes tracked in root CHANGELOG.md
    • Server-specific features (endpoints, database, health checks)
  • Client Library Version: package.jsonclientVersion field (e.g., 1.0.0)

Where to Find What:

This allows the server to evolve (adding endpoints, database changes) without forcing client library version bumps when the client API hasn't changed.

Quick Start

Development Mode (Recommended for Local Testing)

# Install dependencies
npm install

# Build the project
npm run build

# Start in development mode (no configuration needed)
npm run dev

Development mode runs with sensible defaults:

  • ✅ Auto-generates API key (with warning)
  • ✅ Local database: ./reports.db
  • ✅ Human-readable logs
  • ✅ Port 3010

Access at http://localhost:3010

Production Mode

1. Create .env file:

cp .env.example .env

2. Edit .env and set your API key:

# Required
SPECTIFYR_API_KEY=your-secure-production-key

# Optional (production defaults shown)
SPECTIFYR_PORT=3010
SPECTIFYR_HOST=0.0.0.0
SPECTIFYR_DB_PATH=~/.spectify/reports/database/reports.db
LOG_LEVEL=info
LOG_FORMAT=pretty  # or 'json' for structured logs

3. Build and start:

npm run build
npm start

Production mode validates all configuration and fails fast if misconfigured.

Configuration via .env File (Recommended)

Create a .env file in the project root:

# .env - Report Service Configuration

# Required: API key for authentication
SPECTIFYR_API_KEY=your-secret-key-here

# Optional: Server configuration (defaults shown)
SPECTIFYR_PORT=3010
SPECTIFYR_HOST=0.0.0.0

# Optional: Database location
# Development default: ./reports.db
# Production default: ~/.spectify/reports/database/reports.db
SPECTIFYR_DB_PATH=~/.spectify/reports/database/reports.db

# Optional: Logging
LOG_LEVEL=info            # debug, info, warn, error
LOG_FORMAT=pretty         # 'pretty' (human-readable) or 'json' (structured)

Environment Variables

Alternatively, use environment variables:

export SPECTIFYR_API_KEY=your-secret-key-here
export SPECTIFYR_PORT=3010
export SPECTIFYR_DB_PATH=~/.spectify/reports/database/reports.db
npm start

Configure the linting orchestrator

In the orchestrator's configuration:

# config.yaml
reportService:
  enabled: true
  url: 'http://localhost:3010'
  apiKey: ${SPECTIFYR_API_KEY}
  retries: 3
  pendingDir: './pending-reports'

Or with environment variables:

export SPECTIFYR_URL=http://localhost:3010
export SPECTIFYR_API_KEY=your-secret-key-here

Usage

Web UI

Navigate to http://localhost:3010 in your browser to:

  • View recent lint jobs
  • Search by document name or organization
  • Filter by status, ruleset, or date range
  • View detailed results for each job
  • See per-ruleset breakdown

API

POST /reports/jobs

Receive job completion notification from the linting orchestrator (authenticated).

curl -X POST http://localhost:3010/reports/jobs \
  -H "Authorization: Bearer your-secret-key" \
  -H "Content-Type: application/json" \
  -d @job-notification.json

GET /jobs

List all jobs (paginated).

curl http://localhost:3010/jobs?limit=50&offset=0

GET /jobs/:jobId

Get detailed results for specific job.

curl http://localhost:3010/jobs/abc123

Cleanup

Delete reports older than N days:

# Dry run (shows what would be deleted)
npm run cleanup -- --days 90 --dry-run

# Actually delete
npm run cleanup -- --days 90

Architecture

The linting reporting service is designed as an independent companion to the linting orchestrator:

┌──────────────────┐                  ┌──────────────────┐
│  spectifyd       │ ───────────────> │  spectifyr       │
│  (orchestrator)  │  HTTP POST       │  (reports)       │
│  port 3003       │  notifications   │  port 3010       │
└──────────────────┘  (fire-and-forget)        │
                                               │
                                               v
                                        ┌─────────────┐
                                        │   SQLite    │
                                        │  Database   │
                                        └─────────────┘

Communication Pattern:

  • Fire-and-forget HTTP POST notifications
  • 3 retry attempts with exponential backoff (1s, 2s, 4s)
  • If all retries fail, the orchestrator stores the notification locally
  • Background job retries pending notifications every 5 minutes
  • Never lose production reports

Deployment

Docker

# Build image
docker build -t linting-reports:latest .

# Run container
docker run -d \
  -p 3010:3010 \
  -v $(pwd)/reports.db:/app/reports.db \
  -e SPECTIFYR_API_KEY=your-secret-key \
  linting-reports:latest

Docker Compose

See examples/docker-compose.yml for running the linting orchestrator and the linting reporting service together.

Systemd

See examples/spectifyr.service for systemd configuration.

Development

# Install dependencies
npm install

# Build TypeScript
npm run build

# Run tests
npm test

# Development mode (auto-reload)
npm run dev

# Type checking
npm run typecheck

Documentation

Configuration Options

| Environment Variable | Default | Description | |---------------------|---------|-------------| | PORT | 3010 | HTTP server port | | HOST | 0.0.0.0 | Bind address | | DATABASE_PATH | ./reports.db | SQLite database file | | SPECTIFYR_API_KEY | (required) | API key for authentication | | LOG_LEVEL | info | Logging level (debug, info, warn, error) | | LOG_FORMAT | pretty | Log format (json for JSON, anything else for human-readable) |

License

See LICENSE

Related Projects

Contributing

See CONTRIBUTING.md

Support