TypeScript static-analysis tooling for dead code, dependency, and architecture hygiene.
  • JavaScript 52.9%
  • TypeScript 47.1%
Find a file
pdurlej 5c9fa5f2e3
All checks were successful
CI / Node.js 22 (push) Successful in 11s
CI / test (push) Successful in 23s
CI / Node.js 20 (push) Successful in 11s
Merge pull request 'docs(agents): add § 0 cousin-onboarding pointer (agent-souls discipline)' (#46) from claude/docs/cousin-onboarding-pointer into main
Reviewed-on: #46
2026-05-20 12:39:17 +02:00
.forgejo/workflows Add Node release matrix to CI 2026-05-18 18:51:53 +02:00
.github/workflows Add Node release matrix to CI 2026-05-18 18:51:53 +02:00
decisions Bootstrap fallow-ts governance 2026-05-16 23:35:09 +02:00
docs Polish public positioning for alpha release 2026-05-19 00:43:21 +02:00
examples Add Node release matrix to CI 2026-05-18 18:51:53 +02:00
scripts Harden npm publish dry-run proof 2026-05-18 18:54:17 +02:00
src Merge remote-tracking branch 'origin/main' into codex/release-identity-alpha2 2026-05-18 23:17:34 +02:00
tests Polish public positioning for alpha release 2026-05-19 00:43:21 +02:00
.gitignore Bootstrap fallow-ts analyzer contract 2026-05-16 08:43:46 +02:00
AGENTS.md docs(agents): add § 0 cousin-onboarding pointer (agent-souls discipline) 2026-05-19 23:54:57 +02:00
CHANGELOG.md Cut fallow-ts 0.1.0-alpha.2 identity 2026-05-18 18:50:34 +02:00
LICENSE Add fallow-ts bootstrap files 2026-05-16 08:45:30 +02:00
package-lock.json Cut fallow-ts 0.1.0-alpha.2 identity 2026-05-18 18:50:34 +02:00
package.json Polish public positioning for alpha release 2026-05-19 00:43:21 +02:00
README.md Polish public positioning for alpha release 2026-05-19 00:43:21 +02:00
tsconfig.json Add fallow-ts bootstrap files 2026-05-16 08:45:30 +02:00

fallow-ts

fallow-ts is a deterministic TypeScript/JavaScript codebase-intelligence checkpoint for AI agents and reviewers.

It does not execute the project under analysis. It reads source files and package metadata, builds a conservative import/export graph, and reports the static evidence an agent should inspect before claiming a change is clean.

The current alpha is intentionally narrow. It is not a full dead-code analyzer and it does not try to replace TypeScript, ESLint, Biome, Knip, dependency cruiser, tests, or human review. Today it focuses on three review signals:

  • unresolved relative internal imports;
  • deterministic circular dependencies;
  • likely-unused internal exports, with package entrypoints protected.

Use it as a cheap read-only guardrail and prompt-shaping layer: it tells an agent what deserves attention, not what is safe to delete automatically.

Non-affiliation

fallow-ts is operator-owned experimental software. It is not the official fallow-rs/fallow project and does not imply affiliation with upstream Fallow unless it is explicitly upstreamed later.

Install

From a fresh source checkout:

npm install
npm run build
npm run release:smoke

After the package is published, the intended package-manager path is:

npm install --save-dev fallow-ts
npx fallow-ts analyze --root . --format text

Until then, use the source checkout commands below.

Alpha Adoption Path

For a first repository, use fallow-ts as a read-only checkpoint:

  1. Run the demo so the current finding language is familiar.
  2. Run JSON or agent-context output on the target repo.
  3. Create a baseline before enforcing CI on an existing project.
  4. Treat findings as review prompts. Do not delete code because a static alpha report says it looks unused.

Good early fits:

  • small JS/TS libraries;
  • package entrypoint review before cleanup;
  • PR checks that should catch new unresolved relative imports;
  • agent loops that need compact context before editing.

Bad early fits:

  • framework-heavy reachability claims;
  • dependency policy enforcement;
  • auto-fix workflows;
  • security or production-safety decisions.

CLI

npm run build
node dist/cli.js analyze --root .
node dist/cli.js analyze --root . --format json --output /tmp/fallow-ts-report.json
node dist/cli.js analyze --root . --format agent-context
node dist/cli.js baseline create --root . --output fallow-ts-baseline.json
node dist/cli.js analyze --root . --baseline fallow-ts-baseline.json --fail-on warning

The default command is analyze, so this is equivalent:

node dist/cli.js --root . --format json

--format agent-context emits compact Markdown for AI agents. See docs/agent-context.md.

baseline create stores current finding fingerprints for CI adoption. --fail-on warning exits 1 only for unbaselined findings at or above the threshold. See docs/baseline.md.

Copy-paste CI examples live in examples/ci/, with Forgejo Actions first and GitHub Actions as a mirror template.

For AI-agent loops, prefer agent-context over full JSON unless the agent needs machine-readable fields. It keeps the prompt focused on findings, public entrypoints, graph evidence, and limitations.

Demo

A small demo project lives in examples/demo-project/. It intentionally contains one missing relative import, one circular dependency, and one likely-unused export candidate.

npm run build
node dist/cli.js analyze --root examples/demo-project --format text
node dist/cli.js analyze --root examples/demo-project --format agent-context

For adoption guidance, see docs/adoption.md.

For release checks, npm run release:smoke packs the local package, installs that tarball into a temporary clean project, and verifies the installed CLI can print help, analyze JSON, and create/use a baseline.

Current JSON Contract

The full v0 contract is documented in docs/report-schema-v0.md. The example below shows the current shape.

{
  "schema": "fallow-ts.report",
  "schema_version": "0.1",
  "tool": "fallow-ts",
  "version": "0.1.0-alpha.2",
  "root": ".",
  "summary": {
    "files": 2,
    "modules": 2,
    "imports": 1,
    "exports": 2
  },
  "package": {
    "path": "package.json",
    "name": "example",
    "type": "module",
    "packageManager": "npm@10.0.0",
    "main": "./src/index.ts",
    "module": "./src/index.ts",
    "exports": {
      ".": "./src/index.ts"
    },
    "imports": {},
    "dependencies": {},
    "devDependencies": {}
  },
  "workspaces": [
    {
      "source": "package.json",
      "manager": "npm",
      "patterns": ["packages/*"]
    }
  ],
  "graph": {
    "internalEdges": [
      {
        "importer": "src/index.ts",
        "source": "./helper",
        "kind": "static",
        "line": 1,
        "target": "src/helper.ts",
        "targetModule": "src/helper"
      }
    ],
    "unresolvedInternalEdges": [],
    "publicEntryPoints": [
      {
        "source": "package.json#exports",
        "entry": ".",
        "target": "src/index.ts",
        "targetModule": "src"
      }
    ],
    "unresolvedPublicEntryPoints": [],
    "cycles": []
  },
  "findings": [],
  "classification": {
    "auto_safe": [],
    "decision_needed": [],
    "blocking": []
  },
  "modules": [
    {
      "path": "src/index.ts",
      "module": "src/index",
      "imports": [],
      "exports": [
        { "name": "main", "kind": "function", "line": 1 }
      ]
    }
  ],
  "errors": [],
  "limitations": [
    "Regex-based first contract; no TypeScript AST yet.",
    "Template literals and comments are masked before import parsing; code inside template interpolation is not analyzed yet.",
    "Likely-unused exports are conservative cleanup candidates, not deletion-safety claims.",
    "Does not infer dependency policy or full framework entry points yet."
  ]
}

Scope

Current scope:

  • discover .ts, .tsx, .js, .jsx, .mts, .cts, .mjs, .cjs
  • skip generated/build directories such as node_modules, dist, coverage
  • parse common static import, export, dynamic import, and require() forms
  • read root package.json metadata needed for later graph work
  • detect shallow npm/yarn/pnpm workspace declarations
  • resolve conservative relative internal import edges
  • represent simple package public entrypoints from main, module, and exports
  • report high-confidence unresolved relative internal imports
  • detect deterministic cycles in the resolved internal graph
  • report conservative likely-unused internal runtime exports
  • emit a compact agent-context format for prompt use
  • ignore import-looking text inside comments and template literals
  • produce stable JSON and a compact text summary

Out of scope for the initial bootstrap:

  • deletion-safety claims for unused export/file cleanup
  • framework plugins
  • package dependency policy
  • MCP server
  • auto-fix
  • parity with fallow-py

Why start this small?

Because the useful part is the contract: deterministic evidence first, analyzer ambition second. fallow-py learned that public credibility comes from a tool that can dogfood itself, explain its limitations, and fail honestly.