Skip to content
 
 

Latest commit

 

History

260 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Trellis

Keep growing codebases maintainable.

Trellis measures structural debt in TypeScript and Python codebases. It finds complex functions, duplicated code, and import cycles, shows where they accumulate, and tracks what changes between audits.

Run it against a local directory. Get a sloppiness index, ranked hotspots, and the measurements behind every score contribution. Audits run offline, without model calls or project setup.

Quickstart · Compare changes · Documentation

When the code gets harder to change

A refactor spans more files than expected. Similar logic starts appearing in several places. Modules depend on each other in both directions. The codebase still builds, but working in it takes more effort.

Trellis gives you a repeatable way to locate that structural debt and see whether a change improves it. Use it before a refactor, during review, or in CI to enforce the limits your project chooses.

It works on files as they exist on disk, including uncommitted changes and directories outside Git.

What trellis measures

  • Complexity. Functions with many decision paths or deeply nested logic.
  • Structural erosion. How much function mass is concentrated in complex functions.
  • Duplication. Repeated code, including copies with renamed identifiers and literals.
  • Import cycles. Groups of modules connected by circular dependencies.
  • Safeguards. How hooks and quality checks are configured and connected, reported separately from the score.

When all required analysis completes, the headline is a 0–100 sloppiness index. Lower is better. Each contribution traces back to raw measurements. If a required dimension is incomplete, Trellis withholds the number and names the unknown dimensions instead of publishing a misleading rank. Findings include file locations so you can inspect the code behind them.

The index measures production code. Test code is analyzed separately, and safeguard configuration never offsets structural debt.

Optional pinned tools add unscored clone and declared architecture evidence. See the quality-evidence guide for setup, policy, compatibility and supported-platform limits.

Quickstart

Requires Bun 1.1 or later.

Install from source:

git clone https://github.com/stoicnode/trellis-python
cd trellis-python
bun install
bun link

Audit a TypeScript, Python, or mixed workspace:

trellis audit /path/to/project

The audited project needs no configuration, credentials, Git repository, Python interpreter, or installed dependencies. A default audit prints its report and writes nothing. The report includes per-language file and import coverage.

Choose JSON or Markdown when you need to keep or share the result:

trellis audit . --json --out report.json
trellis audit . --md --out report.md

--out writes the report to the file instead of stdout. A confirmation goes to stderr; add --quiet to suppress it.

Compare changes

Capture a baseline, make your changes, then audit again:

trellis audit . --json --out /tmp/before.json

# Make your changes.

trellis audit . --json --baseline /tmp/before.json

A supplied baseline enables score-regression and new-finding policy checks. To inspect index changes, metric deltas, and new/resolved/persistent findings, save the current report and compare the artifacts:

trellis audit . --json --out /tmp/after.json
trellis compare /tmp/before.json /tmp/after.json

Named hotspots keep their identity across comment and line shifts; replacing a function or adding the same method name in another class creates a new hotspot. Anonymous or duplicate identities remain conservative new/resolved pairs. The current analyzer emits schema 1.5.0 and uses bounded suffix-array duplication analysis. Historical reports remain readable; crossing an analyzer or scoring-semantic transition requires a fresh baseline. The scoring contract is 0.9.0-provisional: cycle scoring uses the production-induced graph in both languages; workspace-wide cycles remain separate evidence. Python cycle scores cover declared source targets, while runtime-selected and absent-target imports remain located evidence. Formula weights and the 100-token / 3-line clone thresholds are unchanged. See the identity and compatibility rules and native engine acceptance. The Release A migration record inventories the Python graph/executable-size changes, additive advisory evidence, fresh baseline commands and rollback rules.

Guide an agent through cleanup

Ask your agent: Run trellis guide cleanup and follow it until no clearly justified improvements remain. The bundled guide describes the cleanup workflow; repository-specific constraints stay in your repository instructions.

trellis guide cleanup

Reading the guide writes nothing and starts no audit or agent. The same canonical content is available as guide("cleanup") from @os-eco/trellis-cli/client, or as { name, content } with trellis guide cleanup --json. Markdown output uses --md. The maintained source is src/guides/cleanup.ts; workflow documentation should reference it rather than copy its instructions.

Set your project's limits

Add an optional trellis.yaml to declare the conditions that fail an audit:

policy:
  maxIndex: 40
  regression:
    maxIncrease: 2
  failOnNew:
    - import-cycle

With a baseline, this policy also rejects an index increase above two points or a new import cycle.

Trellis exits 0 when policy passes, 2 when policy fails, and 1 when it cannot run. A policy failure still emits the report, so CI retains the evidence behind the failed check.

Policies set acceptance limits. The scoring formula stays consistent across projects.

Track a repository or a fleet

Keep local history when you want to follow a codebase over time:

trellis audit . --history
trellis report

History lives centrally in ~/.trellis/trellis.db.

For multiple repositories, declare targets and run the same audit across all of them:

cp targets.yaml.example targets.yaml
trellis fleet --history

Each target keeps its own report and policy result. Canonical configuration drift is available as a separate inspection.

Use it from TypeScript

The SDK calls the same audit core as the CLI:

import { audit } from "@os-eco/trellis-cli/client";

const result = await audit("/path/to/project");

console.log(result.report);
if (result.policy.failed) process.exitCode = 2;

Local audits, SDK calls, fleet runs, and CI use the same measurement and policy logic.

Scope and limits

Trellis analyzes TypeScript, TSX, and Python (.py). Other languages and excluded files are reported as coverage boundaries.

Python analysis uses a pinned in-process Lezer parser. It handles Python 3 functions, methods, comprehensions, match cases, and ordinary imports without executing target code. Absolute and relative imports resolve against discovered root and src/ modules. Binding-confirmed literal dynamic imports can resolve to discovered targets; runtime-selected imports and missing local targets remain graph limitations. Cross-language imports are not resolved. Optional external evidence providers currently inspect TypeScript files only. See Python support and limits.

Native advisory documentation review flags Python docstrings and attached TypeScript/TSX JSDoc blocks exceeding 40 nonblank content lines or 300 words. Warnings include measured counts and do not affect the index. Configure documentation.enabled, documentation.maxContentLines, and documentation.maxWords in trellis.yaml; use policy.failOnNew to gate new documentation.excessive findings against a baseline.

Advisory executable-scope evidence locates module and class initialization decisions and nesting at depth 3 in any unit, including functions below the scored hotspot threshold. It preserves separate production and test metrics without changing the index. See the executable scope guide for ownership and depth rules.

Audit and comparison summaries now pair absolute burden with density, label production graph scope and observation limits, and show exact score changes that rounding can hide. Documentation warnings have a separate advisory section. See reading reports.

Clone reports also carry advisory duplication.candidate.* metrics for independent executable copies. They classify syntax context and count non-overlapping token occurrences, including copies that share a physical line. Raw clone groups and the scored duplication density remain unchanged; similar data tables remain visible as raw evidence without being called duplicated implementation. See the candidate clone guide for the population and postfilters.

Audits never execute the project's tests, builds, linters, or hooks. Safeguard findings describe configuration and wiring; they do not establish that those checks pass.

Missing dependencies can limit import resolution. Parse failures and analysis limits remain visible. An incomplete required scoring dimension withholds the headline, retains completed raw metrics, and names every unknown dimension.

The scoring formula is provisional. The index is a weighted measure of structural debt, not a percentage of bad code. Compare reports with compatible analyzer, scoring, and configuration identities.

Documentation

Part of os-eco

Trellis is the code-health measurement tool in os-eco. It works independently and needs no other ecosystem tool.

Status

Pre-1.0. The deterministic audit, baseline comparison, declarative policies, optional history, and fleet workflows are implemented. Trellis audits its own codebase.

The scoring formula remains provisional while calibration continues.

License

MIT.

About

Keep growing TypeScript codebases maintainable. Trellis measures complexity, duplication, and import cycles, pinpoints structural debt, and tracks regressions offline.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages