Skip to content

Commit f5ab88a

Browse files
author
Irsyad
committed
CodeBread v1.0.0 — initial public release
Interactive codebase analyzer & visualizer: scans a project, extracts every function/class, maps frontend -> backend -> database connections, and renders it as an interactive node-graph. Runs on the Python standard library alone, UI is vanilla JS/SVG with no build step. Highlights: orbit layout, focus mode, orphan/circular-dependency detection, diff mode between scans, right-click actions, minimap, breadcrumb and keyboard navigation.
0 parents  commit f5ab88a

28 files changed

Lines changed: 5274 additions & 0 deletions

.gitignore

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
dist/
9+
*.egg-info/
10+
.eggs/
11+
*.egg
12+
wheels/
13+
.installed.cfg
14+
15+
# Virtual environments
16+
.venv/
17+
venv/
18+
env/
19+
ENV/
20+
21+
# Testing / tooling caches
22+
.pytest_cache/
23+
.mypy_cache/
24+
.ruff_cache/
25+
.coverage
26+
htmlcov/
27+
28+
# OS
29+
.DS_Store
30+
Thumbs.db
31+
desktop.ini
32+
33+
# Editors / IDEs
34+
.vscode/
35+
.idea/
36+
*.swp
37+
*.swo
38+
*~
39+
40+
# Local environment / secrets
41+
.env
42+
.env.*
43+
44+
# Private notes — not meant for the public repo
45+
codebread-spec.md
46+
47+
# Node (only relevant if you add JS tooling later)
48+
node_modules/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Danial Irsyad
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
<p align="center">
2+
<img src="assets/logo-wordmark.png" alt="CodeBread" width="360">
3+
</p>
4+
5+
<p align="center">
6+
<b>Slice open any codebase and see how it's actually wired together.</b><br>
7+
An interactive, zero-dependency map of files → functions → API routes → database tables.
8+
</p>
9+
10+
<p align="center">
11+
<img alt="version" src="https://img.shields.io/badge/version-1.0.0-2dd4bf">
12+
<img alt="python" src="https://img.shields.io/badge/python-3.9%2B-0284c7">
13+
<img alt="deps" src="https://img.shields.io/badge/required%20dependencies-none-2dd4bf">
14+
<img alt="license" src="https://img.shields.io/badge/license-MIT-8b5cf6">
15+
</p>
16+
17+
---
18+
19+
## What is this
20+
21+
CodeBread scans a project, extracts every function and class, maps how
22+
everything connects — **frontend → API → backend → database** — and renders
23+
it as an interactive node-graph in your browser. Click a file to slice it
24+
open into its functions; click a function to see everything it calls and
25+
everything that calls it, with the full chain lit up end to end.
26+
27+
**The problem it solves:** dropping into a codebase you didn't write — or one
28+
an AI generated for you — and not knowing where anything is. Reading files
29+
one at a time doesn't build a mental model fast. CodeBread builds the model
30+
for you: it finds the routes, follows the `fetch()` calls to the handlers
31+
that answer them, follows the handlers to the tables they touch, and draws
32+
the whole path.
33+
34+
## Why I built this
35+
36+
This started as a personal tool. I kept generating projects with AI and then
37+
staring at the result with no idea how the pieces fit together — which file
38+
called which, where the API boundary actually was, what touched the
39+
database. I wanted something that would just *show* me, instead of me
40+
grepping through the tree file by file. CodeBread is that tool.
41+
42+
It's a v1.0 — actively used by me on my own projects, and I'll keep adding
43+
to it. If it's useful to you too, that's a bonus. Issues and PRs are welcome.
44+
45+
## What it's built with
46+
47+
- **Backend/analysis engine:** pure Python **standard library** — no
48+
required third-party packages, nothing to `pip install` beyond Python
49+
itself. Parsing is stdlib `ast` for Python and structural regex for
50+
everything else (see language table below).
51+
- **Frontend:** vanilla **JavaScript + SVG**, no framework, no build step,
52+
no `npm install`. The entire UI is three files (`app.js`, `index.html`,
53+
`style.css`).
54+
- **Serving:** a tiny local server built on `http.server` from the stdlib.
55+
56+
That's it. Clone it, run it, nothing to compile.
57+
58+
---
59+
60+
## Install
61+
62+
```bash
63+
# option A: install the CLI
64+
pip install .
65+
66+
# option B: don't install anything, just run it
67+
python codebread.py --path /path/to/project
68+
```
69+
70+
Optional extra (better `.gitignore` matching while scanning):
71+
72+
```bash
73+
pip install .[full] # adds pathspec
74+
```
75+
76+
Requires **Python 3.9+**. Nothing else.
77+
78+
## Use
79+
80+
```bash
81+
codebread --path /path/to/project # scan + open the UI in your browser
82+
codebread # prompts for the path
83+
python codebread.py --path . # uninstalled, same thing
84+
```
85+
86+
That's the whole quick start: point it at a folder, a browser tab opens with
87+
the map already scanned.
88+
89+
### CLI reference
90+
91+
| Flag | What it does |
92+
|---|---|
93+
| `--path, -p PATH` | root folder to scan (prompted if omitted) |
94+
| `--port 8137` | local server port (auto-picks a free one nearby if taken) |
95+
| `--json out.json` | export the full graph as JSON |
96+
| `--load out.json` | re-open a saved scan without re-scanning |
97+
| `--html out.html` | export a **self-contained static HTML** file you can share |
98+
| `--diff old.json new.json` | compare two saved scans and print what changed (files/functions/tables added, removed, changed) |
99+
| `--no-open` | don't auto-open the browser |
100+
| `--no-serve` | scan + export only, don't start the server |
101+
| `--version` | print the installed version |
102+
103+
---
104+
105+
## What you get
106+
107+
- **Explorer sidebar** — the full folder tree, expandable like a file
108+
explorer; every file tagged with its layer color.
109+
- **Orbit layout (default)** — files float freely in space, spread apart so
110+
connections stay untangled. Expand a file and its functions arrange in a
111+
clean ring around it, spoked by straight lines back to the center. A
112+
**Free** force-directed layout is also available (toggle bottom-right).
113+
- **Focus mode** — clears the canvas so you inspect one file at a time:
114+
pick a file in the Explorer and only it, its functions, and its direct
115+
connections show up. Toggle it off to go back to the full overview.
116+
- **Progressive reveal (OSINT-style)** — click a file to slice it open into
117+
its numbered functions; click a function to draw in what it calls and
118+
what calls it. Dense codebases stay readable.
119+
- **Full-chain highlight** — select any node and its complete end-to-end
120+
chain lights up (frontend `fetch()``GET /api/users` route → handler →
121+
`users` table), everything unrelated dims.
122+
- **Right-click for actions** — a context menu on every node, edge, and
123+
the empty canvas: reveal connections, focus a file, open it in the IDE
124+
view, jump to a route's source/target, copy a name or path, and more.
125+
- **Insights panel** — flags orphaned functions (no detected callers) and
126+
circular call chains, both clickable to jump straight to them.
127+
- **Diff mode** — compare two saved scans (`--diff old.json new.json`) to
128+
see exactly what changed between them.
129+
- **Minimap + breadcrumb** — a live minimap of the whole graph with a
130+
draggable viewport, and a breadcrumb showing the real folder path of
131+
whatever's currently selected.
132+
- **Keyboard navigation**``/`` step through a selected node's
133+
neighbors, ``/`` walk back/forward through your selection history,
134+
`/` to search.
135+
- **Detail panel** — params, return type, auto-generated description
136+
("Function 3 · handles GET /api/users · queries users"), every caller and
137+
callee, clickable.
138+
- **View the actual code** — every function has an expandable
139+
**▸ View code** section: syntax-highlighted source with real line
140+
numbers. A full **IDE view** (⌗) opens any file whole, with an outline
141+
sidebar.
142+
- **Search** (`/`) and **layer filter** (Frontend / Backend / Database /
143+
Config) in the header.
144+
- **Warnings, never silence** — unreadable files, unsupported languages and
145+
permission problems show up as ⚠ badges and in the warnings list, never
146+
hidden. Secrets found in config files are always masked.
147+
148+
## Language support
149+
150+
| Language | Parser | Extracted |
151+
|---|---|---|
152+
| Python | stdlib `ast` (precise) | functions, classes, params/annotations, docstrings, Flask/FastAPI/Django routes, SQLAlchemy/Django models, raw SQL, `requests`/`httpx` calls |
153+
| JavaScript / TypeScript / JSX / TSX / Vue / Svelte | structural regex + brace matching | functions, arrow fns, classes, Express/Nest/Fastify routes, `fetch`/`axios` calls, Mongoose/Prisma/Sequelize/Knex/TypeORM, raw SQL |
154+
| Java, C#, Go, PHP, Ruby | structural regex | functions/methods, classes, Spring/ASP.NET/Laravel/Rails/Gin routes, raw SQL |
155+
| SQL | regex | `CREATE TABLE` schemas with columns |
156+
| Config (`.env`, json/yaml/toml/ini, settings.py…) | key scan | DB connection settings — **credentials always masked** |
157+
| Anything else (Rust, Kotlin, Swift, C/C++…) || shown in the UI as "⚠ Unsupported — parsing skipped", never silently dropped |
158+
159+
## How it classifies layers
160+
161+
Score-based heuristics combining framework import signatures
162+
(React/Vue → frontend, Flask/Express → backend, SQLAlchemy/Prisma →
163+
database), folder conventions (`/client`, `/server`, `/models`…), file
164+
extensions, and extracted facts (defines routes → backend, defines models →
165+
database). Ambiguous files are marked **Unclassified** instead of guessed.
166+
167+
## How orphan + cycle detection works
168+
169+
- **Orphaned functions**: any function/method with zero detected incoming
170+
calls, that isn't a route handler and isn't a common framework entry
171+
point (`__init__`, `main`, `setUp`, test functions, …). Flagged with a
172+
badge on the node and listed in the Insights panel — a good starting
173+
point for finding dead code (heuristic, not exhaustive: it can miss calls
174+
the static parser doesn't recognize).
175+
- **Circular call chains**: an iterative cycle-detection pass over the
176+
call graph (no recursion, so it's safe on large codebases) flags
177+
functions that call each other in a loop, both on the node (↻ badge) and
178+
as a listed chain in the Insights panel.
179+
180+
## Project layout
181+
182+
```
183+
codebread.py ← runnable entry point (no install needed)
184+
codebread/
185+
cli.py ← argparse CLI
186+
scanner.py ← .gitignore-aware recursive walker
187+
languages.py ← language detection / binary sniffing
188+
parsers/
189+
python_parser.py ← ast-based Python extractor
190+
javascript_parser.py ← JS/TS/Vue/Svelte extractor
191+
generic_parser.py ← Java/C#/Go/PHP/Ruby + SQL + config
192+
classifier.py ← frontend/backend/database/config scoring
193+
connections.py ← call graph + API↔route + fn↔table matching +
194+
orphan/cycle detection
195+
analyzer.py ← pipeline orchestration
196+
diff.py ← compares two saved scans
197+
server.py ← stdlib local web server
198+
export.py ← JSON + single-file HTML export
199+
web/ ← the UI (vanilla JS + SVG, zero dependencies)
200+
assets/ ← logo (.svg source + .png for the README —
201+
GitHub blocks same-repo SVG <img> embeds)
202+
```
203+
204+
---
205+
206+
## Roadmap
207+
208+
Already done as of v1.0:
209+
210+
- [x] Orphaned-function and circular-dependency detection
211+
- [x] Diff mode between two scans
212+
- [x] Focus mode, orbit layout, right-click actions, minimap, breadcrumb
213+
214+
Not yet, but planned:
215+
216+
- [ ] "Explain this function" — a plain-language AI summary button
217+
- [ ] More precise multi-language parsing (currently structural regex for
218+
everything but Python)
219+
- [ ] An automated test suite
220+
221+
Have an idea? Open an issue.
222+
223+
## Contributing
224+
225+
This is a young, actively-changing personal project, so keep that in mind —
226+
but contributions are genuinely welcome:
227+
228+
- **Bugs / ideas** → open an issue with a repro or a description.
229+
- **Pull requests** → welcome, especially for language parser improvements
230+
or UI polish. Keep the zero-dependency philosophy: the core tool should
231+
keep running on nothing but the Python standard library, and the UI
232+
should keep running on vanilla JS with no build step.
233+
- No formal test suite yet, so please describe how you manually verified a
234+
change in your PR.
235+
236+
## License
237+
238+
[MIT](LICENSE) — use it, modify it, ship it, sell it. No attribution
239+
required beyond keeping the license file. See [LICENSE](LICENSE) for the
240+
full text.

assets/logo-wordmark.png

26.6 KB
Loading

assets/logo-wordmark.svg

Lines changed: 15 additions & 0 deletions
Loading

assets/logo.png

12.3 KB
Loading

assets/logo.svg

Lines changed: 10 additions & 0 deletions
Loading

codebread.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env python3
2+
"""Convenience launcher so the spec's `python codebread.py --path ...` works
3+
without installing the package."""
4+
import os
5+
import sys
6+
7+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
8+
9+
from codebread.cli import main
10+
11+
if __name__ == "__main__":
12+
main()

codebread/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""CodeBread — slice open a codebase and see its internal structure."""
2+
3+
__version__ = "1.0.0"

0 commit comments

Comments
 (0)