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

maat-ostraca

v0.9.0

Published

Translate the ghost in the machine into the poetry of human intent

Readme

maat-ostraca

Analyze source files and compare code snapshots with one CLI and consistent JSON across TypeScript, Go, Dart, Python 3, Rust, and Swift.

Maat Ostraca

maat extracts imports, symbols, metrics, I/O counts, messages, environment keys, and test names. Use it in scripts, code reviews, or reports without building a separate query for each language. Analysis is static and operates on one source file at a time.

Install

Requires Node.js 24 or newer.

npm install --global maat-ostraca
maat --help

Or run the published package without a global installation:

npx maat-ostraca rules --language typescript --json

The examples below use maat. When working from a checkout, use npm run cli -- in its place; checkout capabilities may be newer than the published package.

Quick start

Choose a source file and its language explicitly:

SOURCE_FILE=src/lib.rs
LANGUAGE=rust

# Discover this language's rules.
maat rules --language "$LANGUAGE" --json

# Analyze every implemented rule for this language.
maat analyse --in "$SOURCE_FILE" --language "$LANGUAGE" --rules '*' --json

# Select portable rules for a smaller report.
maat analyse --in "$SOURCE_FILE" --language "$LANGUAGE" \
  --rules function_map,method_map,file_metrics --json

Use the same commands with any supported language:

| --language | Example source file | Implemented rules | Class maps | Interface maps | | ------------ | ------------------- | ----------------: | ---------- | ------------------- | | typescript | src/index.ts | 16 | Yes | Yes | | go | main.go | 15 | No | Yes | | dart | lib/main.dart | 16 | Yes | Yes | | python | app.py | 14 | Yes | No | | rust | src/lib.rs | 15 | No | Yes, from traits | | swift | Sources/App.swift | 16 | Yes | Yes, from protocols |

The CLI does not infer the language from the filename. Python, Rust, and Swift analysis requires no Python interpreter, Cargo/rustc, Swift compiler, or Xcode at runtime.

Commands

| Command | Inputs | Purpose | | --------- | ---------------------------------------------------------- | ------------------------------------------ | | analyse | --in <file>, or stdin | Analyze one snapshot | | diff | --from <file> and --to <file>, or stdin for the target | Compare two snapshots of the same language | | rules | --language; optional --match <names> | List rule names and descriptions |

analyse and diff require --language and --rules. Add --json for machine output; omit it for a human-readable report. Run maat <command> --help for all options. Sources are limited to 5 MiB each; empty stdin is rejected.

Select rules

All six languages implement these 13 rules:

| Group | Rule names | | ----------- | --------------------------------------------------------------- | | Imports | import_files_list, package_imports_list | | Symbols | function_map, method_map | | Metrics | file_metrics, code_hash | | I/O | io_calls_count, io_read_calls_count, io_write_calls_count | | Messages | exception_messages_list, error_messages_list | | Environment | env_names_list | | Tests | testcase_titles_list |

Class-capable languages also implement class_map. Interface-capable languages implement interface_map and interfaces_code_map.

# Explicit names, a prefix wildcard, or all implemented rules.
maat analyse --in "$SOURCE_FILE" --language "$LANGUAGE" --rules 'io_*,file_metrics' --json
maat analyse --in "$SOURCE_FILE" --language "$LANGUAGE" --rules '*' --json

# Manifest filtering accepts exact names, not wildcard selectors.
maat rules --language "$LANGUAGE" --match function_map,code_hash --json

Quote wildcard selectors to prevent shell expansion. '*' expands to the implemented rules for the selected language, so its output keys vary by capability. Imported function/type classification is not implemented; older catalog entries may still list import_functions_list and import_types_list for TypeScript, Go, and Dart.

Read from stdin

cat "$SOURCE_FILE" | maat analyse --language "$LANGUAGE" --rules env_names_list --json

For example, this self-contained command:

printf 'process.env.API_TOKEN;\n' | maat analyse --language typescript --rules env_names_list --json

returns:

{ "language": "typescript", "rules": { "env_names_list": ["API_TOKEN"] } }

The equivalent Swift environment query uses the same rule and JSON shape:

printf '%s\n' 'import Foundation' 'let home = ProcessInfo.processInfo.environment["HOME"]' \
  | maat analyse --language swift --rules env_names_list --json
{ "language": "swift", "rules": { "env_names_list": ["HOME"] } }

Query JSON

JSON is the machine contract: stable key ordering, predictable maps, and sorted, deduplicated lists where applicable. These jq queries work across all six languages:

maat analyse --in "$SOURCE_FILE" --language "$LANGUAGE" --rules function_map --json \
  | jq '.rules.function_map | to_entries | map({symbol: .key, lines: .value.loc})'

maat analyse --in "$SOURCE_FILE" --language "$LANGUAGE" --rules method_map --json \
  | jq '.rules.method_map[] | {name, receiver, ioCallsCount}'

Treat symbol keys as opaque identifiers. Signatures, import paths, and metric approximations reflect each language's syntax. Shared field names and types do not imply equal metric values for translated programs.

See the cross-language JSON contract for result shapes, capability differences, and the tests that enforce portability.

Compare snapshots

maat diff --from before.rs --to after.rs --language rust \
  --rules function_map,file_metrics,code_hash --json

# Emit numeric deltas directly and omit the original hash strings.
maat diff --from before.rs --to after.rs --language rust \
  --rules function_map,file_metrics,code_hash --delta-only --json

# Read the target snapshot from stdin.
cat after.rs | maat diff --from before.rs --language rust --rules code_hash --json

The same flags work for every supported language. List diffs have added and removed arrays; symbol-map entries have a status; standard numeric diffs have from, to, and delta fields.

Add --exit-code-on-change to diff to signal changes to a script:

| Exit code | Meaning | | --------- | ------------------------------------------------------ | | 0 | Success; without the flag, a changed diff also exits 0 | | 1 | Internal analysis failure | | 2 | Invalid usage or input, including unreadable files | | 3 | Changes detected with --exit-code-on-change |

With --json, errors use an error object containing code and message. Successful human output is also deterministic, but scripts should use JSON.

Analysis scope

Analysis extracts syntax and documented patterns; it does not execute source code. Dynamic messages, runtime dependency resolution, receiver types, and macro-generated code may not be discoverable. Rust does not evaluate cfg branches, and Python/Rust/Swift parser recovery may return partial results for incomplete code.

Swift maps classes to class_map and protocols to the interface maps. Methods include extension methods, initializers, and methods on structs, enums, and actors. Overload keys preserve argument labels and types; treat them as opaque identifiers. Test discovery covers Swift Testing @Test declarations and parameterless XCTest instance methods, excluding nested helpers and static or parameterized methods. Swift conditional-compilation branches are inspected without selecting a platform.

See language analysis notes for extraction conventions and language-specific limitations.

Develop locally

Requires Node.js 24+ and npm. Install Bun to run the e2e suite; the release workflow uses Bun 1.3.6. jq is optional for the query examples above.

git clone https://github.com/flarebyte/maat-ostraca.git
cd maat-ostraca
npm ci
npm run build
npm run cli -- rules --language rust --json

To expose the checkout's compiled CLI as maat, run npm link after building. Rebuild after source changes when using the linked executable.

| Task | Command | | ------------------------------------- | ----------------------------------- | | Typecheck | npm run typecheck | | Unit tests | npm test | | Build CLI into dist/ | npm run build | | E2e tests, including the compiled CLI | npm run build && npm run test:e2e | | Unit coverage | npm run test:cov | | Lint | make lint | | Format and apply lint fixes | make format | | Duplication check | make dup |

The implementation lives under src/, unit tests under test/, CLI integration tests under script/e2e/, and source fixtures/golden JSON under testdata/. Golden tests check analyse/diff output and repeated-run byte stability. Shared contract tests exercise portable queries across every supported language.

For a language extension, add rule adapters under src/rules/<rule>/<language>.ts, shared extraction helpers under src/rules/_shared/<language>/, and entries in the capability and contract-test matrices. Add expected-value tests and CLI goldens alongside the implementation.

Coverage details: Python, Rust, and Swift. The Swift audit includes 68 unit cases and 42 dedicated e2e cases, with additional shared language/query checks. See its coverage record for measured percentages and regression scenarios. Release setup and recovery: releasing.