tree2guide 1.0.0__py3-none-any.whl

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.
@@ -0,0 +1,475 @@
1
+ Metadata-Version: 2.4
2
+ Name: tree2guide
3
+ Version: 1.0.0
4
+ Summary: See your project structure clearly — a tree generator with gitignore-compatible exclusion, multi-format output, and AI-ready summaries.
5
+ Author: Lawrence Roble
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Lawrence Roble (@law4percent)
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/law4percent/tree2guide
29
+ Project-URL: Repository, https://github.com/law4percent/tree2guide
30
+ Project-URL: Issues, https://github.com/law4percent/tree2guide/issues
31
+ Project-URL: Documentation, https://law4percent.github.io/tree2guide/
32
+ Keywords: tree,markdown,documentation,cli,gitignore,project-structure,json,yaml,html,llm
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Environment :: Console
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.9
39
+ Classifier: Programming Language :: Python :: 3.10
40
+ Classifier: Programming Language :: Python :: 3.11
41
+ Classifier: Programming Language :: Python :: 3.12
42
+ Classifier: Topic :: Documentation
43
+ Classifier: Topic :: Software Development :: Documentation
44
+ Classifier: Topic :: Utilities
45
+ Requires-Python: >=3.9
46
+ Description-Content-Type: text/markdown
47
+ License-File: LICENSE
48
+ Provides-Extra: dev
49
+ Requires-Dist: pytest>=7.0; extra == "dev"
50
+ Dynamic: license-file
51
+
52
+ # tree2guide
53
+
54
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/law4percent/tree2guide/blob/main/LICENSE)
55
+ [![Python](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/)
56
+
57
+ **Understand your project's structure in seconds.**
58
+
59
+ Generate clean project trees, AI-ready summaries, and reusable documentation from any directory — all with zero dependencies.
60
+
61
+ **Author:** Lawrence Roble ([@law4percent](https://github.com/law4percent))
62
+ Open-source, MIT licensed. Contributions, issues, and pull requests are welcome.
63
+
64
+ ---
65
+
66
+ ## Why this exists
67
+
68
+ I'm a solo developer and self-learner. I don't always have time to study every architectural principle before I start building. What I *can* do is look at the shape of my own project.
69
+
70
+ **tree2guide** is the tool I built for that — a quick way to visualize my folder structure, notice when something's drifting into spaghetti, and decide for myself whether I'm actually following good separation of concerns, or just telling myself I am.
71
+
72
+ It turned out to be genuinely useful for other things too — documentation, onboarding, PR descriptions, AI prompts — so it grew into a general-purpose tool. But that's not why it exists. It exists to help developers like me catch bad structure early, without needing to be an expert first.
73
+
74
+ > tree2guide starts as a project structure generator, but its long-term vision is to become the foundation for project understanding — providing structured representations that can power documentation, analysis, automation, and intelligent developer tools.
75
+
76
+ ---
77
+
78
+ ## Why not just use `tree`?
79
+
80
+ | Feature | `tree` | tree2guide |
81
+ |---|:---:|:---:|
82
+ | Markdown output | ❌ | ✅ |
83
+ | HTML output (collapsible) | ❌ | ✅ |
84
+ | JSON output | ❌ | ✅ |
85
+ | YAML output | ❌ | ✅ |
86
+ | AI-ready summary | ❌ | ✅ |
87
+ | `.tree2ignore` (gitignore-style) | ❌ | ✅ |
88
+ | Python library API | ❌ | ✅ |
89
+ | Cross-platform | ⚠️ | ✅ |
90
+ | Zero dependencies | N/A | ✅ |
91
+
92
+ ---
93
+
94
+ ## Example Output
95
+
96
+ Running `tree2guide src --stdout`:
97
+
98
+ ```
99
+ src/
100
+ ├── tree2guide/
101
+ │ ├── renderers/
102
+ │ │ ├── __init__.py
103
+ │ │ ├── html.py
104
+ │ │ ├── json_renderer.py
105
+ │ │ ├── llm.py
106
+ │ │ ├── markdown.py
107
+ │ │ ├── text.py
108
+ │ │ └── yaml_renderer.py
109
+ │ ├── __init__.py
110
+ │ ├── cli.py
111
+ │ ├── ignore.py
112
+ │ ├── llm.py
113
+ │ └── scanner.py
114
+ ```
115
+
116
+ Running `tree2guide . --llm --stdout`:
117
+
118
+ ```
119
+ ============================================================
120
+ PROJECT STRUCTURE SUMMARY: tree2guide
121
+ ============================================================
122
+
123
+ DETECTED STACK / LANGUAGE:
124
+ - Python (pyproject.toml)
125
+
126
+ SIZE:
127
+ Files : 18
128
+ Directories: 4
129
+
130
+ TOP-LEVEL LAYOUT:
131
+ Directories:
132
+ src/
133
+ tests/
134
+ docs/
135
+ Files:
136
+ pyproject.toml
137
+ README.md
138
+ LICENSE
139
+
140
+ NOTABLE FLAGS:
141
+ - Tests directory present
142
+ - GitHub Actions / workflows present
143
+ - LICENSE file present
144
+ - CHANGELOG present
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Philosophy
150
+
151
+ tree2guide follows a few simple principles:
152
+
153
+ - **One scan, many outputs.** The filesystem is walked once; any renderer can consume the result.
154
+ - **Zero third-party dependencies.** Always. `pip install tree2guide` is instant.
155
+ - **Human-readable first.** Markdown is the default because humans read it everywhere.
156
+ - **AI-ready by design.** The `--llm` flag produces structured output optimised for AI context windows.
157
+ - **CLI and library.** Every feature available on the command line is also available as a Python API.
158
+ - **Never reads file contents.** Only structure and filenames — your code stays on your machine.
159
+
160
+ ---
161
+
162
+ ## Privacy
163
+
164
+ tree2guide operates entirely on your local machine.
165
+
166
+ It **does**:
167
+ - ✅ Read directory structure and filenames
168
+ - ✅ Apply ignore rules
169
+ - ✅ Generate output locally
170
+
171
+ It **does not**:
172
+ - ❌ Read file contents
173
+ - ❌ Upload anything
174
+ - ❌ Require an internet connection
175
+ - ❌ Collect telemetry
176
+ - ❌ Send data to any AI service
177
+
178
+ ---
179
+
180
+ ## Installation
181
+
182
+ ```bash
183
+ pip install tree2guide
184
+ ```
185
+
186
+ Requires Python 3.9+, no other dependencies. Installs a `tree2guide` command directly — no `python` prefix needed.
187
+
188
+ ### Development setup (for contributors)
189
+
190
+ **macOS / Linux**
191
+ ```bash
192
+ cd tree2guide_pkg
193
+ python3 -m venv venv
194
+ source venv/bin/activate
195
+ pip install -e ".[dev]"
196
+ ```
197
+
198
+ **Windows**
199
+ ```bat
200
+ cd tree2guide_pkg
201
+ python -m venv venv
202
+ venv\Scripts\activate
203
+ pip install -e ".[dev]"
204
+ ```
205
+
206
+ ---
207
+
208
+ ## Quick Start
209
+
210
+ ```bash
211
+ # Markdown output (default) — writes docs_tree.md
212
+ tree2guide docs
213
+
214
+ # Plain text
215
+ tree2guide . --format text
216
+
217
+ # JSON
218
+ tree2guide . --format json
219
+
220
+ # Self-contained HTML with collapsible folders
221
+ tree2guide . --format html
222
+
223
+ # AI-ready project summary (no network call, no API key)
224
+ tree2guide . --llm
225
+
226
+ # Print to stdout instead of writing a file
227
+ tree2guide . --stdout
228
+
229
+ # Pipe to clipboard
230
+ tree2guide . --stdout | pbcopy # macOS
231
+ tree2guide . --stdout | clip # Windows
232
+ ```
233
+
234
+ ---
235
+
236
+ ## Command Reference
237
+
238
+ ```bash
239
+ tree2guide <target_folder> [options]
240
+ ```
241
+
242
+ | Flag | Description |
243
+ |---|---|
244
+ | `-o`, `--output` | Output file path (default: `<folder>_tree.<ext>` based on format) |
245
+ | `--exclude-file` | Use a specific exclude file instead of auto-detecting `.tree2ignore` |
246
+ | `--title` | Add a heading above the tree |
247
+ | `--no-footer` | Omit the author/license footer (markdown and html only) |
248
+ | `--stdout` | Print to stdout instead of writing a file |
249
+ | `--format {markdown,text,json,yaml,html,llm}` | Output format (default: `markdown`) |
250
+ | `--llm` | Shorthand for `--format llm` — AI-friendly project summary |
251
+ | `--max-depth N` | Limit recursion depth |
252
+ | `--dirs-only` | Only show directories |
253
+ | `--files-only` | Only show files (directories shown as scaffolding only) |
254
+ | `--no-hidden` | Skip dotfiles/dotfolders without needing `.tree2ignore` entries |
255
+ | `--sort {dirs-first,files-first,alpha}` | Sort order within each folder (default: `dirs-first`) |
256
+
257
+ Symlinks are rendered as `name -> target` and never followed — avoids infinite loops.
258
+
259
+ ### Default output filenames
260
+
261
+ | Format | Output file |
262
+ |---|---|
263
+ | `markdown` | `<folder>_tree.md` |
264
+ | `text` | `<folder>_tree.txt` |
265
+ | `json` | `<folder>_tree.json` |
266
+ | `yaml` | `<folder>_tree.yaml` |
267
+ | `html` | `<folder>_tree.html` |
268
+ | `llm` | `<folder>_llm.txt` |
269
+
270
+ ---
271
+
272
+ ## The `.tree2ignore` file
273
+
274
+ ### The #1 rule: where it goes
275
+
276
+ **`.tree2ignore` must sit directly inside the folder you pass as the target.**
277
+ Patterns are written relative to that folder — never include the target folder's name as a prefix.
278
+
279
+ ```bash
280
+ # .tree2ignore lives at docs/.tree2ignore
281
+ tree2guide docs
282
+ ```
283
+
284
+ ```
285
+ # correct — relative to docs/
286
+ api
287
+ _drafts
288
+
289
+ # wrong — only correct if you ran: tree2guide .
290
+ docs/api
291
+ docs/_drafts
292
+ ```
293
+
294
+ ### Pattern syntax (real `.gitignore` rules)
295
+
296
+ | Pattern | Meaning |
297
+ |---|---|
298
+ | `build` | Matches a file or folder named `build` at any depth |
299
+ | `build/` | Same, but only matches directories |
300
+ | `/build` | Matches `build` only at the root of the target (anchored) |
301
+ | `*.log` | Matches all files ending in `.log`, anywhere |
302
+ | `**/android/key.properties` | Matches that exact path at any depth |
303
+ | `!keep-this` | Negates — re-includes something an earlier rule excluded |
304
+ | `# comment` | Ignored |
305
+
306
+ Patterns evaluate top to bottom — later rules override earlier ones, same as Git.
307
+
308
+ ### Whitelist example
309
+
310
+ Show only `admin/`, hide everything else:
311
+
312
+ ```
313
+ *
314
+ !admin
315
+ !admin/**
316
+ ```
317
+
318
+ ### Copy your `.gitignore` directly
319
+
320
+ The matching engine reimplements Git's rules exactly — copy your `.gitignore` into `.tree2ignore` and it will behave identically.
321
+
322
+ ---
323
+
324
+ ## Defaults (always excluded, no setup needed)
325
+
326
+ - `.git`
327
+ - `.tree2ignore`
328
+ - `__pycache__`
329
+ - `*.pyc`
330
+ - `.DS_Store`
331
+
332
+ ---
333
+
334
+ ## Library API
335
+
336
+ `tree2guide` works as an importable library, not just a CLI:
337
+
338
+ ```python
339
+ import tree2guide
340
+ from pathlib import Path
341
+
342
+ root = Path("./my-project").resolve()
343
+ patterns = tree2guide.load_exclude_patterns(root / tree2guide.EXCLUDE_FILENAME)
344
+ matcher = tree2guide.ExcludeMatcher(patterns)
345
+
346
+ # Build the tree once
347
+ tree = tree2guide.build_node_tree(root, matcher)
348
+
349
+ # Render to any format
350
+ print(tree2guide.render_markdown(tree, title="My Project"))
351
+ print(tree2guide.render_text(tree))
352
+ print(tree2guide.render_json(tree))
353
+ print(tree2guide.render_yaml(tree))
354
+ print(tree2guide.render_html(tree, title="My Project"))
355
+ print(tree2guide.render_llm(tree, title="My Project"))
356
+
357
+ # Get the heuristic summary directly
358
+ summary = tree2guide.analyze(tree)
359
+ print(summary.detected_stack)
360
+ print(summary.file_count, summary.dir_count)
361
+ print(summary.notable_flags)
362
+ ```
363
+
364
+ ### Public API surface
365
+
366
+ | Name | Description |
367
+ |---|---|
368
+ | `build_node_tree(root, matcher, options=None)` | Scan filesystem → `TreeNode` |
369
+ | `build_tree(root, matcher, options=None)` | Backward-compatible wrapper → `list[str]` |
370
+ | `TreeNode` | Internal tree model (dataclass) |
371
+ | `TreeOptions` | Scanner options (max_depth, dirs_only, sort, etc.) |
372
+ | `ExcludeMatcher` | Evaluates `.tree2ignore` patterns |
373
+ | `GitignoreRule` | Single compiled pattern rule |
374
+ | `load_exclude_patterns(path)` | Parse a `.tree2ignore` file |
375
+ | `analyze(node)` | Heuristic analysis → `LlmSummary` |
376
+ | `LlmSummary` | Detected stack, file/dir counts, notable flags |
377
+ | `render_markdown(tree, ...)` | Markdown string |
378
+ | `render_text(tree, ...)` | Plain text string |
379
+ | `render_json(tree)` | JSON string |
380
+ | `render_yaml(tree)` | YAML string |
381
+ | `render_html(tree, ...)` | Self-contained HTML string |
382
+ | `render_llm(tree, ...)` | LLM-optimised plain text string |
383
+
384
+ ---
385
+
386
+ ## Project Structure
387
+
388
+ ```
389
+ tree2guide_pkg/
390
+ ├── .github/
391
+ │ └── workflows/
392
+ │ └── ci.yml
393
+ ├── docs/ # GitHub Pages docs site
394
+ │ ├── _config.yml
395
+ │ ├── index.md
396
+ │ ├── installation.md
397
+ │ ├── quickstart.md
398
+ │ ├── tree2ignore.md
399
+ │ ├── cli.md
400
+ │ ├── examples.md
401
+ │ ├── api.md
402
+ │ └── contributing.md
403
+ ├── src/
404
+ │ └── tree2guide/
405
+ │ ├── __init__.py # public API surface
406
+ │ ├── cli.py # argparse + entry point
407
+ │ ├── ignore.py # GitignoreRule, ExcludeMatcher
408
+ │ ├── llm.py # analyze(), LlmSummary
409
+ │ ├── scanner.py # build_node_tree(), TreeNode, TreeOptions
410
+ │ └── renderers/
411
+ │ ├── __init__.py
412
+ │ ├── html.py
413
+ │ ├── json_renderer.py
414
+ │ ├── llm.py
415
+ │ ├── markdown.py
416
+ │ ├── text.py
417
+ │ └── yaml_renderer.py
418
+ ├── tests/
419
+ │ ├── test_ignore.py
420
+ │ ├── test_llm.py
421
+ │ ├── test_markdown_renderer.py
422
+ │ ├── test_renderers.py
423
+ │ └── test_scanner.py
424
+ ├── CHANGELOG.md
425
+ ├── LICENSE
426
+ ├── README.md
427
+ └── pyproject.toml
428
+ ```
429
+
430
+ Architecture: **Scanner → Tree Model → Renderer**. The scanner builds a `TreeNode` once; each renderer transforms the same object into a different format. Adding a new output format means writing a new renderer — no changes to the scanner or CLI needed.
431
+
432
+ ---
433
+
434
+ ## Troubleshooting
435
+
436
+ **"No exclude file found at .../.tree2ignore"**
437
+ → `.tree2ignore` must be directly inside the folder you passed as the target.
438
+
439
+ **Patterns aren't excluding anything**
440
+ → Check for a stray prefix. If you ran `tree2guide docs`, write `api` not `docs/api`.
441
+
442
+ **I want to exclude everything except one folder**
443
+ ```
444
+ *
445
+ !keepme
446
+ !keepme/**
447
+ ```
448
+
449
+ **`--stdout` produces garbled characters on Windows**
450
+ → Pipe directly to clipboard instead: `tree2guide . --stdout | clip`
451
+
452
+ ---
453
+
454
+ ## Contributing
455
+
456
+ Pull requests, feature ideas, and bug reports are welcome.
457
+ See [CONTRIBUTING](https://github.com/law4percent/tree2guide?tab=contributing-ov-file) for the full guide, architecture walkthrough, and how to add a new renderer or stack signal.
458
+
459
+ Open stretch goals:
460
+ - Browser playground (Pyodide/WASM)
461
+ - Interactive HTML viewer from JSON output
462
+ - `--format csv` — flat path list with type column
463
+ - File size annotations
464
+ - Character class patterns in `.tree2ignore` (`[abc]`, `[!abc]`)
465
+ - Windows CI in the test matrix
466
+
467
+ ---
468
+
469
+ ## License
470
+
471
+ MIT — see [LICENSE](LICENSE) for details.
472
+
473
+ ---
474
+
475
+ *Built and maintained by [Lawrence Roble](https://github.com/law4percent).*
@@ -0,0 +1,18 @@
1
+ tree2guide/__init__.py,sha256=gLEDXuZLOTLTr72z0QK2VbsAYxNCcWsfhUBRn5J7Ylk,1414
2
+ tree2guide/cli.py,sha256=vrqWhtnMjJpKi7_w5lPF0rWbZLhLh124PrgYxrmjXD8,4994
3
+ tree2guide/ignore.py,sha256=PJBsT9n0gpGDVWj7EwvMpgGE8-_CudcG69Hk-mdWvak,2885
4
+ tree2guide/llm.py,sha256=E6LFtaubmkRUBZljlA76o6DY_Ce-Ngn7MCo0mtapaC4,7903
5
+ tree2guide/scanner.py,sha256=FV5tmj1mmnoSbbf8Y_4iBdUoav77_-RzJbn4SfAD9Xc,4774
6
+ tree2guide/renderers/__init__.py,sha256=9hoeaaDamF7uOXlefeEBgUZCbVbl68cE5CT79-GPJXU,283
7
+ tree2guide/renderers/html.py,sha256=l3g1P36bRGHNUwBMnaqT4CBbst0ksUJqk4wXQ8oG6Pk,6886
8
+ tree2guide/renderers/json_renderer.py,sha256=gh7EoTnXKKqNYFNyX0DF7cuLgDGiIy-HtXCtcw16ueM,1407
9
+ tree2guide/renderers/llm.py,sha256=HX27BKmGtY_bguai68NvfAyWa_GH40LRG_I9U-LSl3c,2904
10
+ tree2guide/renderers/markdown.py,sha256=_RaIyw2dX2db7jxRTWxzv3Oo2PH2D7d95dOWI_w7JAw,1039
11
+ tree2guide/renderers/text.py,sha256=VgpAkBDixDQwfeK2kRlJk1ZWjALpcAWNkzQQgqakli4,925
12
+ tree2guide/renderers/yaml_renderer.py,sha256=FLIJeEegTj39OT1duPqqWt3kb4SxONPyWjKuRYBwkNM,2043
13
+ tree2guide-1.0.0.dist-info/licenses/LICENSE,sha256=EFfa-1By8tbtJviVt4PpnWOSf1ofiUVY0PJwu9QL9iM,1086
14
+ tree2guide-1.0.0.dist-info/METADATA,sha256=M5b6Fj3v_Sc57OplsiRoF0Gei7jSp6TA3d6SjtI_YlA,15388
15
+ tree2guide-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
16
+ tree2guide-1.0.0.dist-info/entry_points.txt,sha256=Ew9Of3QKG8JIO3_iCMX5kiHB_9FfyRusH_-bAfwiWvE,51
17
+ tree2guide-1.0.0.dist-info/top_level.txt,sha256=sr16BeMsxMpYZNJpUddvDmVjAMYMXZm2lmBrgKbCUew,11
18
+ tree2guide-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ tree2guide = tree2guide.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Lawrence Roble (@law4percent)
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.
@@ -0,0 +1 @@
1
+ tree2guide