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

tonofcov

v0.0.58

Published

Source-line code coverage for TON smart contracts (FunC, Tolk planned). HTML report, conditional-throw branch coverage, agent-friendly gaps listing, and LCOV output for IDEs and CI.

Downloads

83

Readme

tonofcov (TON of Coverage)

Source-line code coverage for TON smart contracts, with first-class branch coverage on conditional throws (throw_if / throw_unless / throw_arg_*) — the most audit-relevant signal in FunC - see exactly which error paths your tests never triggered.

Works with @ton/sandbox + Jest. Outputs:

  • coverage/gaps.md + gaps.json — structured listing of uncovered functions, one-sided throws, and uncovered ranges with per-entry source snippets and AST context. Designed as input for LLM-driven test-writing loops: feed it to an agent and have it iteratively close coverage gaps. No other TON coverage tool produces this.
  • coverage/html/index.html — built-in self-contained HTML report with syntax highlighting, gutter bars, multi-line throw classification, and a dedicated conditional-throws branch-coverage column.
  • coverage/lcov.info — standard LCOV consumable by:
    • VSCodeCoverage Gutters extension (green/red markers in the gutter)
    • JetBrains IDEs — native Run > Show Coverage Data (IntelliJ, WebStorm, etc.)
    • Codecov / Coveralls — drop into CI, get PR coverage-diff comments
    • genhtml — standalone HTML report

Status

Functional for FunC. Tolk support is planned once the Tolk compiler exposes structured debug-info (it currently only emits Fift line-comments). Tact is out of scope — different coverage story, different tool.

| Language | Status | Notes | |---|---|---| | FunC | working | Own WASM build with debugger extensions (tonofcov-func-bin) | | Tolk | planned | Blocked on structured debug-info from tolk-js | | Tact | out of scope | Separate tool |

Install

npm install --save-dev tonofcov

Peer-deps: @ton/sandbox ≥ 0.37, @ton/core ≥ 0.63, @ton/blueprint ≥ 0.41, jest ≥ 29.

Note: tonofcov ships its own FunC compiler WASM build (tonofcov-func-bin) with debugger extensions and a stack overflow fix for large contracts. You do not need to install or configure @ton-community/func-js-bin — tonofcov handles compilation internally.

Quick start

Extend your Jest config with two hooks:

// jest.config.js
module.exports = {
  preset: 'ts-jest',                                      // keep your existing preset
  setupFilesAfterEnv: ['tonofcov/dist/jest-setup'],       // add this
  globalTeardown: 'tonofcov/dist/jest-teardown',          // add this
  // ...your existing config
};

Most TON projects already use ts-jest or a preset shipped with @ton/blueprint / @ton/sandbox, and Jest only allows one preset — so adding the two hooks inline is the path of least resistance. If your project already sets setupFilesAfterEnv, append 'tonofcov/dist/jest-setup' to the array rather than replacing it.

If you already have a globalTeardown of your own (Jest only allows one), wrap it:

// jest.teardown.js
const tonofcovTeardown = require('tonofcov/dist/jest-teardown').default;
const myTeardown = require('./my-existing-teardown');

module.exports = async () => {
  await myTeardown();
  await tonofcovTeardown();
};
// jest.config.js
module.exports = {
  globalTeardown: './jest.teardown.js',
  // ...
};

If you have no preset configured yet, you can use tonofcov's instead:

module.exports = {
  preset: 'tonofcov/jest-preset',
  // ...your existing config
};

Run tests as usual:

npm test

After the suite finishes, tonofcov writes:

  • coverage/lcov.info — for IDE / CI tooling
  • coverage/html/index.html — standalone HTML report (on by default)
  • coverage/gaps.md + coverage/gaps.json — agent-friendly listing of uncovered functions, partial throws, and uncovered ranges (on by default)

What you get

Line coverage

Every FunC source line is classified covered / uncovered / partial / non-exec. inline and inline_ref functions propagate hits back to their call sites, and multi-line statements are kept consistent.

Conditional-throw branch coverage

Each throw_if / throw_unless / throw_arg_if / throw_arg_unless is a two-sided branch: the happy path (cond matched → no throw) and the error path (cond matched → threw). Lines where only one side fired are marked partial (yellow). The HTML report shows per-throw fire counts in a dedicated column, and the index page has a separate "Conditional throws" progress section.

Gaps report (agent-friendly)

coverage/gaps.md and coverage/gaps.json list everything uncovered, grouped by file and prioritized by actionability:

  1. UNCOVERED_FN — a function with zero interior hits. Biggest single-test win.
  2. PARTIAL_THROW — a conditional throw whose error branch never fired (or always fired). Untested error paths.
  3. UNCOVERED_RANGE — contiguous uncovered lines inside an otherwise-covered function. Usually a missed branch.

Each entry includes the source snippet plus mechanical context — enclosing function, nearest conditional header, call sites. No natural-language hints; the consuming agent reads the code and decides how to trigger each gap.

HTML report layout

Per-file page: [throws counter | hit counter | line # | coloured border | syntax-highlighted source]. Index page: Lines block (total / hit / % / bar) and Conditional-throws block (total / fired / % / bar). Files matching the stdlib exclude default are pushed below a divider and don't affect overall percentages.

Configuration

All configuration is via environment variables.

| Variable | Default | Effect | |---|---|---| | TONOFCOV_HTML | enabled | Set to 0 / false / off to skip HTML report generation. | | TONOFCOV_NO_HTML | — | Alternative kill switch for CI. =1 disables HTML. | | TONOFCOV_GAPS | enabled | Set to 0 / false / off to skip the gaps report (gaps.md + gaps.json). | | TONOFCOV_NO_GAPS | — | Alternative kill switch for gaps. =1 disables. | | TONOFCOV_OUT_DIR | coverage | Output directory, relative to cwd. | | TONOFCOV_INCLUDE | — | Comma-separated globs. If set, ONLY matching files contribute to overall totals. | | TONOFCOV_EXCLUDE | **/stdlib.fc,**/mathlib.fc | Comma-separated globs. Matching files are shown but don't count toward totals. Set to empty string to count everything. | | TONOFCOV_TEST_NAME | "" | Populates LCOV's TN: field. | | TONOFCOV_NO_INLINE_PROPAGATE | — | Set to 1 to skip inline-propagation and post-processing passes; raw aggregation only. | | TONOFCOV_NO_DEBUG | — | Comma-separated substrings of target filenames to compile without debug info (no coverage for these contracts). Useful when debug-compiled code changes cell hashes that other contracts depend on. | | TONOFCOV_VERBOSE | — | Set to 1 for detailed progress logs (compilation, aggregation, CFG caps). | | TONOFCOV_DEBUG | — | Set to 1 for internal diagnostic output (between-fill ratio stats, etc.). |

Globs support * (any char except /) and ** (any chars including /).

CI example — GitHub Actions + Codecov

name: ci
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm test
        env:
          TONOFCOV_NO_HTML: "1"   # LCOV only in CI; skip HTML
      - uses: codecov/codecov-action@v4
        with:
          files: coverage/lcov.info
          fail_ci_if_error: true

For GitLab CI, Bitbucket Pipelines, etc. — the pattern is identical: run Jest, upload coverage/lcov.info.

Accuracy — the honest version

Binary coverage (line shown as covered vs not) is reliable — that's what LCOV is for and what we do well.

Hit counts are approximate. Relative ordering (A runs more than B) within a function is usually meaningful, but absolute numbers can be off by a small factor because the FunC compiler emits multiple opcodes per source statement. Conditional headers (if / while / etc.) are normalized; straight-line statements are not. See KNOWN_ARTIFACTS.md for the full catalogue of compiler-level quirks.

Gas counters are tracked internally but not yet exposed — the values double-count across inline expansions and are inconsistent with normalization. See artifact #8.

How it works

  1. A compile hook replaces blueprint's doCompileFunc with tonofcov's own FunC WASM compiler (tonofcov-func-bin) to force debugInfo: true, then parses the debug-marks Cell into (cell_hash, offset) → location_keys maps.
  2. A sandbox hook wraps Executor.runTransaction / runTickTock / runGetMethod to bump vmLog verbosity to full_location_stack and capture every executed step's cell hash, offset, gas, and exception state.
  3. After tests (afterAll in the worker, then globalTeardown in the parent process), vmLogs are aggregated against the compile cache → raw per-line hits and throw counts.
  4. Post-processing: inline-propagation, multi-line-statement propagation, sequential-fill, dead-branch suppression, conditional-header normalization, return-statement capping, non-code-hit stripping, function-signature propagation.
  5. Emit LCOV and (by default) a static HTML report.

License

MIT.

Credits

Built on top of work from @ton/sandbox's debug-marks format, krigga's FunC debugger compiler fork (ctx_id, req_ctx_id, branch coverage fields), and @scaleton/tree-sitter-func (GPL-3.0 grammar, loaded at runtime). The FunC WASM binary (tonofcov-func-bin) is built from krigga/ton debugger branch via ton-wasm-builder and is GPL-2.0 (inheriting from TON source). This package itself is MIT.