Skip to content

ebanchik1/Found

Repository files navigation

Found — a plain-language map for vibe-coded apps

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.


Install / run

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.

Richer labels (optional)

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.

What it does

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.

Flags

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

Scope

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

Honest hedging

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.

Privacy

  • 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.

Schema reference

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.

Roadmap

  • 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 ON section 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.

Contributing

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.

Development

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 --noEmit

Day-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 app

The eval harness scores Found's output against fixtures/*/ground-truth.json. Aim for ≥80% correct-or-hedged-correct before shipping.

License

MIT. See LICENSE.

About

A plain-language map for vibe-coded apps. Tells you what you have, in English.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors