Skip to content

Configuration

The unentropy.json file configures which metrics to track, storage options, and quality gate thresholds. This reference covers all configuration options.

Place unentropy.json in your project root directory:

my-project/
├── unentropy.json
├── package.json
└── src/
{
  "metrics": {
    "metric-id": {
      "type": "numeric",
      "command": "echo 42"
    }
  },
  "storage": {
    "type": "sqlite-artifact"
  },
  "qualityGate": {
    "mode": "soft",
    "thresholds": []
  }
}

The metrics object defines which metrics to track. Each key is a unique metric identifier.

{
  "metrics": {
    "coverage": {
      "$ref": "coverage",
      "name": "Test Coverage",
      "description": "Percentage of code covered by tests",
      "command": "@collect coverage-lcov ./coverage/lcov.info",
      "unit": "percent"
    }
  }
}

Type: string
Required: Yes
Pattern: ^[a-z0-9-]+$ (lowercase alphanumeric with hyphens)
Length: 1-64 characters

The object key serves as the unique metric identifier. Used in:

  • Database storage
  • Quality gate threshold references
  • Report displays

Examples: coverage, bundle-size, test-loc

Type: string
Required: No

Reference a built-in metric template. Inherits default properties like description, unit, and command.

{
  "loc": {
    "$ref": "loc"
  }
}

Available templates:

  • coverage - Test coverage percentage (supports --type line|branch|function)
  • loc - Lines of code
  • size - File/bundle size
  • build-time - Build duration
  • test-time - Test duration
  • dependencies-count - Dependency count

See Metrics Guide for details.

Type: string
Required: No
Max length: 256 characters

Display name for reports and charts. Defaults to the metric ID if omitted.

{
  "frontend-loc": {
    "$ref": "loc",
    "name": "Frontend Code Lines"
  }
}

Type: "numeric" or "label"
Required: Yes (unless using $ref)

Determines how values are stored and visualized:

  • numeric: Parsed as numbers, displayed as line charts
  • label: Stored as strings, displayed as bar charts
{
  "coverage": {
    "type": "numeric",
    "command": "@collect coverage-lcov ./coverage/lcov.info"
  },
  "status": {
    "type": "label",
    "command": "echo healthy"
  }
}

Type: string
Required: No
Max length: 256 characters

Human-readable explanation shown in reports.

{
  "bundle": {
    "$ref": "size",
    "description": "Production build size for main bundle"
  }
}

Type: string
Required: Yes
Max length: 1024 characters

Shell command to execute for collecting this metric. The command’s stdout is captured and parsed based on the metric type.

{
  "coverage": {
    "type": "numeric",
    "command": "@collect coverage-lcov ./coverage/lcov.info"
  },
  "api-count": {
    "type": "numeric",
    "command": "grep -r 'export function' src/api | wc -l"
  }
}

@collect shortcuts (faster, in-process execution):

  • @collect loc <path> - Count lines of code
  • @collect size <path> - Calculate file size
  • @collect coverage-lcov <path> [--type line|branch|function] - Extract LCOV coverage
  • @collect coverage-clover <paths...> [--type line|branch|function] - Extract and merge Clover XML coverage
  • @collect coverage-cobertura <paths...> [--type line|branch|function] - Extract and merge Cobertura XML coverage

Type: string
Required: No
Max length: 10 characters

Display unit for numeric metrics. Used for formatting in reports.

Valid units:

  • percent - Displays as 87.5%
  • integer - Displays as 1,234
  • bytes - Displays as 1.5 MB (auto-scales)
  • duration - Displays as 1m 30s (auto-scales)
  • decimal - Displays as 3.14
{
  "coverage": {
    "type": "numeric",
    "command": "@collect coverage-lcov ./coverage/lcov.info",
    "unit": "percent"
  }
}
  • Minimum metrics: 1
  • Maximum metrics: 50
  • Metric ID length: 1-64 characters
  • Command timeout: 30 seconds (configurable per-metric)

Commands run with these environment variables:

VariableDescriptionExample
UNENTROPY_COMMIT_SHACurrent git commita3f5c2b...
UNENTROPY_BRANCHCurrent git branchmain
UNENTROPY_RUN_IDGitHub Actions run ID1234567890
UNENTROPY_RUN_NUMBERGitHub Actions run number42
UNENTROPY_ACTORUser who triggered rundependabot[bot]
UNENTROPY_METRIC_KEYCurrent metric IDcoverage
UNENTROPY_METRIC_TYPECurrent metric typenumeric

Execution rules:

  • Runs in repository root directory
  • Uses /bin/sh shell environment
  • Stdout is captured and parsed
  • Stderr is logged (doesn’t fail metric)
  • Exit code ignored (only output matters)

Configure where metrics data is stored.

{
  "storage": {
    "type": "sqlite-artifact"
  }
}

Or omit the storage block entirely—artifact storage is the default.

Options:

{
  "storage": {
    "type": "sqlite-artifact",
    "artifactName": "unentropy-metrics",
    "branch": "main"
  }
}
  • artifactName: Artifact name (default: unentropy-metrics)
  • branch: Branch to search (default: current branch)
{
  "storage": {
    "type": "sqlite-s3"
  }
}

S3 credentials are provided as GitHub Action inputs, not in the config file:

- uses: unentropy/track-metrics-action@v1
  with:
    s3-endpoint: ${{ secrets.S3_ENDPOINT }}
    s3-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
    s3-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}
    s3-bucket: my-metrics-bucket
    s3-region: us-east-1

See Storage Guide for setup details.

{
  "storage": {
    "type": "sqlite-local"
  }
}

Database stored at ./unentropy.db in your project directory. Use for local development only (doesn’t persist in CI).

Configure thresholds to enforce on pull requests.

{
  "qualityGate": {
    "mode": "soft",
    "thresholds": [
      {
        "metric": "coverage",
        "mode": "min",
        "target": 80
      }
    ]
  }
}

Controls how threshold violations are handled:

{
  "qualityGate": {
    "mode": "soft"
  }
}

Modes:

  • off - Disabled (no evaluation)
  • soft - Evaluates and posts comments, never fails build (default)
  • hard - Fails build when thresholds violated

Array of threshold rules for metrics:

{
  "qualityGate": {
    "thresholds": [
      {
        "metric": "coverage",
        "mode": "min",
        "target": 80
      },
      {
        "metric": "bundle",
        "mode": "max",
        "target": 500000
      },
      {
        "metric": "loc",
        "mode": "no-regression"
      }
    ]
  }
}

Type: string
Required: Yes

Metric ID to evaluate. Must match a metric key in the metrics object.

Type: string
Required: Yes

Comparison mode:

  • min - Metric must not drop below target
  • max - Metric must not exceed target
  • no-regression - Metric must not decrease from baseline
  • delta-max-drop - Metric can increase, but not more than maxDropPercent percentage

Type: number
Required: Yes (for min and max modes)

Threshold value. Meaning depends on mode:

  • min / max: Absolute value

Not used for no-regression or delta-max-drop modes.

Type: number
Required: Yes (only for delta-max-drop mode)

Maximum allowed percentage increase (e.g., 5 = 5% max increase).

{
  "metric": "bundle",
  "mode": "delta-max-drop",
  "maxDropPercent": 5
}

See Quality Gates Guide for examples.

Configure the appearance and layout of generated HTML reports.

Control the visual appearance of your reports with built-in themes or custom palettes.

Type: string | object
Default: "lattice"

Select a built-in palette or provide custom color overrides.

Built-in palettes:

ValueDescription
"lattice"Cool blue accent (default)
"flux"Warm amber accent
"halftone"Purple accent
"specimen"Green accent

Custom palette (object with dark and/or light keys):

{
  "report": {
    "theme": {
      "dark": { "--accent": "#ff00ff" },
      "light": { "--accent": "#aa00aa" }
    }
  }
}

Available CSS variables for custom palettes:

VariableUsed for
--bgPage background
--surfaceCard backgrounds
--surface-cardElevated card surfaces
--borderDefault borders
--border-softSubtle dividers
--textPrimary text
--text-dimSecondary text
--text-mutedPlaceholder/disabled text
--accentHighlights and links
--upPositive trend indicators
--downNegative trend indicators
--warnWarning states

Each value must be a 7-character hex color (e.g., #1c2230). Omitted variables fall back to Lattice defaults.

Type: "auto" | "light" | "dark"
Default: "auto"

Control how the report selects between light and dark palettes.

ValueBehavior
"auto"Emits both palettes; prefers-color-scheme selects at runtime
"light"Locks to light palette; emits only light CSS variables
"dark"Locks to dark palette; emits only dark CSS variables
{
  "report": {
    "theme": "flux",
    "mode": "dark"
  }
}

Organize metrics into named sections and combine related metrics on a single chart.

Type: SectionConfig[]
Required: No

Define named, visually separated groups of charts. When absent, the report uses a flat layout with all metrics displayed in definition order.

Each section contains:

{
  "report": {
    "sections": [
      {
        "name": "Code Size",
        "description": "Source code metrics by language",
        "charts": [
          { "metrics": "typescript-loc" },
          { "metrics": "javascript-loc" }
        ]
      }
    ]
  }
}
FieldTypeRequiredDescription
namestringYesSection header text (max 256 characters)
descriptionstringNoSubtitle shown below the header
chartsChartConfig[]YesCharts to render, in display order
FieldTypeRequiredDescription
metricsstring | string[]YesMetric ID(s) to plot. Array plots multiple metrics on one chart.
titlestringNoCustom chart title. Defaults to metric name(s) when omitted.

Single-metric chart:

{ "metrics": "bundle-size", "title": "Production Bundle Size" }

Multi-metric chart:

{ "metrics": ["modern-classes", "legacy-classes"], "title": "Modern vs Legacy" }

Metrics with different units or scales automatically receive dual Y-axes. A legend identifies each series and can be clicked to toggle visibility.

  • Unknown theme string → warning logged, falls back to "lattice"
  • Custom theme with partial variables → missing variables filled from Lattice defaults
  • Invalid mode value → validation error at config load time
  • Invalid hex format in custom theme → validation error at config load time
  • Empty sections array → validation error (remove the block or define at least one section)
  • Unknown metrics references in charts → silently omitted from the report
  • Metrics not referenced in any chart → omitted from the report with no warning
{
  "metrics": {
    "coverage": {
      "$ref": "coverage",
      "name": "Test Coverage",
      "description": "Overall test coverage percentage",
      "command": "@collect coverage-lcov ./coverage/lcov.info"
    },
    "src-loc": {
      "$ref": "loc",
      "name": "Source Code Lines",
      "command": "@collect loc ./src --language TypeScript"
    },
    "test-loc": {
      "$ref": "loc",
      "name": "Test Code Lines",
      "command": "@collect loc ./tests"
    },
    "bundle": {
      "$ref": "size",
      "name": "Production Bundle",
      "command": "@collect size ./dist/**/*.js"
    },
    "api-endpoints": {
      "type": "numeric",
      "name": "API Endpoints",
      "description": "Number of exported API functions",
      "command": "grep -r 'export.*function' src/api | wc -l",
      "unit": "integer"
    }
  },
  "storage": {
    "type": "sqlite-artifact"
  },
  "qualityGate": {
    "mode": "soft",
    "thresholds": [
      {
        "metric": "coverage",
        "mode": "min",
        "target": 80
      },
      {
        "metric": "bundle",
        "mode": "delta-max-drop",
        "maxDropPercent": 5
      },
      {
        "metric": "src-loc",
        "mode": "no-regression"
      }
    ]
  },
  "report": {
    "theme": "specimen",
    "mode": "auto",
    "sections": [
      {
        "name": "Code Size",
        "description": "Source code and build artifact metrics",
        "charts": [
          { "metrics": ["src-loc", "test-loc"], "title": "Lines of Code" },
          { "metrics": "bundle", "title": "Production Bundle Size" }
        ]
      },
      {
        "name": "Quality",
        "charts": [
          { "metrics": "coverage" },
          { "metrics": "api-endpoints" }
        ]
      }
    ]
  }
}

Validate your configuration locally:

bunx unentropy verify

Common validation errors:

Error: Invalid metric key "Test-Coverage"
Keys must be lowercase with hyphens only (pattern: ^[a-z0-9-]+$)
Example: test-coverage
Error in metric "coverage": type must be either 'numeric' or 'label'
Found: 'percentage'
Error in metric "test-coverage": command cannot be empty
Provide a shell command that outputs the metric value
Error in metric "test-coverage": missing required fields
Required: type, command
Found: type
Error: report.sections cannot be empty
Remove the report block or define at least one section
Error: Section "Code Size" has no charts
Each section must contain at least one chart
Error: mode must be one of: auto, light, dark
Found: "system"
Error: theme values must be 7-character hex (e.g. #1c2230)
Found: "#ff00f" at report.theme.dark.--accent