You built an app with AI. It works. But you open the folder a week later and have no idea what any of it is, what's safe to touch, or what happens if you break something. Found reads your project and tells you what you have, in plain English.
Open-source, MIT, contributions welcome. Focused tool, not a platform. See Scope before filing a feature request.
No install required:
cd ~/path/to/your-app
npx @ebanchik/found .Or install globally:
npm install -g @ebanchik/found
found .Requires Node.js 18 or newer. First-time user? Read docs/GETTING-STARTED.md for a full walkthrough — prerequisites, what the output sections mean, common situations, and flags.
Set an Anthropic API key and Found uses a single cheap model call to turn flat templates into real descriptions:
export FOUND_ANTHROPIC_KEY=sk-ant-...
npx @ebanchik/found .What changes: "A screen at /Input. Probably where people interact with input." becomes "Where users enter the credit cards they have and how much they spend in each category." The model receives the parsed structure only — paths, exports, import edges — never your source code. Cost is fractions of a cent per run.
Skip the LLM step anytime with --no-llm.
Point it at a project folder. It prints a map like:
WHAT THIS APP IS BUILT ON
A React chat app built with Vite and styled with Tailwind CSS. Conversations are powered
by Anthropic's Claude API with streaming responses. The backend runs on Express and is
deployed to Vercel.
Language: TypeScript
Frontend: React, React hooks, Vite
Styling: Tailwind CSS, Radix UI, Lucide icons
AI: Anthropic Claude SDK, Streaming LLM responses
Backend: Express
Deployment: Vercel
Your app is 1 screen, 2 endpoints, 5 components, and 2 helpers. That's all of it.
SCREENS PEOPLE SEE
The main app screen Displays the chat interface where users select a philosopher and chat.
src/App.tsx
API ENDPOINTS
The chat endpoint Receives messages and returns Claude's responses for the selected philosopher.
api/chat.js
BEHIND THE SCENES (you've never had to open these)
The list of philosophers Stores the names and details of the philosophers available to chat with.
philosophers.js
That's the whole product.
| Flag | What it does |
|---|---|
--json |
Output found-map.json to stdout instead of human text |
--all |
Show every item without the 20-per-section listing cap |
--debug |
Show underlying stack traces beneath friendly errors |
--no-llm |
Skip the LLM enrichment step; use the deterministic labels only |
In scope:
- JavaScript / TypeScript projects (React, Next.js, Vite). This is what AI tools mostly generate.
- Single apps. One
package.json, one project. - Read-only. Found never modifies your code.
Out of scope (for now):
- Other languages (Python, Go, etc.)
- Monorepos / multi-package workspaces
- Anything that writes to or runs your code
A confident wrong label is worse than no label. Found maps each finding's confidence to one of three treatments:
| Confidence | Treatment | Example |
|---|---|---|
| High (≥ 0.8) | State plainly | "The sign-in screen — where people log in." |
| Medium (0.5–0.8) | Hedge visibly | "A screen at /login. Probably where people sign in." |
| Low (< 0.5) | Don't guess | "A file called helpers.js — I can't tell what this does without a closer look." |
For someone who's lost, an honest hedge beats a confident wrong answer every time.
- No telemetry. No analytics. No phone-home.
- v0.1 is fully local — your code never leaves your machine.
- v0.2a (shipped — see "Richer labels" above) adds optional LLM-enriched labels via a single batched cheap-model call. The LLM sees the parsed structure (paths, exports, import edges) — never your raw source. API key is opt-in via
FOUND_ANTHROPIC_KEY. No key, no LLM call. Skip anytime with--no-llm.
Found writes found-map.json (with --json) following this shape:
{
"version": "0.1",
"generatedAt": "2026-05-27T15:00:00Z",
"summary": {
"screens": 4,
"endpoints": 0,
"components": 0,
"helpers": 2,
"configFiles": 6,
"tests": 0,
"unknown": 0
},
"nodes": [
{
"path": "src/screens/Login.jsx",
"kind": "screen",
"name": "The sign-in screen",
"does": "A screen at /login. Probably where people sign in.",
"confidence": 0.85,
"confidenceSource": "convention+graph",
"userFacing": true
}
],
"edges": [
{ "from": "src/screens/Login.jsx", "to": "src/lib/email.js" }
]
}| Field | Type | Notes |
|---|---|---|
version |
"0.1" |
Schema version. Bumped on breaking changes. |
generatedAt |
ISO 8601 string | When the map was produced. |
summary |
object | Counts by kind. |
nodes[].kind |
enum | screen / endpoint / component / helper / config / test / entrypoint / unknown |
nodes[].confidence |
number 0–1 | Drives hedging in the human renderer. |
nodes[].confidenceSource |
enum | convention / convention+graph / graph / model (v0.2a). Lets you audit where a label came from. |
nodes[].userFacing |
boolean | Whether the user sees it directly. |
edges[] |
array | Dependency graph. from imports to. |
The schema is additive between minor versions. v0.2a adds confidenceSource: "model" and model-emitted float confidence values without breaking v0.1 consumers.
- v0.1 — Static map. Deterministic labels. Shipped.
- v0.2a — Optional LLM-enriched labels via a single batched cheap-model call.
confidenceSource: "model". Shipped. - v0.2.1 — New
WHAT THIS APP IS BUILT ONsection with detected technologies and patterns (React, hooks, Tailwind, Anthropic SDK, streaming, RAG, etc.). Detection runs locally; LLM only sees the resulting tag list, never your source. Shipped. - v0.2b —
--change "..."for blast-radius queries: "I want to change the login flow → touch these files, avoid these, likely symptom if it breaks." - Beyond — watch mode, "what just happened" diff narration, explain-on-demand. Not promised, listed for orientation.
The high-value places to help:
- More accurate conventions (the label table in
src/classify.ts) for framework variants the scanner misses. - Synthetic fixtures that exercise specific real-world patterns — see
fixtures/for the format. - New stacks (Python, etc.) — but as additive scanners behind the same interface, keeping each one honest about what it can't read.
Keep PRs scoped. The fastest way to make this worse is to turn it into five tools.
First-time setup:
npm install
npm run build # builds dist/ so the bin regression test runs
npm test # vitest unit tests (110+ tests)
npm run eval # synthetic eval against fixtures/
npm run typecheck # tsc --noEmitDay-to-day:
npm run dev fixtures/next-app-basic # dogfood against a bundled fixture
npm run dev /path/to/your/project # dogfood against any real JS/TS appThe eval harness scores Found's output against fixtures/*/ground-truth.json. Aim for ≥80% correct-or-hedged-correct before shipping.
MIT. See LICENSE.