codebread 1.0.6__tar.gz → 1.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. codebread-1.1.1/PKG-INFO +279 -0
  2. codebread-1.1.1/README.md +263 -0
  3. codebread-1.1.1/codebread/__init__.py +40 -0
  4. {codebread-1.0.6 → codebread-1.1.1}/codebread/cli.py +13 -0
  5. codebread-1.1.1/codebread/context.py +170 -0
  6. {codebread-1.0.6 → codebread-1.1.1}/codebread/web/app.js +562 -52
  7. {codebread-1.0.6 → codebread-1.1.1}/codebread/web/index.html +93 -29
  8. codebread-1.1.1/codebread/web/style.css +887 -0
  9. codebread-1.1.1/codebread.egg-info/PKG-INFO +279 -0
  10. {codebread-1.0.6 → codebread-1.1.1}/codebread.egg-info/SOURCES.txt +2 -0
  11. {codebread-1.0.6 → codebread-1.1.1}/pyproject.toml +3 -2
  12. codebread-1.1.1/tests/test_context.py +18 -0
  13. {codebread-1.0.6 → codebread-1.1.1}/tests/test_server.py +12 -0
  14. codebread-1.1.1/tests/test_version.py +24 -0
  15. codebread-1.0.6/PKG-INFO +0 -356
  16. codebread-1.0.6/README.md +0 -340
  17. codebread-1.0.6/codebread/__init__.py +0 -36
  18. codebread-1.0.6/codebread/web/style.css +0 -623
  19. codebread-1.0.6/codebread.egg-info/PKG-INFO +0 -356
  20. codebread-1.0.6/tests/test_version.py +0 -14
  21. {codebread-1.0.6 → codebread-1.1.1}/LICENSE +0 -0
  22. {codebread-1.0.6 → codebread-1.1.1}/codebread/analyzer.py +0 -0
  23. {codebread-1.0.6 → codebread-1.1.1}/codebread/classifier.py +0 -0
  24. {codebread-1.0.6 → codebread-1.1.1}/codebread/connections.py +0 -0
  25. {codebread-1.0.6 → codebread-1.1.1}/codebread/deobfuscate.py +0 -0
  26. {codebread-1.0.6 → codebread-1.1.1}/codebread/diff.py +0 -0
  27. {codebread-1.0.6 → codebread-1.1.1}/codebread/export.py +0 -0
  28. {codebread-1.0.6 → codebread-1.1.1}/codebread/languages.py +0 -0
  29. {codebread-1.0.6 → codebread-1.1.1}/codebread/models.py +0 -0
  30. {codebread-1.0.6 → codebread-1.1.1}/codebread/parsers/__init__.py +0 -0
  31. {codebread-1.0.6 → codebread-1.1.1}/codebread/parsers/generic_parser.py +0 -0
  32. {codebread-1.0.6 → codebread-1.1.1}/codebread/parsers/javascript_parser.py +0 -0
  33. {codebread-1.0.6 → codebread-1.1.1}/codebread/parsers/python_parser.py +0 -0
  34. {codebread-1.0.6 → codebread-1.1.1}/codebread/scanner.py +0 -0
  35. {codebread-1.0.6 → codebread-1.1.1}/codebread/server.py +0 -0
  36. {codebread-1.0.6 → codebread-1.1.1}/codebread.egg-info/dependency_links.txt +0 -0
  37. {codebread-1.0.6 → codebread-1.1.1}/codebread.egg-info/entry_points.txt +0 -0
  38. {codebread-1.0.6 → codebread-1.1.1}/codebread.egg-info/requires.txt +0 -0
  39. {codebread-1.0.6 → codebread-1.1.1}/codebread.egg-info/top_level.txt +0 -0
  40. {codebread-1.0.6 → codebread-1.1.1}/setup.cfg +0 -0
  41. {codebread-1.0.6 → codebread-1.1.1}/tests/test_analyzer.py +0 -0
  42. {codebread-1.0.6 → codebread-1.1.1}/tests/test_config_parser.py +0 -0
  43. {codebread-1.0.6 → codebread-1.1.1}/tests/test_connections.py +0 -0
  44. {codebread-1.0.6 → codebread-1.1.1}/tests/test_deobfuscate.py +0 -0
  45. {codebread-1.0.6 → codebread-1.1.1}/tests/test_generic_parser.py +0 -0
  46. {codebread-1.0.6 → codebread-1.1.1}/tests/test_javascript_parser.py +0 -0
  47. {codebread-1.0.6 → codebread-1.1.1}/tests/test_python_parser.py +0 -0
  48. {codebread-1.0.6 → codebread-1.1.1}/tests/test_scanner.py +0 -0
@@ -0,0 +1,279 @@
1
+ Metadata-Version: 2.4
2
+ Name: codebread
3
+ Version: 1.1.1
4
+ Summary: Interactive codebase analyzer & visualizer — slice open a project and see how it's wired together.
5
+ Author: Danial Irsyad
6
+ License: MIT
7
+ Keywords: codebase,analyzer,visualizer,call-graph,architecture,dependency-graph,code-visualization,static-analysis,code-map
8
+ Requires-Python: >=3.9
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Provides-Extra: full
12
+ Requires-Dist: pathspec>=0.11; extra == "full"
13
+ Provides-Extra: test
14
+ Requires-Dist: pytest>=7; extra == "test"
15
+ Dynamic: license-file
16
+
17
+ <p align="center">
18
+ <img src="https://cdn.jsdelivr.net/gh/honow48-tech/CodeBread@main/assets/logo-wordmark.png" alt="CodeBread" width="320">
19
+ </p>
20
+
21
+ <p align="center">
22
+ <b>See how any codebase is wired together.</b><br>
23
+ Files, functions, API routes and database tables, mapped in your browser.
24
+ </p>
25
+
26
+ <p align="center">
27
+ An interactive codebase visualizer: call graph, dependency map and API-to-database tracing<br>
28
+ for Python, JavaScript, TypeScript, PHP, Java, Go, C# and Ruby.
29
+ </p>
30
+
31
+ <p align="center">
32
+ <a href="https://pypi.org/project/codebread/"><img alt="PyPI" src="https://img.shields.io/pypi/v/codebread?color=b0541c&label=pypi"></a>
33
+ <a href="https://github.com/honow48-tech/CodeBread/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/honow48-tech/CodeBread/actions/workflows/ci.yml/badge.svg"></a>
34
+ <img alt="Python 3.9+" src="https://img.shields.io/badge/python-3.9%2B-5f5c55">
35
+ <img alt="No dependencies" src="https://img.shields.io/badge/dependencies-none-5f5c55">
36
+ <img alt="MIT" src="https://img.shields.io/badge/license-MIT-5f5c55">
37
+ </p>
38
+
39
+ <p align="center">
40
+ <img src="https://cdn.jsdelivr.net/gh/honow48-tech/CodeBread@main/assets/overview.gif" alt="The CodeBread overview: project totals, a language breakdown, and a file table that previews each file on hover" width="880">
41
+ </p>
42
+
43
+ ## Quick start
44
+
45
+ ```bash
46
+ pip install codebread
47
+ codebread --path ./my-project
48
+ ```
49
+
50
+ A browser tab opens with the project already mapped. Everything runs on your
51
+ machine: nothing is uploaded, and nothing in the scanned project is executed.
52
+
53
+ ## What you get
54
+
55
+ ### Overview
56
+
57
+ Totals, a breakdown of the project by language, and every file in one table.
58
+ Hover a row to preview what the file contains and what it talks to.
59
+
60
+ ### Connections
61
+
62
+ Pick a file to see what uses it, what it uses, and which functions are
63
+ linked. Click a neighbour to follow the trail; a breadcrumb takes you back.
64
+ It only ever draws one file's neighbourhood, so it stays readable on a
65
+ project with thousands of files.
66
+
67
+ <p align="center">
68
+ <img src="https://cdn.jsdelivr.net/gh/honow48-tech/CodeBread@main/assets/connections.gif" alt="The Connections page: callers on the left, the selected file in the middle, the files it uses on the right, joined function to function" width="880">
69
+ </p>
70
+
71
+ ### Map
72
+
73
+ The whole project as a graph. Click a file to open it into its functions.
74
+ Click a function to light up everything it calls and everything that calls
75
+ it, all the way from a frontend `fetch()` to the database table.
76
+
77
+ <p align="center">
78
+ <img src="https://cdn.jsdelivr.net/gh/honow48-tech/CodeBread@main/assets/map.png" alt="The Map view with one function selected and its call chain highlighted" width="880">
79
+ </p>
80
+
81
+ ### Code
82
+
83
+ Read any file with an outline and syntax highlighting, without leaving the page.
84
+
85
+ <p align="center">
86
+ <img src="https://cdn.jsdelivr.net/gh/honow48-tech/CodeBread@main/assets/code.png" alt="The Code view: file tree, function outline and highlighted source" width="880">
87
+ </p>
88
+
89
+ ### Context for AI assistants
90
+
91
+ An AI assistant that reads every file to understand a project spends most of
92
+ its tokens on code it never needed. CodeBread can write the map down instead:
93
+
94
+ ```bash
95
+ codebread --path ./my-project --md
96
+ ```
97
+
98
+ This creates `CODEBREAD.md` in the project: every route, table and function,
99
+ and who calls whom. On CodeBread's own repo it's about **13k tokens instead
100
+ of 83k** for the full source. The report has the same file one click away:
101
+ **Copy for AI** or **Download .md**.
102
+
103
+ ## Commands
104
+
105
+ | Flag | What it does |
106
+ |---|---|
107
+ | `--path, -p PATH` | Folder to scan (asks if you leave it out) |
108
+ | `--md [FILE]` | Write the AI context file (default: `CODEBREAD.md` in the scanned folder) |
109
+ | `--html FILE` | Export the report as one self-contained HTML file you can share |
110
+ | `--json FILE` | Save the scan as JSON |
111
+ | `--load FILE` | Open a saved JSON scan without scanning again |
112
+ | `--diff OLD NEW` | Compare two saved scans and print what changed |
113
+ | `--port 8137` | Port for the local server |
114
+ | `--no-open` | Don't open the browser |
115
+ | `--no-serve` | Scan and export only, no server |
116
+ | `--version` | Print the version |
117
+
118
+ Sharing a report with someone who doesn't have CodeBread:
119
+
120
+ ```bash
121
+ codebread --path . --html report.html --no-serve
122
+ ```
123
+
124
+ ## Languages
125
+
126
+ | Language | Functions | Routes | API calls | Database |
127
+ |---|:---:|:---:|:---:|:---:|
128
+ | Python | ✓ | Flask, FastAPI, Django | requests, httpx, aiohttp | SQLAlchemy, Django, peewee |
129
+ | JavaScript / TypeScript | ✓ | Express, Fastify, Koa, NestJS | fetch, axios | Prisma, Mongoose, Sequelize, Knex, TypeORM |
130
+ | Vue / Svelte | ✓ | same as JS | fetch, axios | same as JS |
131
+ | PHP | ✓ | Laravel | – | raw SQL |
132
+ | Java | ✓ | Spring | – | raw SQL |
133
+ | C# | ✓ | ASP.NET | – | raw SQL |
134
+ | Go | ✓ | Gin, net/http | – | raw SQL |
135
+ | Ruby | ✓ | Rails, Sinatra | – | raw SQL |
136
+ | SQL | – | – | – | `CREATE TABLE` schemas |
137
+
138
+ Files in other languages still appear in the file list, marked as unsupported.
139
+
140
+ <details>
141
+ <summary><b>Full parser details</b></summary>
142
+
143
+ <br>
144
+
145
+ Python is parsed with the standard-library `ast` module, so it also gets
146
+ parameter types, return types and docstrings. Every other language uses
147
+ structural regex with brace matching and gets parameter names only.
148
+
149
+ | Language | Parser | Functions | Classes | Routes | API calls | ORM models | Raw SQL | Call graph | Page links |
150
+ |---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
151
+ | Python | `ast` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – |
152
+ | JS / TS / JSX / TSX | regex | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – |
153
+ | Vue / Svelte | regex, `<script>` only | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – |
154
+ | Java | regex | ✓ | ✓ | ✓ | – | – | ✓ | ✓ | – |
155
+ | C# | regex | ✓ | ✓ | ✓ | – | – | ✓ | ✓ | – |
156
+ | Go | regex | ✓ | structs | ✓ | – | – | ✓ | ✓ | – |
157
+ | PHP | regex | ✓ | ✓ | ✓ | – | – | ✓ | ✓ | ✓ |
158
+ | Ruby | regex | ✓ | ✓ | ✓ | – | – | ✓ | ✓ | ✓ |
159
+ | SQL | regex | – | – | – | – | tables + columns | ✓ | – | – |
160
+ | Config (`.env`, json, yaml, toml, ini, xml) | key scan | – | – | – | – | – | – | – | – |
161
+
162
+ Config files are only scanned for database connection settings, and
163
+ credentials are always masked. Vue and Svelte templates (`@click`, `v-on`)
164
+ aren't parsed, only the `<script>` block.
165
+
166
+ </details>
167
+
168
+ ## How it works
169
+
170
+ CodeBread reads your files and never runs them. It finds functions, routes
171
+ and tables, then matches them up: a `fetch("/api/users")` in the frontend is
172
+ linked to the handler that serves `GET /api/users`, and that handler to the
173
+ `users` table it queries.
174
+
175
+ <details>
176
+ <summary><b>Layers, unused code and call cycles</b></summary>
177
+
178
+ <br>
179
+
180
+ - **Layers.** Each file is scored as frontend, backend, database or config
181
+ from its imports (React, Flask, Prisma…), its folder (`/client`,
182
+ `/server`, `/models`…) and what it contains (routes, models). Files that
183
+ don't clearly fit are left as *Unclassified* rather than guessed.
184
+ - **Unused functions.** Functions nothing calls are flagged, except route
185
+ handlers and entry points like `main` and test functions. It's a starting
186
+ point for finding dead code, not proof: calls the parser can't see are
187
+ missed.
188
+ - **Call cycles.** Functions that call each other in a loop are flagged on
189
+ the map and listed with the warnings.
190
+
191
+ </details>
192
+
193
+ <details>
194
+ <summary><b>Decoding obfuscated code</b></summary>
195
+
196
+ <br>
197
+
198
+ Some code, often bought or "nulled" PHP scripts, hides its strings behind
199
+ hex escapes, `chr()` arithmetic, base64 or junk statements. CodeBread decodes
200
+ these **without running anything**: it only evaluates integer literals and
201
+ basic operators inside a known decode call (`chr(...)`, `base64_decode(...)`),
202
+ and refuses anything else. Decoded values are underlined in the code view
203
+ (hover to see the original), and files with findings get a 🔓 badge.
204
+
205
+ | Language | Hex | Octal | Unicode | Char codes | Base64 | Junk code |
206
+ |---|:---:|:---:|:---:|:---:|:---:|:---:|
207
+ | Python | ✓ | ✓ | ✓ | `chr()` | `b64decode` | – |
208
+ | JS / TS / Vue / Svelte | ✓ | ✓ | ✓ | `fromCharCode` | `atob` | ✓ |
209
+ | Java | – | ✓ | ✓ | `(char)` | `Base64` | ✓ |
210
+ | C# | ✓ | – | ✓ | `(char)` | `FromBase64String` | ✓ |
211
+ | Go | ✓ | ✓ | ✓ | `rune()` | `base64` | ✓ |
212
+ | PHP | ✓ | ✓ | `\u{}` | `chr()` | `base64_decode` | ✓ |
213
+ | Ruby | ✓ | ✓ | ✓ | `.chr` | `decode64` | – |
214
+
215
+ Decoded text goes through the same credential masking as config files.
216
+ Junk-code detection needs `;`-terminated statements, so it's off for Python
217
+ and Ruby rather than guessing.
218
+
219
+ </details>
220
+
221
+ ## Safety
222
+
223
+ - Read-only. Nothing in the scanned project is ever executed.
224
+ - Secrets found in `.env` and config files are masked before they reach the
225
+ report, the JSON export or the AI context file.
226
+ - Runs on `localhost` only. No network calls, no telemetry.
227
+
228
+ Found a security issue? Please follow [SECURITY.md](SECURITY.md) instead of
229
+ opening a public issue.
230
+
231
+ ## Development
232
+
233
+ ```bash
234
+ git clone https://github.com/honow48-tech/CodeBread.git
235
+ cd CodeBread
236
+ pip install -e ".[full,test]"
237
+ pytest -q
238
+ ```
239
+
240
+ No build step: the analyzer is Python's standard library, and the UI is three
241
+ plain files in [`codebread/web/`](codebread/web) (HTML, CSS and vanilla
242
+ JavaScript). `pathspec` in the `full` extra is optional and only improves
243
+ `.gitignore` matching.
244
+
245
+ <details>
246
+ <summary><b>Project layout</b></summary>
247
+
248
+ ```
249
+ codebread.py run without installing: python codebread.py --path .
250
+ codebread/
251
+ cli.py command-line flags
252
+ scanner.py walks the folder, respects .gitignore
253
+ languages.py language detection
254
+ parsers/ Python (ast), JS/TS/Vue, and everything else
255
+ classifier.py frontend / backend / database / config scoring
256
+ connections.py call graph, API-to-route and function-to-table links
257
+ deobfuscate.py static decoding of obfuscated literals
258
+ analyzer.py runs the pipeline
259
+ context.py the AI context Markdown
260
+ diff.py compares two saved scans
261
+ export.py JSON and single-file HTML export
262
+ server.py local web server
263
+ web/ the UI
264
+ tests/ pytest suite with a small fixture project per language
265
+ ```
266
+
267
+ </details>
268
+
269
+ ## Contributing
270
+
271
+ Issues and pull requests are welcome, especially parser improvements for more
272
+ frameworks. Two rules keep the project easy to run: the core stays on the
273
+ Python standard library, and the UI stays plain JavaScript with no build
274
+ step. Please run `pytest -q` and add a fixture under `tests/` for new parser
275
+ behaviour.
276
+
277
+ ## License
278
+
279
+ [MIT](LICENSE)
@@ -0,0 +1,263 @@
1
+ <p align="center">
2
+ <img src="https://cdn.jsdelivr.net/gh/honow48-tech/CodeBread@main/assets/logo-wordmark.png" alt="CodeBread" width="320">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <b>See how any codebase is wired together.</b><br>
7
+ Files, functions, API routes and database tables, mapped in your browser.
8
+ </p>
9
+
10
+ <p align="center">
11
+ An interactive codebase visualizer: call graph, dependency map and API-to-database tracing<br>
12
+ for Python, JavaScript, TypeScript, PHP, Java, Go, C# and Ruby.
13
+ </p>
14
+
15
+ <p align="center">
16
+ <a href="https://pypi.org/project/codebread/"><img alt="PyPI" src="https://img.shields.io/pypi/v/codebread?color=b0541c&label=pypi"></a>
17
+ <a href="https://github.com/honow48-tech/CodeBread/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/honow48-tech/CodeBread/actions/workflows/ci.yml/badge.svg"></a>
18
+ <img alt="Python 3.9+" src="https://img.shields.io/badge/python-3.9%2B-5f5c55">
19
+ <img alt="No dependencies" src="https://img.shields.io/badge/dependencies-none-5f5c55">
20
+ <img alt="MIT" src="https://img.shields.io/badge/license-MIT-5f5c55">
21
+ </p>
22
+
23
+ <p align="center">
24
+ <img src="https://cdn.jsdelivr.net/gh/honow48-tech/CodeBread@main/assets/overview.gif" alt="The CodeBread overview: project totals, a language breakdown, and a file table that previews each file on hover" width="880">
25
+ </p>
26
+
27
+ ## Quick start
28
+
29
+ ```bash
30
+ pip install codebread
31
+ codebread --path ./my-project
32
+ ```
33
+
34
+ A browser tab opens with the project already mapped. Everything runs on your
35
+ machine: nothing is uploaded, and nothing in the scanned project is executed.
36
+
37
+ ## What you get
38
+
39
+ ### Overview
40
+
41
+ Totals, a breakdown of the project by language, and every file in one table.
42
+ Hover a row to preview what the file contains and what it talks to.
43
+
44
+ ### Connections
45
+
46
+ Pick a file to see what uses it, what it uses, and which functions are
47
+ linked. Click a neighbour to follow the trail; a breadcrumb takes you back.
48
+ It only ever draws one file's neighbourhood, so it stays readable on a
49
+ project with thousands of files.
50
+
51
+ <p align="center">
52
+ <img src="https://cdn.jsdelivr.net/gh/honow48-tech/CodeBread@main/assets/connections.gif" alt="The Connections page: callers on the left, the selected file in the middle, the files it uses on the right, joined function to function" width="880">
53
+ </p>
54
+
55
+ ### Map
56
+
57
+ The whole project as a graph. Click a file to open it into its functions.
58
+ Click a function to light up everything it calls and everything that calls
59
+ it, all the way from a frontend `fetch()` to the database table.
60
+
61
+ <p align="center">
62
+ <img src="https://cdn.jsdelivr.net/gh/honow48-tech/CodeBread@main/assets/map.png" alt="The Map view with one function selected and its call chain highlighted" width="880">
63
+ </p>
64
+
65
+ ### Code
66
+
67
+ Read any file with an outline and syntax highlighting, without leaving the page.
68
+
69
+ <p align="center">
70
+ <img src="https://cdn.jsdelivr.net/gh/honow48-tech/CodeBread@main/assets/code.png" alt="The Code view: file tree, function outline and highlighted source" width="880">
71
+ </p>
72
+
73
+ ### Context for AI assistants
74
+
75
+ An AI assistant that reads every file to understand a project spends most of
76
+ its tokens on code it never needed. CodeBread can write the map down instead:
77
+
78
+ ```bash
79
+ codebread --path ./my-project --md
80
+ ```
81
+
82
+ This creates `CODEBREAD.md` in the project: every route, table and function,
83
+ and who calls whom. On CodeBread's own repo it's about **13k tokens instead
84
+ of 83k** for the full source. The report has the same file one click away:
85
+ **Copy for AI** or **Download .md**.
86
+
87
+ ## Commands
88
+
89
+ | Flag | What it does |
90
+ |---|---|
91
+ | `--path, -p PATH` | Folder to scan (asks if you leave it out) |
92
+ | `--md [FILE]` | Write the AI context file (default: `CODEBREAD.md` in the scanned folder) |
93
+ | `--html FILE` | Export the report as one self-contained HTML file you can share |
94
+ | `--json FILE` | Save the scan as JSON |
95
+ | `--load FILE` | Open a saved JSON scan without scanning again |
96
+ | `--diff OLD NEW` | Compare two saved scans and print what changed |
97
+ | `--port 8137` | Port for the local server |
98
+ | `--no-open` | Don't open the browser |
99
+ | `--no-serve` | Scan and export only, no server |
100
+ | `--version` | Print the version |
101
+
102
+ Sharing a report with someone who doesn't have CodeBread:
103
+
104
+ ```bash
105
+ codebread --path . --html report.html --no-serve
106
+ ```
107
+
108
+ ## Languages
109
+
110
+ | Language | Functions | Routes | API calls | Database |
111
+ |---|:---:|:---:|:---:|:---:|
112
+ | Python | ✓ | Flask, FastAPI, Django | requests, httpx, aiohttp | SQLAlchemy, Django, peewee |
113
+ | JavaScript / TypeScript | ✓ | Express, Fastify, Koa, NestJS | fetch, axios | Prisma, Mongoose, Sequelize, Knex, TypeORM |
114
+ | Vue / Svelte | ✓ | same as JS | fetch, axios | same as JS |
115
+ | PHP | ✓ | Laravel | – | raw SQL |
116
+ | Java | ✓ | Spring | – | raw SQL |
117
+ | C# | ✓ | ASP.NET | – | raw SQL |
118
+ | Go | ✓ | Gin, net/http | – | raw SQL |
119
+ | Ruby | ✓ | Rails, Sinatra | – | raw SQL |
120
+ | SQL | – | – | – | `CREATE TABLE` schemas |
121
+
122
+ Files in other languages still appear in the file list, marked as unsupported.
123
+
124
+ <details>
125
+ <summary><b>Full parser details</b></summary>
126
+
127
+ <br>
128
+
129
+ Python is parsed with the standard-library `ast` module, so it also gets
130
+ parameter types, return types and docstrings. Every other language uses
131
+ structural regex with brace matching and gets parameter names only.
132
+
133
+ | Language | Parser | Functions | Classes | Routes | API calls | ORM models | Raw SQL | Call graph | Page links |
134
+ |---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
135
+ | Python | `ast` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – |
136
+ | JS / TS / JSX / TSX | regex | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – |
137
+ | Vue / Svelte | regex, `<script>` only | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – |
138
+ | Java | regex | ✓ | ✓ | ✓ | – | – | ✓ | ✓ | – |
139
+ | C# | regex | ✓ | ✓ | ✓ | – | – | ✓ | ✓ | – |
140
+ | Go | regex | ✓ | structs | ✓ | – | – | ✓ | ✓ | – |
141
+ | PHP | regex | ✓ | ✓ | ✓ | – | – | ✓ | ✓ | ✓ |
142
+ | Ruby | regex | ✓ | ✓ | ✓ | – | – | ✓ | ✓ | ✓ |
143
+ | SQL | regex | – | – | – | – | tables + columns | ✓ | – | – |
144
+ | Config (`.env`, json, yaml, toml, ini, xml) | key scan | – | – | – | – | – | – | – | – |
145
+
146
+ Config files are only scanned for database connection settings, and
147
+ credentials are always masked. Vue and Svelte templates (`@click`, `v-on`)
148
+ aren't parsed, only the `<script>` block.
149
+
150
+ </details>
151
+
152
+ ## How it works
153
+
154
+ CodeBread reads your files and never runs them. It finds functions, routes
155
+ and tables, then matches them up: a `fetch("/api/users")` in the frontend is
156
+ linked to the handler that serves `GET /api/users`, and that handler to the
157
+ `users` table it queries.
158
+
159
+ <details>
160
+ <summary><b>Layers, unused code and call cycles</b></summary>
161
+
162
+ <br>
163
+
164
+ - **Layers.** Each file is scored as frontend, backend, database or config
165
+ from its imports (React, Flask, Prisma…), its folder (`/client`,
166
+ `/server`, `/models`…) and what it contains (routes, models). Files that
167
+ don't clearly fit are left as *Unclassified* rather than guessed.
168
+ - **Unused functions.** Functions nothing calls are flagged, except route
169
+ handlers and entry points like `main` and test functions. It's a starting
170
+ point for finding dead code, not proof: calls the parser can't see are
171
+ missed.
172
+ - **Call cycles.** Functions that call each other in a loop are flagged on
173
+ the map and listed with the warnings.
174
+
175
+ </details>
176
+
177
+ <details>
178
+ <summary><b>Decoding obfuscated code</b></summary>
179
+
180
+ <br>
181
+
182
+ Some code, often bought or "nulled" PHP scripts, hides its strings behind
183
+ hex escapes, `chr()` arithmetic, base64 or junk statements. CodeBread decodes
184
+ these **without running anything**: it only evaluates integer literals and
185
+ basic operators inside a known decode call (`chr(...)`, `base64_decode(...)`),
186
+ and refuses anything else. Decoded values are underlined in the code view
187
+ (hover to see the original), and files with findings get a 🔓 badge.
188
+
189
+ | Language | Hex | Octal | Unicode | Char codes | Base64 | Junk code |
190
+ |---|:---:|:---:|:---:|:---:|:---:|:---:|
191
+ | Python | ✓ | ✓ | ✓ | `chr()` | `b64decode` | – |
192
+ | JS / TS / Vue / Svelte | ✓ | ✓ | ✓ | `fromCharCode` | `atob` | ✓ |
193
+ | Java | – | ✓ | ✓ | `(char)` | `Base64` | ✓ |
194
+ | C# | ✓ | – | ✓ | `(char)` | `FromBase64String` | ✓ |
195
+ | Go | ✓ | ✓ | ✓ | `rune()` | `base64` | ✓ |
196
+ | PHP | ✓ | ✓ | `\u{}` | `chr()` | `base64_decode` | ✓ |
197
+ | Ruby | ✓ | ✓ | ✓ | `.chr` | `decode64` | – |
198
+
199
+ Decoded text goes through the same credential masking as config files.
200
+ Junk-code detection needs `;`-terminated statements, so it's off for Python
201
+ and Ruby rather than guessing.
202
+
203
+ </details>
204
+
205
+ ## Safety
206
+
207
+ - Read-only. Nothing in the scanned project is ever executed.
208
+ - Secrets found in `.env` and config files are masked before they reach the
209
+ report, the JSON export or the AI context file.
210
+ - Runs on `localhost` only. No network calls, no telemetry.
211
+
212
+ Found a security issue? Please follow [SECURITY.md](SECURITY.md) instead of
213
+ opening a public issue.
214
+
215
+ ## Development
216
+
217
+ ```bash
218
+ git clone https://github.com/honow48-tech/CodeBread.git
219
+ cd CodeBread
220
+ pip install -e ".[full,test]"
221
+ pytest -q
222
+ ```
223
+
224
+ No build step: the analyzer is Python's standard library, and the UI is three
225
+ plain files in [`codebread/web/`](codebread/web) (HTML, CSS and vanilla
226
+ JavaScript). `pathspec` in the `full` extra is optional and only improves
227
+ `.gitignore` matching.
228
+
229
+ <details>
230
+ <summary><b>Project layout</b></summary>
231
+
232
+ ```
233
+ codebread.py run without installing: python codebread.py --path .
234
+ codebread/
235
+ cli.py command-line flags
236
+ scanner.py walks the folder, respects .gitignore
237
+ languages.py language detection
238
+ parsers/ Python (ast), JS/TS/Vue, and everything else
239
+ classifier.py frontend / backend / database / config scoring
240
+ connections.py call graph, API-to-route and function-to-table links
241
+ deobfuscate.py static decoding of obfuscated literals
242
+ analyzer.py runs the pipeline
243
+ context.py the AI context Markdown
244
+ diff.py compares two saved scans
245
+ export.py JSON and single-file HTML export
246
+ server.py local web server
247
+ web/ the UI
248
+ tests/ pytest suite with a small fixture project per language
249
+ ```
250
+
251
+ </details>
252
+
253
+ ## Contributing
254
+
255
+ Issues and pull requests are welcome, especially parser improvements for more
256
+ frameworks. Two rules keep the project easy to run: the core stays on the
257
+ Python standard library, and the UI stays plain JavaScript with no build
258
+ step. Please run `pytest -q` and add a fixture under `tests/` for new parser
259
+ behaviour.
260
+
261
+ ## License
262
+
263
+ [MIT](LICENSE)
@@ -0,0 +1,40 @@
1
+ """CodeBread — slice open a codebase and see its internal structure."""
2
+ from __future__ import annotations
3
+
4
+ import os
5
+ import re
6
+
7
+
8
+ def _read_version() -> str:
9
+ """Single source of truth: pyproject.toml's [project] version.
10
+
11
+ A source checkout (pyproject.toml sitting next to the package) wins:
12
+ an editable `pip install -e .` freezes its metadata at install time,
13
+ so after a version bump importlib.metadata keeps reporting the old
14
+ number until you reinstall. Wheel installs have no pyproject.toml
15
+ beside them and fall through to their own (always correct) metadata.
16
+ No toml parser needed for one `version = "..."` line — keeps the
17
+ zero-dependency promise.
18
+ """
19
+ root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
20
+ try:
21
+ with open(os.path.join(root, "pyproject.toml"), encoding="utf-8") as f:
22
+ text = f.read()
23
+ if re.search(r"""^name\s*=\s*["']codebread["']""", text, re.M):
24
+ m = re.search(r"""^version\s*=\s*["']([^"']+)["']""", text, re.M)
25
+ if m:
26
+ return m.group(1)
27
+ except OSError:
28
+ pass
29
+ try:
30
+ from importlib.metadata import PackageNotFoundError, version
31
+ try:
32
+ return version("codebread")
33
+ except PackageNotFoundError:
34
+ pass
35
+ except ImportError:
36
+ pass
37
+ return "0.0.0+unknown"
38
+
39
+
40
+ __version__ = _read_version()
@@ -37,6 +37,11 @@ def main(argv=None) -> int:
37
37
  help="also export the full graph as JSON")
38
38
  parser.add_argument("--html", metavar="OUT.html",
39
39
  help="also export a self-contained static HTML file")
40
+ parser.add_argument("--md", nargs="?", const="", metavar="OUT.md",
41
+ help="also write an AI context brief (Markdown) - a "
42
+ "compact map of the project an assistant can read "
43
+ "instead of every file. Default: CODEBREAD.md in "
44
+ "the scanned folder")
40
45
  parser.add_argument("--no-open", action="store_true",
41
46
  help="don't auto-open the browser")
42
47
  parser.add_argument("--no-serve", action="store_true",
@@ -89,6 +94,14 @@ def main(argv=None) -> int:
89
94
  print(f"[codebread] {graph['stats']['warnings']} warning(s) - "
90
95
  f"they are shown as badges in the UI, nothing was hidden.")
91
96
 
97
+ from .context import export_markdown, to_markdown
98
+ graph["contextMd"] = to_markdown(graph) # powers the report's "Copy for AI" / download
99
+ if args.md is not None:
100
+ default_dir = graph.get("meta", {}).get("root") or os.getcwd()
101
+ if not os.path.isdir(default_dir): # --load of a graph scanned elsewhere
102
+ default_dir = os.getcwd()
103
+ p = export_markdown(graph, args.md or os.path.join(default_dir, "CODEBREAD.md"))
104
+ print(f"[codebread] AI context brief written to {p}")
92
105
  if args.json:
93
106
  p = export_json(graph, args.json)
94
107
  print(f"[codebread] Graph JSON written to {p}")