algorembrant commited on
Commit
2db20ba
·
verified ·
1 Parent(s): abc9785

Upload 6 files

Browse files
README.md ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # filesystem-auditor
2
+
3
+ ## Description
4
+ `filesystem-auditor` is a pair of high-performance Python scripts designed to scan and analyze repository structures and tech stacks. It handles massive filesystems efficiently using `os.scandir` and provides detailed Markdown-formatted audits of file types, counts, and sizes. Look at `example_output\` forlder for examples.
5
+
6
+ ![license](https://img.shields.io/badge/license-MIT-blue)
7
+ ![reposize](https://img.shields.io/badge/reposize-29.6%20KB-brightgreen)
8
+ ![last-commit](https://img.shields.io/badge/last--commit-2026--02--28-orange)
9
+ ![language-python](https://img.shields.io/badge/language-Python-blue)
10
+
11
+ ## System Overview
12
+
13
+ ```mermaid
14
+ graph TD
15
+ A[Repository Path] --> B{Action}
16
+ B -->|Structure Scan| C[scan_structure.py]
17
+ B -->|Techstack Scan| D[scan_techstack.py]
18
+ C --> E[STRUCTURE.md]
19
+ D --> F[TECHSTACK.md]
20
+ E --> G[Visual Documentation]
21
+ F --> G
22
+ ```
23
+
24
+ ## Project Structure
25
+
26
+ ```text
27
+ filesystem-auditor (local)/
28
+ ├── scan_structure.py
29
+ └── scan_techstack.py
30
+ ```
31
+
32
+ ## Usage
33
+ To audit your repository, run the scripts from the command line:
34
+
35
+ ```powershell
36
+ # Scan directory structure
37
+ python scan_structure.py . --output STRUCTURE.md
38
+
39
+ # Audit techstack (file types, counts, sizes)
40
+ python scan_techstack.py . --output TECHSTACK.md
41
+ ```
42
+
43
+ ## BibTeX Citation
44
+ ```bibtex
45
+ @misc{albeos2026filesystemauditor,
46
+ author = {Rembrant Oyangoren Albeos},
47
+ title = {filesystem-auditor: High-performance repository structure and techstack scanner},
48
+ year = {2026},
49
+ publisher = {Hugging Face},
50
+ journal = {Hugging Face Repository},
51
+ howpublished = {\url{https://huggingface.co/algorembrant/filesystem-auditor/}}
52
+ }
53
+ ```
54
+
55
+ ## Author
56
+ Rembrant Oyangoren Albeos (2026)
STACKS.md ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Description
2
+ This project, `filesystem-auditor`, is a high-performance utility designed to audit repository structures and analyze tech stacks. It leverages optimized filesystem traversal to handle large-scale codebases, providing surgical precision in identifying file types, counts, and total sizes. The system is built for speed and reliability, ensuring that every file is accounted for without missing a single entry.
3
+
4
+ ## System Overview
5
+
6
+ ```mermaid
7
+ graph TD
8
+ A[Repository Path] --> B{Action}
9
+ B -->|Structure Scan| C[scan_structure.py]
10
+ B -->|Techstack Scan| D[scan_techstack.py]
11
+ C --> E[STRUCTURE.md]
12
+ D --> F[TECHSTACK.md]
13
+ E --> G[Visual Documentation]
14
+ F --> G
15
+ ```
16
+
17
+ ## Project Structure
18
+
19
+ ```text
20
+ filesystem-auditor (local)/
21
+ ├── scan_structure.py
22
+ └── scan_techstack.py
23
+ ```
24
+
25
+ ## Techstack
26
+ Audit of **filesystem-auditor (local)** project files (excluding environment and cache):
27
+
28
+ | File Type | Count | Size (KB) |
29
+ | :--- | :--- | :--- |
30
+ | Python (.py) | 2 | 29.6 |
31
+ | Markdown (.md) | 1 | 0.1 |
32
+ | **Total** | **3** | **29.7** |
33
+
34
+ ## Dependencies
35
+ - **Python**:
36
+ - `os`: Core file system operations and traversal.
37
+ - `sys`: System-specific parameters and functions.
38
+ - `argparse`: Robust command-line argument parsing.
39
+ - `pathlib`: Object-oriented filesystem paths.
40
+ - `collections`: High-performance container datatypes (`defaultdict`).
41
+ - `subprocess`: Spawning new processes and connecting to their pipes.
42
+
43
+ ## Applications
44
+ - Google Antigravity
45
+ - Google Gemini Pro 3.1
46
+ - Visual Studio Code
47
+ - Windows PowerShell
example_output/STRUCTURE.md ADDED
@@ -0,0 +1,579 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Project Structure
2
+
3
+ ```text
4
+ QRAT2025/
5
+ ├── Concepts and Topics Folder/
6
+ │ ├── Basics/
7
+ │ │ ├── Basics 101.ipynb
8
+ │ │ ├── code promting.ipynb
9
+ │ │ ├── Foundation101.ipynb
10
+ │ │ └── nothing.ipynb
11
+ │ ├── concepts from other sources/
12
+ │ │ └── lists.ipynb
13
+ │ ├── Chart plotting using python.ipynb
14
+ │ ├── Max Number of Losing Streak in Regards to Winrate.ipynb
15
+ │ ├── Risk Management Logic.ipynb
16
+ │ └── The Law of Large Numbers (LLN).ipynb
17
+ ├── Documents/
18
+ │ ├── QRAT2025/
19
+ │ │ ├── diversification_model/
20
+ │ │ │ ├── img (1).png
21
+ │ │ │ ├── img (2).png
22
+ │ │ │ ├── img (3).png
23
+ │ │ │ ├── img (4).png
24
+ │ │ │ └── ReportTester-257199749_Diversification.html
25
+ │ │ ├── dump/
26
+ │ │ │ ├── ReportHistory-206675473 - Shortcut (2).lnk
27
+ │ │ │ ├── ReportHistory-206675473 - Shortcut.lnk
28
+ │ │ │ ├── ReportHistory-263204408.html
29
+ │ │ │ ├── ReportHistory-263204408.png
30
+ │ │ │ ├── ReportHistory-2632044080.html
31
+ │ │ │ ├── ReportHistory-2632044080.png
32
+ │ │ │ ├── ReportHistory-26320440800.html
33
+ │ │ │ ├── ReportHistory-26320440800.png
34
+ │ │ │ ├── ReportHistory-263204408000.html
35
+ │ │ │ ├── ReportHistory-263204408000.png
36
+ │ │ │ ├── ReportHistory-263204408gg.html
37
+ │ │ │ ├── ReportHistory-263204408gg.png
38
+ │ │ │ ├── ReportHistory-270451645.html
39
+ │ │ │ ├── ReportHistory-270451645.png
40
+ │ │ │ ├── ReportHistory-270454941.html
41
+ │ │ │ ├── ReportHistory-270454941.png
42
+ │ │ │ ├── ReportHistory-270456114.html
43
+ │ │ │ ├── ReportHistory-270456114.png
44
+ │ │ │ ├── ReportHistory-270461496.html
45
+ │ │ │ ├── ReportHistory-270461496.png
46
+ │ │ │ ├── ReportHistory-2704614960.html
47
+ │ │ │ ├── ReportHistory-2704614960.png
48
+ │ │ │ ├── ReportHistory-27046149600.html
49
+ │ │ │ ├── ReportHistory-27046149600.png
50
+ │ │ │ ├── ReportHistory-270461496000.html
51
+ │ │ │ ├── ReportHistory-270461496000.png
52
+ │ │ │ ├── ReportHistory-2704614960000.html
53
+ │ │ │ ├── ReportHistory-2704614960000.png
54
+ │ │ │ ├── ReportHistory-27046149600000.html
55
+ │ │ │ ├── ReportHistory-27046149600000.png
56
+ │ │ │ ├── ReportHistory-272840495.html
57
+ │ │ │ ├── ReportHistory-272840495.png
58
+ │ │ │ ├── ReportHistory-272840495.xlsx
59
+ │ │ │ ├── ReportHistory-2728404950.html
60
+ │ │ │ ├── ReportHistory-2728404950.png
61
+ │ │ │ ├── ReportHistory-274899951.html
62
+ │ │ │ ├── ReportHistory-274899951.png
63
+ │ │ │ ├── ReportTester-257199749 qwe-holding.png
64
+ │ │ │ ├── ReportTester-257199749 qwe-hst.png
65
+ │ │ │ ├── ReportTester-257199749 qwe-mfemae.png
66
+ │ │ │ ├── ReportTester-257199749 qwe.html
67
+ │ │ │ ├── ReportTester-257199749 qwe.png
68
+ │ │ │ ├── ReportTester-257199749-holding.png
69
+ │ │ │ ├── ReportTester-257199749-hst.png
70
+ │ │ │ ├── ReportTester-257199749-mfemae.png
71
+ │ │ │ ├── ReportTester-257199749.html
72
+ │ │ │ ├── ReportTester-257199749.png
73
+ │ │ │ ├── ReportTester-257199749BTCUSDc1-holding.png
74
+ │ │ │ ├── ReportTester-257199749BTCUSDc1-hst.png
75
+ │ │ │ ├── ReportTester-257199749BTCUSDc1-mfemae.png
76
+ │ │ │ ├── ReportTester-257199749BTCUSDc1.html
77
+ │ │ │ ├── ReportTester-257199749BTCUSDc1.png
78
+ │ │ │ ├── ReportTester-257199749q-holding.png
79
+ │ │ │ ├── ReportTester-257199749q-hst.png
80
+ │ │ │ ├── ReportTester-257199749q-mfemae.png
81
+ │ │ │ ├── ReportTester-257199749q.html
82
+ │ │ │ ├── ReportTester-257199749q.png
83
+ │ │ │ ├── ReportTesterhedgeminimum-257199749-holding.png
84
+ │ │ │ ├── ReportTesterhedgeminimum-257199749-hst.png
85
+ │ │ │ ├── ReportTesterhedgeminimum-257199749-mfemae.png
86
+ │ │ │ ├── ReportTesterhedgeminimum-257199749.html
87
+ │ │ │ ├── ReportTesterhedgeminimum-257199749.png
88
+ │ │ │ ├── ReportTesterskip 3-6 bar-257199749-holding.png
89
+ │ │ │ ├── ReportTesterskip 3-6 bar-257199749-hst.png
90
+ │ │ │ ├── ReportTesterskip 3-6 bar-257199749-mfemae.png
91
+ │ │ │ ├─�� ReportTesterskip 3-6 bar-257199749.html
92
+ │ │ │ ├── ReportTesterskip 3-6 bar-257199749.png
93
+ │ │ │ └── traderbotversion1.set
94
+ │ │ ├── live_stopouthedging/
95
+ │ │ │ ├── ReportHistory-257199749 7am to 10am.html
96
+ │ │ │ ├── ReportHistory-257199749 7am to 10am.png
97
+ │ │ │ ├── ReportHistory-257199749 7am to 11am.html
98
+ │ │ │ ├── ReportHistory-257199749 7am to 11am.png
99
+ │ │ │ ├── ReportHistory-257199749 7am to 1pm.html
100
+ │ │ │ ├── ReportHistory-257199749 7am to 1pm.png
101
+ │ │ │ ├── ReportHistory-257199749 7am to 2pm.html
102
+ │ │ │ ├── ReportHistory-257199749 7am to 2pm.png
103
+ │ │ │ ├── ReportHistory-257199749 7am to 8am.html
104
+ │ │ │ ├── ReportHistory-257199749 7am to 8am.png
105
+ │ │ │ ├── ReportHistory-257199749 7am to 9am.html
106
+ │ │ │ ├── ReportHistory-257199749 7am to 9am.png
107
+ │ │ │ ├── ReportHistory-257199749 alltime.html
108
+ │ │ │ ├── ReportHistory-257199749 alltime.png
109
+ │ │ │ ├── ReportHistory-257199749.html
110
+ │ │ │ ├── ReportHistory-257199749.png
111
+ │ │ │ ├── ReportHistory-263204408 LiveTest2 runall.html
112
+ │ │ │ ├── ReportHistory-263204408 LiveTest2 runall.png
113
+ │ │ │ ├── ReportHistory-263204408.html
114
+ │ │ │ ├── ReportHistory-263204408.png
115
+ │ │ │ ├── ReportHistory-263204408gg.html
116
+ │ │ │ └── ReportHistory-263204408gg.png
117
+ │ │ └── livereport/
118
+ │ │ ├── ReportHistory-148362150 live1.html
119
+ │ │ ├── ReportHistory-148362150 live1.png
120
+ │ │ ├── ReportHistory-183590578 Live3.html
121
+ │ │ ├── ReportHistory-183590578 Live3.png
122
+ │ │ ├── ReportHistory-186000559 live2.html
123
+ │ │ └── ReportHistory-186000559 live2.png
124
+ │ ├── eeee.ipynb
125
+ │ └── ewe.doc
126
+ ├── MQL5 Folder/
127
+ │ ├── #1EATB-Expert Advisor Trading Bot for MT5/
128
+ │ │ ├── LiveTest1 Results/
129
+ │ │ │ ├── ReportHistory-257199749 alltime.html
130
+ │ │ │ └── ReportHistory-257199749 alltime.png
131
+ │ │ ├── LiveTest2 Results/
132
+ │ │ │ ├── ReportHistory-263204408 LiveTest2 runall.html
133
+ │ │ │ └── ReportHistory-263204408 LiveTest2 runall.png
134
+ │ │ ├── Test1 Results/
135
+ │ │ │ ├── nonetest Results/
136
+ │ │ │ │ └── nonetest parameters.txt
137
+ │ │ │ ├── ReportHistory-270451645.html
138
+ │ │ │ ├── ReportHistory-270451645.png
139
+ │ │ │ ├── testsummary.txt
140
+ │ │ │ ├── total prompting attempt.txt
141
+ │ │ │ ├── traderbotversion1.set
142
+ │ │ │ ├── TradingBotVersion1.ex5
143
+ │ │ │ └── TradingBotVersion1.mq5
144
+ │ │ ├── Test2 Results/
145
+ │ │ │ ├── parameters.txt
146
+ │ │ │ ├── ReportHistory-206675473.html
147
+ │ │ │ └── ReportHistory-206675473.png
148
+ │ │ ├── Test3 Results/
149
+ │ │ │ ├── ReportHistory-274899951.html
150
+ │ │ │ ├── ReportHistory-274899951.png
151
+ │ │ │ └── test 3 paramenters.txt
152
+ │ │ ├── Test4 Results/
153
+ │ │ │ ├── parameters&summary.txt
154
+ │ │ │ ├── ReportHistory-270454941.html
155
+ │ │ │ └── ReportHistory-270454941.png
156
+ │ │ ├── Test5 Results/
157
+ │ │ │ ├── ReportHistory-270456114.html
158
+ │ │ │ ├── ReportHistory-270456114.png
159
+ │ │ │ └── summary&paratener.txt
160
+ │ │ ├── Test6 Results/
161
+ │ │ │ ├── ReportHistory-2728404950.html
162
+ │ │ │ ├── ReportHistory-2728404950.png
163
+ │ │ │ └── test 6 parameters.txt
164
+ │ │ ├── Testrun12hours Results/
165
+ │ │ │ ├── ReportHistory-2704614960000.html
166
+ │ │ │ ├── ReportHistory-2704614960000.png
167
+ │ │ │ └── seummary and parameters.txt
168
+ │ │ ├── #1EATB.mq5
169
+ │ │ └── MT5-EA_1min hedge stoporders.ipynb
170
+ │ ├── 0_00-3_00 Range/
171
+ │ │ ├── 03 Hedge.ipynb
172
+ │ │ ├── 03 range hedge minimum.ipynb
173
+ │ │ ├── attempts.ipynb
174
+ │ │ ├── Diversification.ipynb
175
+ │ │ ├── Refined version.ipynb
176
+ │ │ └── scratch.mql
177
+ │ ├── 89RS MT5 version/
178
+ │ │ └── 89RS MT5 version.ipynb
179
+ │ ├── ADX Filter/
180
+ │ │ ├── First candle highlighter with adx.ipynb
181
+ │ │ └── template with 1st candle highlighter.mq5
182
+ │ ├── Dec25_Volume Profile based breakout momentuim strategy/
183
+ │ │ ���── codeclaude.c++
184
+ │ │ └── codegemini.c++
185
+ │ ├── Dec29_6-8 range/
186
+ │ │ ├── strategy.ipynb
187
+ │ │ ├── v1.c++
188
+ │ │ └── v2.c++
189
+ │ ├── Developing POC/
190
+ │ │ └── developing POC line.ipynb
191
+ │ ├── H3 0 bar redbear bluebull (indicator)/
192
+ │ │ ├── 1_version.mq5
193
+ │ │ └── H3 0 bar redbear bluebull (indicator).ipynb
194
+ │ └── Revised 0-3/
195
+ │ ├── best/
196
+ │ │ └── highest performing.mq5
197
+ │ ├── 1_latestbest.mq5
198
+ │ ├── 2_latestbest.mq5
199
+ │ ├── 3_latestbest.mw5
200
+ │ ├── 4_latestbest.mq5
201
+ │ └── revised from very begining.ipynb
202
+ ├── Pinescript Folder/
203
+ │ ├── 0SCT2025/
204
+ │ │ ├── SCT Sunstoic's Charting Tool.ipynb
205
+ │ │ ├── SCT2025indicator1-pinescript.js
206
+ │ │ └── SCT2025indicator2-pinescript.js
207
+ │ ├── 12pm Key Level/
208
+ │ │ └── 4_00 utc key.ipynb
209
+ │ ├── 1D Candle Preview/
210
+ │ │ └── daily candle preview.ipynb
211
+ │ ├── 3-Candle Pattern Highlighter (1-Minute Only) General engulfing/
212
+ │ │ └── 3-Candle Pattern Highlighter (1-Minute Only).ipynb
213
+ │ ├── 3-Minute Engulfing Pattern (3mEP) - 1m Visible/
214
+ │ │ └── 3-Minute Engulfing Pattern (3mEP) - 1m Visible.ipynb
215
+ │ ├── 30m high & low/
216
+ │ │ └── 30m highlighter in lower timeframe.ipynb
217
+ │ ├── 3am to close & 9am to 11am Candle/
218
+ │ │ └── limited candles.ipynb
219
+ │ ├── 4CCP + 4CRP Patterns/
220
+ │ │ └── 4CCP + 4CRP Patterns.ipynb
221
+ │ ├── 4CCP + 6CBP Pattern Detector + 30minute bars (AsiaManila)/
222
+ │ │ └── 4CCP + 6CBP Pattern Detector + 30minute bars (AsiaManila).ipynb
223
+ │ ├── 4CCP Pattern detector/
224
+ │ │ └── 4CCP Pattern detector-pinescript.js
225
+ │ ├── 4CEP + 10CRP Patterns/
226
+ │ │ └── 4CEP + 10CRP Patterns.ipynb
227
+ │ ├── 4CEP-T1 & T2 Patterns - Tiny Circle Labels on 3rd Candle/
228
+ │ │ └── 4CEP-T1 & T2 Patterns - Tiny Circle Labels on 3rd Candle.ipynb
229
+ │ ├── 5 Candle Pattern Highlighter (1-Minute Only)/
230
+ │ │ └── 5 Candle Pattern Highlighter (1-Minute Only).ipynb
231
+ │ ├── 6CBP Pattern Detector (Bearish & Bullish)/
232
+ │ │ ├── 6CBP Pattern Detector (Bearish & Bullish).ipynb
233
+ │ │ └── with timestamp version.ipynb
234
+ │ ├── 89RS/
235
+ │ │ ├── 89RS Rangebreakout Stoporder Model.ipynb
236
+ │ │ ├── 89RSindicator-pinescript.js
237
+ │ │ └── 89RSstrategy-pinescript.js
238
+ │ ├── AMDX/
239
+ │ │ └── quarterly.ipynb
240
+ │ ├── Buying at Mariana's Trench/
241
+ │ │ └── buying at marianas trench.ipynb
242
+ │ ├── Daily Candle in Lower Timeframes/
243
+ │ │ └── daily candle convertor.ipynb
244
+ │ ├── Exact 30m Candles in any timeframe/
245
+ │ │ └── live 30m candles.ipynb
246
+ │ ├── Hihglight Key Hourly Candles/
247
+ │ │ └── highlight.ipynb
248
+ │ ├── Hourly Range Logic/
249
+ │ │ └── HR.ipynb
250
+ │ ├── Manual Key level/
251
+ │ │ └── key levels input.ipynb
252
+ │ ├── Market Profile (Volume based)/
253
+ │ │ └── market profile volume based.ipynb
254
+ │ ├── OB-OS Multi-Indicator Dashboard/
255
+ │ │ └── OB/
256
+ │ │ └── OS Multi-Indicator Dashboard.ipynb
257
+ │ ├── Relative Strength Index/
258
+ │ │ └── colored overbough and oversold region.ipynb
259
+ │ ├── Risk Manager and Position Sizing/
260
+ │ │ ├── Risk Manager and Position Sizing-pinescript.js
261
+ │ │ └── Risk Manager and Position Sizing.ipynb
262
+ │ ├── Synthetic Gamma Exposure (GEX)/
263
+ │ │ └── gex.ipynb
264
+ │ ├── Table Statistics/
265
+ │ │ └── clean table.ipynb
266
+ │ ├── Time Logic Reference/
267
+ │ │ └── Time Logic Reference.ipynb
268
+ │ ├── v3 Simple/
269
+ │ │ └── highlight and 1D candle.ipynb
270
+ │ ├── v4 Variant 1/
271
+ │ │ └── v4 30m,15m,3m.ipynb
272
+ │ ├── v5 Cummulative Delta/
273
+ │ │ └── cummulative deta.ipynb
274
+ │ ├── v5 Variant 1/
275
+ │ │ └── v5 30m,15m,3m (with clean table) .ipynb
276
+ │ ├── v5 Variant 2/
277
+ │ │ └── fuhfuhlogic.ipynb
278
+ │ ├── v6 Sunstoic/
279
+ │ │ └── part1.ipynb
280
+ │ ├── Verttical Lines at Specific Time/
281
+ │ │ └── Vertical lines at specific time.ipynb
282
+ │ ├── Vison Market Profile/
283
+ │ │ └── vison market profile.ipynb
284
+ │ ├── VROC buy&sell/
285
+ │ │ └── vroc buysell.ipynb
286
+ │ └── VWAP witih buy&sell spread/
287
+ │ └── VWAP with buy&sell spread.ipynb
288
+ ├── Python Folder/
289
+ │ ├── 3 tick-volume pattern hedge/
290
+ │ │ ├── 3 tick-volume pattern hedge.ipynb
291
+ │ │ ├── save.ipynb
292
+ │ │ └── XAUUSDc M30 – Tick-Volume First Pattern + DMA Overlay + RAVI (UTC Reset).ipynb
293
+ │ ├── All country's Total Debt/
294
+ │ │ ├── Part2/
295
+ │ │ │ ├── update 2.ipynb
296
+ │ │ │ └── Worldwide National Debt Profiles.ipynb
297
+ │ │ ├── debt.ipynb
298
+ │ │ └── Worldwind Yearly Debt (1).ipynb
299
+ │ ├── Bubble Orders/
300
+ │ │ ├── Bubble Orders.ipynb
301
+ │ │ └── xau_bubbles_zones.xls
302
+ │ ├── Candlestick, Tick Volume, Range, Body , Wick/
303
+ │ │ ├── (10 panes) XAUUSDc 3-Minute Candlestick with Tick Volume, Range, Body & Wick.ipynb
304
+ │ │ ├── Filter(body_greaterthan_upper-wick_or_lower-wick).ipynb
305
+ │ │ └── promting attempts.ipynb
306
+ │ ├── COT Report Interpreter/
307
+ │ │ ├── COT Report.ipynb
308
+ │ │ └── VROC, COT report.ipynb
309
+ │ ├── Cummulative Volume/
310
+ │ │ └── MarketOpenClose.ipynb
311
+ │ ├── Dec25.2025_Volume Profile based strategy visualization/
312
+ │ │ ├── 1_framework.ipynb
313
+ │ │ └── 2_framework.ipynb
314
+ │ ├── Dec31_Newsfetching/
315
+ │ │ └── Newfetching.ipynb
316
+ │ ├── Downslope Linear Regression/
317
+ │ │ └── Downslope Linear Regression in Volume.ipynb
318
+ │ ├── EBP One Candle Strategy/
319
+ │ │ └── EBP One Candle Strategy.ipynb
320
+ │ ├── Equity Profile Clasification/
321
+ │ │ ├── Equity classification.ipynb
322
+ │ │ ├── notebook1.ipynb
323
+ │ │ └── notebook2.ipynb
324
+ │ ├── Fetching Data from mplfinance/
325
+ │ │ └── Fetching Data from mplfinance.ipynb
326
+ │ ├── Fetching Portfolio/
327
+ │ │ ├── Broker account fetching.ipynb
328
+ │ │ └── Python fetching portfolio from MT5.ipynb
329
+ │ ├── imprvedversionof1bardelaySwing/
330
+ │ │ ├── attempts.ipynb
331
+ │ │ └── bestswing1BarDelay.ipynb
332
+ │ ├── Law of Large Numbers/
333
+ │ │ └── Law of Large Numbers.ipynb
334
+ │ ├── Market Profiles/
335
+ │ │ ├── Market Profile (volumedata ver).ipynb
336
+ │ │ └── marketprofile on separate graph, chartbasic.ipynb
337
+ │ ├── OHRMRSHS (from 89RS)/
338
+ │ │ └── OHRMRSHS.ipynb
339
+ │ ├── Rem lookback Algorithm/
340
+ │ │ ├── 1bardelay.ipynb
341
+ │ │ ├── 1barlagSwing.ipynb
342
+ │ │ ├── best1barLag.ipynb
343
+ │ │ ├── Rem lookback Algorithm.ipynb
344
+ │ │ └── Volume Score Lookback algorithm.ipynb
345
+ │ ├── Remscount Algorithm/
346
+ │ │ ├── (10 panes) XAUUSDc 3-Minute Candlestick with Tick Volume, Range, Body & Wick (1).ipynb
347
+ │ │ ├── 3candlepattern.ipynb
348
+ │ │ ├── bestswing1BarDelay.ipynb
349
+ │ │ ├── Filter(body_greaterthan_upper-wick_or_lower-wick) (1).ipynb
350
+ │ │ ├── Lowest Pattern Score count.ipynb
351
+ │ │ ├── patternScore.ipynb
352
+ │ │ ├── remscountalgorithm(draft) (1).ipynb
353
+ │ │ └── remscountalgorithm(draft).ipynb
354
+ │ ├── The 0.25 precision footprint candles/
355
+ │ │ ├── Footprint 0.25 cluster precision, market profile.ipynb
356
+ │ │ └── PixeldFootprint.ipynb
357
+ │ ├── Ticker Quotes Fetching/
358
+ │ │ ├── notthis.py
359
+ │ │ └── Quotes of all tradable assets in Exness.ipynb
360
+ │ ├── Time Alignment/
361
+ │ │ └── time alignment.ipynb
362
+ │ ├── Using Python to plot charts from MT5's data feed, mplfinance, matplotlib, plotly charts/
363
+ │ │ ├── notthis.py
364
+ │ │ └── Using Python to plot charts from MT5's data feed, mplfinance, matplotlib, plotly charts.ipynb
365
+ │ ├── Variance and Standard Deviations/
366
+ │ │ ├── notthis.py
367
+ │ │ └── Variance and Standard Deviations.ipynb
368
+ │ ├── Volatility Based Trading Strategy, VTR, ADX, DI, DMag/
369
+ │ │ ├── From tiktok_VTR, ADX, DI, DMag.ipynb
370
+ │ │ ├── notthis.py
371
+ │ │ ├── Volatility Based Trading Strategy, VTR, ADX, DI, DMag.pdf
372
+ │ │ ├── VTR signals, market profile.ipynb
373
+ │ │ ├── VTRchart.ipynb
374
+ │ │ ├── xau_system_output.xls
375
+ │ │ ├── xau_system_signals.png
376
+ │ │ ├── xau_vtr_output.xls
377
+ │ │ └── xau_vtr_tickvolume_output.xls
378
+ │ ├── Volume Spread Analysis/
379
+ │ │ ├── notthis.py
380
+ │ │ └── VSA.ipynb
381
+ │ └── Worldmap/
382
+ │ └── Worldmap.ipynb
383
+ ├── Research Papers/
384
+ │ ├── The 1CPMOTS.rp1_ Is Treating Trading Worse Than a Coin Flip, but with a Slight Edge, Profitable_/
385
+ │ │ ├── codes/
386
+ │ │ │ ├── 1candlepattern.ipynb
387
+ │ │ │ └── Comparative Visualization of Backtest Metrics.ipynb
388
+ │ │ ├── 1CPMOTS_rp1.pdf
389
+ │ │ └── newplot (2).png
390
+ │ ├── The 1HRMRSS.rp1_ Design and Optimization of the One Hour Range Median Reversion Stoporder Strategy/
391
+ │ │ ├── CSV files/
392
+ │ │ │ ├── 1HRMRSS_MCS1000 - total.csv
393
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC00-01_avg_equity.xls
394
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC01-02_avg_equity.xls
395
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC02-03_avg_equity.xls
396
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC03-04_avg_equity.xls
397
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC04-05_avg_equity.xls
398
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC05-06_avg_equity.xls
399
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC06-07_avg_equity.xls
400
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC07-08_avg_equity.xls
401
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC08-09_avg_equity.xls
402
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC09-10_avg_equity.xls
403
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC10-11_avg_equity.xls
404
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC11-12_avg_equity.xls
405
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC12-13_avg_equity.xls
406
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC13-14_avg_equity.xls
407
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC14-15_avg_equity.xls
408
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC15-16_avg_equity.xls
409
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC16-17_avg_equity.xls
410
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC17-18_avg_equity.xls
411
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC18-19_avg_equity.xls
412
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC19-20_avg_equity.xls
413
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC20-21_avg_equity.xls
414
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC21-22(empty)_avg_equity.xls
415
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC22-23_avg_equity.xls
416
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC23-24(empty)_avg_equity.xls
417
+ │ │ │ └── 1HRMRSS_MCS1000_UTC24-00(empty)_avg_equity.xls
418
+ │ │ ├── Drafts/
419
+ │ │ │ ├── (Draft) SwingHHLLbreakout strategy.ipynb
420
+ │ │ │ ├── 89RS.ipynb
421
+ │ │ │ ├── draft too.ipynb
422
+ │ │ │ ├── Research2.1.ipynb
423
+ │ │ │ └── Research2.ipynb
424
+ │ │ ├── Notebooks/
425
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC00-01.ipynb
426
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC01-02.ipynb
427
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC02-03.ipynb
428
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC03-04.ipynb
429
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC04-05.ipynb
430
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC05-06.ipynb
431
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC06-07.ipynb
432
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC07-08.ipynb
433
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC08-09.ipynb
434
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC09-10.ipynb
435
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC10-11.ipynb
436
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC11-12.ipynb
437
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC12-13.ipynb
438
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC13-14.ipynb
439
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC14-15.ipynb
440
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC15-16.ipynb
441
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC16-17.ipynb
442
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC17-18.ipynb
443
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC18-19.ipynb
444
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC19-20.ipynb
445
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC20-21.ipynb
446
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC21-22(empty).ipynb
447
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC22-23(empty).ipynb
448
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC23-24(empty).ipynb
449
+ │ │ │ ├── 1HRMRSS_MCS1000_UTC24-00(empty).ipynb
450
+ │ │ │ ├── 1HRMRSS_MCS1000_UTCTotal_avg_equity.ipynb
451
+ │ │ │ └── note
452
+ │ │ ├── Performance img/
453
+ │ │ │ ├── 1HRMRSS_MCS1000_ProfitabilityPerformance.png
454
+ │ │ │ ├── 1HRMRSS_MCS1000_profitableEquityCurves.png
455
+ │ │ │ ├── 1HRMRSS_MCS1000_TradesPerformance.png
456
+ │ │ │ ├── 1HRMRSS_MCS1000_unprofitableEquityCurves.png
457
+ │ │ │ ├── 3D performance draft.ipynb
458
+ │ │ │ ├── 3D performance draft1.ipynb
459
+ │ │ │ ├── avg_00-01.png
460
+ │ │ │ ├── avg_01-02.png
461
+ │ │ │ ├── avg_02-03.png
462
+ │ │ │ ├── avg_03-04.png
463
+ │ │ │ ├── avg_04-05.png
464
+ │ │ │ ├── avg_05-06.png
465
+ │ │ │ ├── avg_06-07.png
466
+ │ │ │ ├── avg_07-08.png
467
+ │ │ │ ├── avg_08-09.png
468
+ │ │ │ ├── avg_09-10.png
469
+ │ │ │ ├── avg_10-11.png
470
+ │ │ │ ├── avg_11-12.png
471
+ │ │ │ ├── avg_12-13.png
472
+ �� │ │ ├── avg_13-14.png
473
+ │ │ │ ├── avg_14-15.png
474
+ │ │ │ ├── avg_15-16.png
475
+ │ │ │ ├── avg_16-17.png
476
+ │ │ │ ├── avg_17-18.png
477
+ │ │ │ ├── avg_18-19.png
478
+ │ │ │ ├── avg_19-20.png
479
+ │ │ │ ├── avg_20-21.png
480
+ │ │ │ ├── avg_21-22(empty).png
481
+ │ │ │ ├── avg_22-23(empty).png
482
+ │ │ │ ├── avg_23-24(empty).png
483
+ │ │ │ ├── avg_24-00(empty).png
484
+ │ │ │ ├── avg_total.png
485
+ │ │ │ └── overview.png
486
+ │ │ └── The 1HRMRSS.rp1.pdf
487
+ │ ├── The 1SSHSHFT.rp1_ Is Simultaneous Stopout Hedging Strategy, a High Frequency Trading, an Edge in Retail Level Application_/
488
+ │ │ ├── Codes/
489
+ │ │ │ ├── Demo script..c++
490
+ │ │ │ └── Live script.c++
491
+ │ │ └── The 1SSHSHFT_rp1.pdf
492
+ │ ├── The 3HTMOSDSDT.rp1_ Three-hour Timeframe Market Order Strategy with Defined Stoploss and Dynamic Takeprofit/
493
+ │ │ ├── 3HTMOSDSDT.rp1.ipynb
494
+ │ │ ├── 3HTMOSDSDT_rp1.pdf
495
+ │ │ ├── newplot (21).png
496
+ │ │ ├── newplot (22).png
497
+ │ │ ├── newplot (23).png
498
+ │ │ ├── newplot (24).png
499
+ │ │ ├── newplot (25).png
500
+ │ │ └── newplot (26).png
501
+ │ ├── The 3HTMOSDSDT.rp2 _ Portfolio Diversification for ’Three-hour Timeframe Market Order Strategy with Defined Stoploss and Dynamic Takeprofit’ Trading Model/
502
+ │ │ ├── codes/
503
+ │ │ │ ├── 0-3 Range Hedge minimum distance required.c++
504
+ │ │ │ ├── 0-3Range Hedge.c++
505
+ │ │ │ ├── Diversification 0-3 range hedging minimum.c++
506
+ │ │ │ └── Diversiofication 28 pairs.c++
507
+ │ │ └── 3HTMOSDSDT_rp2.pdf
508
+ │ ├── The 3mTSHSUHC.rp1_ Design and Optimization of Three-minute Timeframe Stoporder Hedging Strategy Using Heatmap Candles/
509
+ │ │ ├── 3mTSHSUHC.rp1.pdf
510
+ │ │ └── Design and Optimization of 3mTSHSUHCv1.ipynb
511
+ │ ├── The 3mTSHSUHC.rp2_ Stress Test & Evaluating the Three-minute Timeframe Stoporder Hedging Strategy Using Heatmap Candles/
512
+ │ │ ├── Draft/
513
+ │ │ │ └── The longest error in my career.ipynb
514
+ │ │ ├── 3mTSHSUHC.rp2.pdf
515
+ │ │ ├── Equity Curve of 3mTSHSUHCv1’s Performance.png
516
+ │ │ ├── Heatmap Candles Chart with Trade Executions.png
517
+ │ │ ├── Intraday data set with Heatmap Candles Chart.png
518
+ │ │ └── The 3mTSHSUHC.rp2, stress test .ipynb
519
+ │ └── The 3mTSHSUHC.rp3 _ Metric Threshold and Minimum Bars Apart Analysis of Three-minute Timeframe Stoporder Hedging Strategy Using Heatmap Candles/
520
+ │ ├── Draft/
521
+ │ │ ├── draft1.ipynb
522
+ │ │ ├── this is it.ipynb
523
+ │ │ └── weighted score.ipynb
524
+ │ ├── 3mTSHSUHC.rp3.pdf
525
+ │ ├── FULL_TRADE_STATISTICS_DATAFRAME.xls
526
+ │ ├── single backtest framework.ipynb
527
+ │ ├── singlebactest draft&outlinie.ipynb
528
+ │ ├── the 3d graphs plotting.ipynb
529
+ │ ├── the five 3D graphs.ipynb
530
+ │ └── TOP_10_PARAMETER_COMBINATIONS_BY_SCORE.xls
531
+ ├── z.Others/
532
+ │ ├── z.Images Folder/
533
+ │ │ ├── diagram-export-11-30-2025-10_57_09-AM.png
534
+ │ │ ├── diagram-export-11-30-2025-11_12_54-AM.png
535
+ │ │ ├── pasted-image (1).png
536
+ │ │ ├── pasted-image (11).png
537
+ │ │ ├── pasted-image (12).png
538
+ │ │ ├── pasted-image (15).png
539
+ │ │ ├── pasted-image (2).png
540
+ │ │ ├── pasted-image (3).png
541
+ │ │ ├── pasted-image (4).png
542
+ │ │ ├── pasted-image (6).png
543
+ │ │ ├── pasted-image (7) (1).png
544
+ │ │ ├── pasted-image (8).png
545
+ │ │ ├── pasted-image (9).png
546
+ │ │ ├── pasted-image.png
547
+ │ │ ├── Screenshot 2025-11-12 102519.png
548
+ │ │ ├── Screenshot 2025-11-12 104458.png
549
+ │ │ ├── Screenshot 2025-11-12 105920.png
550
+ │ │ ├── Screenshot 2025-11-12 144500.png
551
+ │ │ ├── Screenshot 2025-11-12 201257.png
552
+ │ │ ├── Screenshot 2025-11-12 205738.png
553
+ │ │ ├── Screenshot 2025-11-15 131419.png
554
+ │ │ ├── Screenshot 2025-11-15 132923.png
555
+ │ │ ├── Screenshot 2025-11-15 135957.png
556
+ │ │ ├── Screenshot 2025-11-15 153904.png
557
+ │ │ ├── Screenshot 2025-11-15 160104.png
558
+ │ │ ├── Screenshot 2025-11-15 162112.png
559
+ │ │ ├── Screenshot 2025-11-15 162726.png
560
+ │ │ ├── Screenshot 2025-11-15 164303.png
561
+ │ │ ├── Screenshot 2025-11-15 182205.png
562
+ │ │ ├── Screenshot 2025-11-15 184043.png
563
+ │ │ ├── Screenshot_20251121_083916_Sheets.png
564
+ │ │ ├── Screenshot_20251205_102855_Docs.png
565
+ │ │ ├── XAUUSD_2025-11-11_21-11-52.png
566
+ │ │ └── XAUUSDc_2025-11-12_10-02-56.png
567
+ │ ├── APA Style (7th Edition).md
568
+ │ ├── test.txt
569
+ │ ├── Understanding GitHub Licenses.md
570
+ │ ├── VTR_DMag_System_Explanation.md
571
+ │ └── WQ Wildmind Quasars’s standard research paper layout.ipynb
572
+ ├── .gitattributes
573
+ ├── gg.md
574
+ ├── LICENSE
575
+ ├── README.md
576
+ ├── scan_structure.py
577
+ ├── scan_techstack.py
578
+ └── STACKS.md
579
+ ```
example_output/TECHSTACK.md ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Techstack
2
+
3
+ Audit of **QRAT2025** project files (excluding environment and cache):
4
+
5
+ | File Type | Count | Size (KB) |
6
+ | :--- | :--- | :--- |
7
+ | Jupyter Notebook (.ipynb) | 163 | 353,640.7 |
8
+ | PNG Image (.png) | 144 | 13,796.6 |
9
+ | HTML (.html) | 47 | 76,265.7 |
10
+ | Microsoft Excel (.xls) | 31 | 6,514.8 |
11
+ | C++ (.c++) | 10 | 98.8 |
12
+ | Plain Text (.txt) | 10 | 1.1 |
13
+ | PDF (.pdf) | 9 | 14,597.1 |
14
+ | MQL5 Source (.mq5) | 8 | 72.8 |
15
+ | Markdown (.md) | 7 | 61.5 |
16
+ | Python (.py) | 7 | 247.9 |
17
+ | JavaScript (.js) | 6 | 121.7 |
18
+ | (no extension) | 3 | 1.1 |
19
+ | MT Parameter Set (.set) | 2 | 0.4 |
20
+ | Windows Shortcut (.lnk) | 2 | 2.4 |
21
+ | CSV (.csv) | 1 | 83.9 |
22
+ | Microsoft Excel (OOXML) (.xlsx) | 1 | 55.3 |
23
+ | Microsoft Word (.doc) | 1 | 2.5 |
24
+ | MQL Source (.mql) | 1 | 5.4 |
25
+ | MQL5 Compiled (.ex5) | 1 | 25.9 |
26
+ | MQL5 Variant (.mw5) | 1 | 9.5 |
27
+ | **Total** | **455** | **465,605.1** |
scan_structure.py ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Repository Structure Scanner
3
+ =============================
4
+ Scans the entire file structure of a repository and outputs a tree-like
5
+ Markdown representation. Handles massive (1GB+) repositories efficiently.
6
+
7
+ Usage:
8
+ python scan_structure.py [path] [--output FILE] [--ignore PATTERN ...]
9
+
10
+ Output:
11
+ A Markdown file containing the full directory tree.
12
+ """
13
+
14
+ import os
15
+ import sys
16
+ import argparse
17
+ import subprocess
18
+ from pathlib import Path
19
+ from collections import defaultdict
20
+
21
+
22
+ # ---------------------------------------------------------------------------
23
+ # Default ignore patterns (common non-source dirs / files)
24
+ # ---------------------------------------------------------------------------
25
+ DEFAULT_IGNORE = {
26
+ ".git",
27
+ "__pycache__",
28
+ ".venv",
29
+ "venv",
30
+ "env",
31
+ "node_modules",
32
+ ".ipynb_checkpoints",
33
+ ".mypy_cache",
34
+ ".pytest_cache",
35
+ ".tox",
36
+ ".eggs",
37
+ "*.egg-info",
38
+ ".DS_Store",
39
+ "Thumbs.db",
40
+ "desktop.ini",
41
+ }
42
+
43
+
44
+ def should_ignore(name: str, ignore_set: set) -> bool:
45
+ """Return True if *name* matches any pattern in the ignore set."""
46
+ if name in ignore_set:
47
+ return True
48
+ for pattern in ignore_set:
49
+ if pattern.startswith("*") and name.endswith(pattern[1:]):
50
+ return True
51
+ return False
52
+
53
+
54
+ def build_tree(root_path: str, ignore_set: set) -> list[str]:
55
+ """
56
+ Walk *root_path* depth-first and return a list of tree-formatted lines.
57
+
58
+ Uses ``os.scandir`` for performance on large filesystems and sorts
59
+ entries alphabetically (directories first).
60
+ """
61
+
62
+ lines: list[str] = []
63
+
64
+ def _walk(current: str, prefix: str) -> None:
65
+ try:
66
+ entries = sorted(
67
+ os.scandir(current),
68
+ key=lambda e: (not e.is_dir(follow_symlinks=False), e.name.lower()),
69
+ )
70
+ except PermissionError:
71
+ return
72
+
73
+ # Filter out ignored entries
74
+ entries = [e for e in entries if not should_ignore(e.name, ignore_set)]
75
+
76
+ for idx, entry in enumerate(entries):
77
+ is_last = idx == len(entries) - 1
78
+ connector = "└── " if is_last else "├── "
79
+ suffix = "/" if entry.is_dir(follow_symlinks=False) else ""
80
+ lines.append(f"{prefix}{connector}{entry.name}{suffix}")
81
+
82
+ if entry.is_dir(follow_symlinks=False):
83
+ extension = " " if is_last else "│ "
84
+ _walk(entry.path, prefix + extension)
85
+
86
+ _walk(root_path, "")
87
+ return lines
88
+
89
+
90
+ def main() -> None:
91
+ parser = argparse.ArgumentParser(
92
+ description="Scan repository file structure and output a Markdown tree."
93
+ )
94
+ parser.add_argument(
95
+ "path",
96
+ nargs="?",
97
+ default=".",
98
+ help="Root directory to scan (default: current directory).",
99
+ )
100
+ parser.add_argument(
101
+ "--output",
102
+ "-o",
103
+ default=None,
104
+ help="Output Markdown file path (default: STRUCTURE.md in scanned dir).",
105
+ )
106
+ parser.add_argument(
107
+ "--ignore",
108
+ nargs="*",
109
+ default=None,
110
+ help="Extra patterns to ignore (added to built-in defaults).",
111
+ )
112
+ parser.add_argument(
113
+ "--no-default-ignore",
114
+ action="store_true",
115
+ help="Disable the built-in ignore list (scan everything).",
116
+ )
117
+ args = parser.parse_args()
118
+
119
+ root = os.path.abspath(args.path)
120
+ root_name = os.path.basename(root)
121
+
122
+ # Build ignore set
123
+ ignore_set: set = set() if args.no_default_ignore else set(DEFAULT_IGNORE)
124
+ if args.ignore:
125
+ ignore_set.update(args.ignore)
126
+
127
+ # Always ignore the output file itself to avoid self-referencing
128
+ out_path = args.output or os.path.join(root, "STRUCTURE.md")
129
+ out_name = os.path.basename(out_path)
130
+ ignore_set.add(out_name)
131
+
132
+ print(f"Scanning: {root}")
133
+ print(f"Ignoring: {', '.join(sorted(ignore_set))}")
134
+
135
+ tree_lines = build_tree(root, ignore_set)
136
+
137
+ # Compose Markdown content
138
+ md_lines = [
139
+ f"## Project Structure\n",
140
+ f"```text",
141
+ f"{root_name}/",
142
+ ]
143
+ md_lines.extend(tree_lines)
144
+ md_lines.append("```\n")
145
+
146
+ content = "\n".join(md_lines)
147
+
148
+ with open(out_path, "w", encoding="utf-8") as fh:
149
+ fh.write(content)
150
+
151
+ total_entries = len(tree_lines)
152
+ print(f"Done – {total_entries} entries written to {out_path}")
153
+
154
+
155
+ if __name__ == "__main__":
156
+ main()
scan_techstack.py ADDED
@@ -0,0 +1,750 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Repository Tech-Stack Scanner
3
+ ===============================
4
+ Scans a repository and produces a Markdown table of file types with counts
5
+ and total sizes in KB. Supports every file extension in existence.
6
+
7
+ Usage:
8
+ python scan_techstack.py [path] [--output FILE] [--ignore PATTERN ...]
9
+ [--exclude-ext EXT ...] [--sort count|size|ext]
10
+
11
+ Output:
12
+ A Markdown file containing the tech-stack audit table.
13
+ """
14
+
15
+ import os
16
+ import sys
17
+ import argparse
18
+ from pathlib import Path
19
+ from collections import defaultdict
20
+
21
+
22
+ # ---------------------------------------------------------------------------
23
+ # Comprehensive file-extension → human-readable label mapping
24
+ # Covers programming, data, document, media, archive, config, and more.
25
+ # Any extension NOT in this dict will be auto-labelled from the extension.
26
+ # ---------------------------------------------------------------------------
27
+ EXT_LABELS: dict[str, str] = {
28
+ # ── Programming Languages ──────────────────────────────────────────
29
+ ".py": "Python",
30
+ ".pyw": "Python (windowed)",
31
+ ".pyx": "Cython",
32
+ ".pxd": "Cython Definition",
33
+ ".pyi": "Python Stub",
34
+ ".pyc": "Python Compiled",
35
+ ".pyo": "Python Optimized",
36
+ ".js": "JavaScript",
37
+ ".mjs": "ES Module JavaScript",
38
+ ".cjs": "CommonJS JavaScript",
39
+ ".jsx": "JSX (React)",
40
+ ".ts": "TypeScript",
41
+ ".tsx": "TSX (React)",
42
+ ".java": "Java",
43
+ ".class": "Java Class",
44
+ ".jar": "Java Archive",
45
+ ".kt": "Kotlin",
46
+ ".kts": "Kotlin Script",
47
+ ".scala": "Scala",
48
+ ".groovy": "Groovy",
49
+ ".c": "C",
50
+ ".h": "C Header",
51
+ ".cpp": "C++",
52
+ ".cxx": "C++",
53
+ ".cc": "C++",
54
+ ".c++": "C++",
55
+ ".hpp": "C++ Header",
56
+ ".hxx": "C++ Header",
57
+ ".hh": "C++ Header",
58
+ ".h++": "C++ Header",
59
+ ".cs": "C#",
60
+ ".csx": "C# Script",
61
+ ".fs": "F#",
62
+ ".fsx": "F# Script",
63
+ ".fsi": "F# Signature",
64
+ ".vb": "Visual Basic",
65
+ ".vbs": "VBScript",
66
+ ".go": "Go",
67
+ ".rs": "Rust",
68
+ ".rb": "Ruby",
69
+ ".erb": "Embedded Ruby",
70
+ ".php": "PHP",
71
+ ".pl": "Perl",
72
+ ".pm": "Perl Module",
73
+ ".lua": "Lua",
74
+ ".r": "R",
75
+ ".rmd": "R Markdown",
76
+ ".swift": "Swift",
77
+ ".m": "Objective-C / MATLAB",
78
+ ".mm": "Objective-C++",
79
+ ".d": "D",
80
+ ".dart": "Dart",
81
+ ".ex": "Elixir",
82
+ ".exs": "Elixir Script",
83
+ ".erl": "Erlang",
84
+ ".hrl": "Erlang Header",
85
+ ".hs": "Haskell",
86
+ ".lhs": "Literate Haskell",
87
+ ".ml": "OCaml",
88
+ ".mli": "OCaml Interface",
89
+ ".clj": "Clojure",
90
+ ".cljs": "ClojureScript",
91
+ ".cljc": "Clojure Common",
92
+ ".edn": "EDN (Clojure)",
93
+ ".lisp": "Common Lisp",
94
+ ".cl": "Common Lisp",
95
+ ".el": "Emacs Lisp",
96
+ ".scm": "Scheme",
97
+ ".rkt": "Racket",
98
+ ".nim": "Nim",
99
+ ".zig": "Zig",
100
+ ".v": "V / Verilog",
101
+ ".vhd": "VHDL",
102
+ ".vhdl": "VHDL",
103
+ ".sv": "SystemVerilog",
104
+ ".asm": "Assembly",
105
+ ".s": "Assembly",
106
+ ".f": "Fortran",
107
+ ".f90": "Fortran 90",
108
+ ".f95": "Fortran 95",
109
+ ".f03": "Fortran 2003",
110
+ ".f08": "Fortran 2008",
111
+ ".for": "Fortran",
112
+ ".cob": "COBOL",
113
+ ".cbl": "COBOL",
114
+ ".pas": "Pascal",
115
+ ".pp": "Pascal",
116
+ ".ada": "Ada",
117
+ ".adb": "Ada Body",
118
+ ".ads": "Ada Spec",
119
+ ".tcl": "Tcl",
120
+ ".tk": "Tcl/Tk",
121
+ ".awk": "AWK",
122
+ ".sed": "sed",
123
+ ".jl": "Julia",
124
+ ".cr": "Crystal",
125
+ ".hack": "Hack",
126
+ ".hx": "Haxe",
127
+ ".hxml": "Haxe XML",
128
+ ".purs": "PureScript",
129
+ ".idr": "Idris",
130
+ ".agda": "Agda",
131
+ ".lean": "Lean",
132
+ ".coq": "Coq",
133
+ ".thy": "Isabelle",
134
+ ".pro": "Prolog",
135
+ ".sml": "Standard ML",
136
+ ".fig": "MATLAB Figure",
137
+ ".mat": "MATLAB Data",
138
+
139
+ # ── Shell / Scripting ──────────────────────────────────────────────
140
+ ".sh": "Shell Script",
141
+ ".bash": "Bash Script",
142
+ ".zsh": "Zsh Script",
143
+ ".fish": "Fish Script",
144
+ ".bat": "Batch File",
145
+ ".cmd": "Windows Command",
146
+ ".ps1": "PowerShell",
147
+ ".psm1": "PowerShell Module",
148
+ ".psd1": "PowerShell Data",
149
+
150
+ # ── Web / Markup / Templating ──────��───────────────────────────────
151
+ ".html": "HTML",
152
+ ".htm": "HTML",
153
+ ".xhtml": "XHTML",
154
+ ".css": "CSS",
155
+ ".scss": "SCSS",
156
+ ".sass": "Sass",
157
+ ".less": "Less",
158
+ ".styl": "Stylus",
159
+ ".vue": "Vue",
160
+ ".svelte": "Svelte",
161
+ ".astro": "Astro",
162
+ ".ejs": "EJS Template",
163
+ ".pug": "Pug Template",
164
+ ".jade": "Jade Template",
165
+ ".hbs": "Handlebars",
166
+ ".mustache": "Mustache",
167
+ ".twig": "Twig Template",
168
+ ".jinja": "Jinja Template",
169
+ ".jinja2": "Jinja2 Template",
170
+ ".j2": "Jinja2 Template",
171
+ ".njk": "Nunjucks Template",
172
+ ".liquid": "Liquid Template",
173
+ ".haml": "HAML",
174
+ ".slim": "Slim Template",
175
+ ".blade.php":"Blade Template",
176
+ ".jsp": "JavaServer Pages",
177
+ ".asp": "ASP",
178
+ ".aspx": "ASP.NET",
179
+ ".cshtml": "Razor (C#)",
180
+ ".razor": "Razor",
181
+ ".wasm": "WebAssembly",
182
+
183
+ # ── Data / Config / Serialisation ──────────────────────────────────
184
+ ".json": "JSON",
185
+ ".jsonl": "JSON Lines",
186
+ ".json5": "JSON5",
187
+ ".geojson": "GeoJSON",
188
+ ".xml": "XML",
189
+ ".xsl": "XSLT",
190
+ ".xslt": "XSLT",
191
+ ".xsd": "XML Schema",
192
+ ".dtd": "Document Type Definition",
193
+ ".yaml": "YAML",
194
+ ".yml": "YAML",
195
+ ".toml": "TOML",
196
+ ".ini": "INI Config",
197
+ ".cfg": "Config",
198
+ ".conf": "Config",
199
+ ".env": "Environment File",
200
+ ".properties": "Properties File",
201
+ ".csv": "CSV",
202
+ ".tsv": "TSV",
203
+ ".parquet": "Apache Parquet",
204
+ ".avro": "Apache Avro",
205
+ ".orc": "Apache ORC",
206
+ ".feather": "Feather (Arrow)",
207
+ ".arrow": "Apache Arrow",
208
+ ".msgpack": "MessagePack",
209
+ ".bson": "BSON",
210
+ ".cbor": "CBOR",
211
+ ".protobuf": "Protocol Buffer",
212
+ ".proto": "Protocol Buffer Schema",
213
+ ".thrift": "Apache Thrift",
214
+ ".hcl": "HCL (Terraform)",
215
+ ".tf": "Terraform",
216
+ ".tfvars": "Terraform Variables",
217
+ ".pkl": "Pickle",
218
+ ".pickle": "Pickle",
219
+ ".npy": "NumPy Array",
220
+ ".npz": "NumPy Archive",
221
+ ".h5": "HDF5",
222
+ ".hdf5": "HDF5",
223
+ ".nc": "NetCDF",
224
+ ".sqlite": "SQLite Database",
225
+ ".sqlite3": "SQLite Database",
226
+ ".db": "Database",
227
+ ".dbf": "dBASE",
228
+ ".mdb": "Access Database",
229
+ ".accdb": "Access Database",
230
+ ".lmdb": "LMDB",
231
+ ".leveldb": "LevelDB",
232
+
233
+ # ── Documents & Office ─────────────────────────────────────────────
234
+ ".md": "Markdown",
235
+ ".mdx": "MDX",
236
+ ".txt": "Plain Text",
237
+ ".text": "Plain Text",
238
+ ".log": "Log File",
239
+ ".rst": "reStructuredText",
240
+ ".adoc": "AsciiDoc",
241
+ ".org": "Org Mode",
242
+ ".tex": "LaTeX",
243
+ ".latex": "LaTeX",
244
+ ".bib": "BibTeX",
245
+ ".rtf": "Rich Text Format",
246
+ ".doc": "Microsoft Word",
247
+ ".docx": "Microsoft Word (OOXML)",
248
+ ".odt": "OpenDocument Text",
249
+ ".pdf": "PDF",
250
+ ".xls": "Microsoft Excel",
251
+ ".xlsx": "Microsoft Excel (OOXML)",
252
+ ".xlsm": "Excel Macro-Enabled",
253
+ ".xlsb": "Excel Binary",
254
+ ".ods": "OpenDocument Spreadsheet",
255
+ ".ppt": "Microsoft PowerPoint",
256
+ ".pptx": "Microsoft PowerPoint (OOXML)",
257
+ ".odp": "OpenDocument Presentation",
258
+ ".pages": "Apple Pages",
259
+ ".numbers": "Apple Numbers",
260
+ ".key": "Apple Keynote",
261
+ ".epub": "EPUB",
262
+ ".mobi": "Mobipocket",
263
+ ".djvu": "DjVu",
264
+ ".chm": "Compiled HTML Help",
265
+ ".man": "Man Page",
266
+ ".info": "GNU Info",
267
+
268
+ # ── Notebooks & Data Science ───────────────────────────────────────
269
+ ".ipynb": "Jupyter Notebook",
270
+ ".rmd": "R Markdown",
271
+ ".qmd": "Quarto Document",
272
+ ".dvc": "DVC File",
273
+ ".onnx": "ONNX Model",
274
+ ".pt": "PyTorch Model",
275
+ ".pth": "PyTorch Checkpoint",
276
+ ".safetensors": "SafeTensors Model",
277
+ ".gguf": "GGUF Model",
278
+ ".bin": "Binary File",
279
+
280
+ # ── Images ─────────────────────────────────────────────────────────
281
+ ".png": "PNG Image",
282
+ ".jpg": "JPEG Image",
283
+ ".jpeg": "JPEG Image",
284
+ ".gif": "GIF Image",
285
+ ".bmp": "Bitmap Image",
286
+ ".tiff": "TIFF Image",
287
+ ".tif": "TIFF Image",
288
+ ".webp": "WebP Image",
289
+ ".avif": "AVIF Image",
290
+ ".heic": "HEIC Image",
291
+ ".heif": "HEIF Image",
292
+ ".svg": "SVG Image",
293
+ ".ico": "Icon",
294
+ ".icns": "Apple Icon",
295
+ ".cur": "Cursor",
296
+ ".psd": "Photoshop",
297
+ ".ai": "Adobe Illustrator",
298
+ ".sketch": "Sketch",
299
+ ".fig": "Figma",
300
+ ".xd": "Adobe XD",
301
+ ".eps": "EPS Vector",
302
+ ".raw": "RAW Image",
303
+ ".cr2": "Canon RAW",
304
+ ".nef": "Nikon RAW",
305
+ ".arw": "Sony RAW",
306
+ ".dng": "DNG RAW",
307
+ ".exr": "OpenEXR",
308
+ ".hdr": "HDR Image",
309
+ ".pbm": "PBM Image",
310
+ ".pgm": "PGM Image",
311
+ ".ppm": "PPM Image",
312
+ ".pcx": "PCX Image",
313
+ ".tga": "TGA Image",
314
+
315
+ # ── Audio ──────────────────────────────────────────────────────────
316
+ ".mp3": "MP3 Audio",
317
+ ".wav": "WAV Audio",
318
+ ".flac": "FLAC Audio",
319
+ ".aac": "AAC Audio",
320
+ ".ogg": "Ogg Audio",
321
+ ".wma": "WMA Audio",
322
+ ".m4a": "M4A Audio",
323
+ ".opus": "Opus Audio",
324
+ ".aiff": "AIFF Audio",
325
+ ".mid": "MIDI",
326
+ ".midi": "MIDI",
327
+ ".amr": "AMR Audio",
328
+ ".ape": "APE Audio",
329
+ ".alac": "ALAC Audio",
330
+
331
+ # ── Video ──────────────────────────────────────────────────────────
332
+ ".mp4": "MP4 Video",
333
+ ".mkv": "MKV Video",
334
+ ".avi": "AVI Video",
335
+ ".mov": "QuickTime Video",
336
+ ".wmv": "WMV Video",
337
+ ".flv": "Flash Video",
338
+ ".webm": "WebM Video",
339
+ ".m4v": "M4V Video",
340
+ ".mpg": "MPEG Video",
341
+ ".mpeg": "MPEG Video",
342
+ ".3gp": "3GP Video",
343
+ ".ogv": "Ogg Video",
344
+ ".ts": "MPEG-TS",
345
+ ".vob": "DVD Video",
346
+ ".rm": "RealMedia",
347
+
348
+ # ── Fonts ──────────────────────────────────────────────────────────
349
+ ".ttf": "TrueType Font",
350
+ ".otf": "OpenType Font",
351
+ ".woff": "WOFF Font",
352
+ ".woff2": "WOFF2 Font",
353
+ ".eot": "EOT Font",
354
+ ".fon": "Bitmap Font",
355
+
356
+ # ── Archives / Compression ─────────────────────────────────────────
357
+ ".zip": "ZIP Archive",
358
+ ".gz": "Gzip Archive",
359
+ ".gzip": "Gzip Archive",
360
+ ".bz2": "Bzip2 Archive",
361
+ ".xz": "XZ Archive",
362
+ ".lz": "Lzip Archive",
363
+ ".lzma": "LZMA Archive",
364
+ ".zst": "Zstandard Archive",
365
+ ".tar": "Tar Archive",
366
+ ".tgz": "Tar+Gzip Archive",
367
+ ".tbz2": "Tar+Bzip2 Archive",
368
+ ".txz": "Tar+XZ Archive",
369
+ ".rar": "RAR Archive",
370
+ ".7z": "7-Zip Archive",
371
+ ".cab": "Cabinet Archive",
372
+ ".iso": "ISO Disk Image",
373
+ ".dmg": "macOS Disk Image",
374
+ ".img": "Disk Image",
375
+ ".vhd": "Virtual Hard Disk",
376
+ ".vhdx": "Virtual Hard Disk (VHDX)",
377
+ ".vmdk": "VMware Disk",
378
+ ".qcow2": "QEMU Disk",
379
+ ".deb": "Debian Package",
380
+ ".rpm": "RPM Package",
381
+ ".apk": "Android Package",
382
+ ".ipa": "iOS App",
383
+ ".snap": "Snap Package",
384
+ ".flatpak": "Flatpak Package",
385
+ ".appimage": "AppImage",
386
+ ".msi": "MSI Installer",
387
+ ".exe": "Windows Executable",
388
+ ".dll": "DLL Library",
389
+ ".so": "Shared Object",
390
+ ".dylib": "macOS Dynamic Library",
391
+ ".a": "Static Library",
392
+ ".lib": "Library",
393
+ ".o": "Object File",
394
+ ".obj": "Object File",
395
+ ".sys": "System File",
396
+ ".drv": "Driver",
397
+
398
+ # ── DevOps / CI / Containerisation ─────────────────────────────────
399
+ ".dockerfile":"Dockerfile",
400
+ ".vagrantfile":"Vagrantfile",
401
+ ".jenkinsfile":"Jenkinsfile",
402
+
403
+ # ── Trading / Domain-specific ──────────────────────────────────────
404
+ ".mq5": "MQL5 Source",
405
+ ".mq4": "MQL4 Source",
406
+ ".mqh": "MQL Header",
407
+ ".ex5": "MQL5 Compiled",
408
+ ".ex4": "MQL4 Compiled",
409
+ ".set": "MT Parameter Set",
410
+ ".pine": "Pine Script",
411
+ ".tpl": "MT Template",
412
+ ".chr": "MT Chart",
413
+ ".mql": "MQL Source",
414
+
415
+ # ── Misc / Build / Project ─────────────────────────────────────────
416
+ ".makefile": "Makefile",
417
+ ".cmake": "CMake",
418
+ ".gradle": "Gradle",
419
+ ".sbt": "SBT Build",
420
+ ".gemspec": "Ruby Gem Spec",
421
+ ".podspec": "CocoaPods Spec",
422
+ ".cabal": "Cabal (Haskell)",
423
+ ".csproj": "C# Project",
424
+ ".fsproj": "F# Project",
425
+ ".vbproj": "VB.NET Project",
426
+ ".sln": "Visual Studio Solution",
427
+ ".xcodeproj":"Xcode Project",
428
+ ".pbxproj": "Xcode Project (PBX)",
429
+ ".xcworkspace":"Xcode Workspace",
430
+ ".plist": "Property List",
431
+ ".lnk": "Windows Shortcut",
432
+ ".url": "URL Shortcut",
433
+ ".desktop": "Desktop Entry",
434
+ ".reg": "Windows Registry",
435
+ ".service": "Systemd Service",
436
+ ".timer": "Systemd Timer",
437
+ ".socket": "Systemd Socket",
438
+ ".lock": "Lock File",
439
+ ".patch": "Patch File",
440
+ ".diff": "Diff File",
441
+ ".map": "Source Map",
442
+ ".whl": "Python Wheel",
443
+ ".egg": "Python Egg",
444
+ ".gem": "Ruby Gem",
445
+ ".nupkg": "NuGet Package",
446
+ ".crate": "Rust Crate",
447
+
448
+ # ── SQL / Database ─────────────────────────────────────────────────
449
+ ".sql": "SQL",
450
+ ".mysql": "MySQL",
451
+ ".pgsql": "PostgreSQL",
452
+ ".plsql": "PL/SQL",
453
+
454
+ # ── GraphQL / API ──────────────────────────────────────────────────
455
+ ".graphql": "GraphQL",
456
+ ".gql": "GraphQL",
457
+ ".swagger": "Swagger",
458
+ ".openapi": "OpenAPI Spec",
459
+
460
+ # ── 3D / CAD / GIS ─────────────────────────────────────────────────
461
+ ".stl": "STL 3D Model",
462
+ ".obj": "Wavefront OBJ",
463
+ ".fbx": "FBX 3D Model",
464
+ ".gltf": "glTF 3D Model",
465
+ ".glb": "glTF Binary",
466
+ ".blend": "Blender File",
467
+ ".3ds": "3DS Model",
468
+ ".dae": "Collada",
469
+ ".usd": "USD Scene",
470
+ ".usda": "USD ASCII",
471
+ ".usdc": "USD Binary",
472
+ ".step": "STEP CAD",
473
+ ".stp": "STEP CAD",
474
+ ".iges": "IGES CAD",
475
+ ".igs": "IGES CAD",
476
+ ".dwg": "AutoCAD Drawing",
477
+ ".dxf": "AutoCAD Exchange",
478
+ ".shp": "Shapefile",
479
+ ".kml": "KML",
480
+ ".kmz": "KMZ",
481
+ ".gpx": "GPX Track",
482
+
483
+ # ── Certificates / Security ────────────────────────────────────────
484
+ ".pem": "PEM Certificate",
485
+ ".crt": "Certificate",
486
+ ".cer": "Certificate",
487
+ ".csr": "Certificate Request",
488
+ ".p12": "PKCS#12",
489
+ ".pfx": "PKCS#12",
490
+ ".asc": "PGP/GPG",
491
+ ".gpg": "GPG Encrypted",
492
+ ".sig": "Signature",
493
+ ".pub": "Public Key",
494
+
495
+ # ── Git-related ────────────────────────────────────────────────────
496
+ ".gitignore": "Git Ignore",
497
+ ".gitattributes": "Git Attributes",
498
+ ".gitmodules": "Git Submodules",
499
+
500
+ # ── Editor / IDE Config ────────────────────────────────────────────
501
+ ".editorconfig": "EditorConfig",
502
+ ".prettierrc": "Prettier Config",
503
+ ".eslintrc": "ESLint Config",
504
+ ".stylelintrc": "Stylelint Config",
505
+ ".babelrc": "Babel Config",
506
+ ".swcrc": "SWC Config",
507
+ ".nvmrc": "NVM Config",
508
+ ".npmrc": "NPM Config",
509
+ ".yarnrc": "Yarn Config",
510
+
511
+ # ── Misc ───────────────────────────────────────────────────────────
512
+ ".mw5": "MQL5 Variant",
513
+ ".webmanifest": "Web App Manifest",
514
+ }
515
+
516
+
517
+ # ---------------------------------------------------------------------------
518
+ # Default ignore patterns (common non-source dirs / files)
519
+ # ---------------------------------------------------------------------------
520
+ DEFAULT_IGNORE = {
521
+ ".git",
522
+ "__pycache__",
523
+ ".venv",
524
+ "venv",
525
+ "env",
526
+ "node_modules",
527
+ ".ipynb_checkpoints",
528
+ ".mypy_cache",
529
+ ".pytest_cache",
530
+ ".tox",
531
+ ".eggs",
532
+ "*.egg-info",
533
+ ".DS_Store",
534
+ "Thumbs.db",
535
+ "desktop.ini",
536
+ }
537
+
538
+
539
+ def should_ignore(name: str, ignore_set: set) -> bool:
540
+ """Return True if *name* matches any pattern in the ignore set."""
541
+ if name in ignore_set:
542
+ return True
543
+ for pattern in ignore_set:
544
+ if pattern.startswith("*") and name.endswith(pattern[1:]):
545
+ return True
546
+ return False
547
+
548
+
549
+ def get_label(ext: str) -> str:
550
+ """Return the human-readable label for an extension."""
551
+ if ext in EXT_LABELS:
552
+ return EXT_LABELS[ext]
553
+ # Fallback: capitalise the extension name
554
+ return ext.upper().lstrip(".")
555
+
556
+
557
+ def scan_files(root_path: str, ignore_set: set, exclude_exts: set) -> dict:
558
+ """
559
+ Walk *root_path* and collect per-extension statistics.
560
+
561
+ Returns a dict keyed by normalised extension string, e.g. ".py",
562
+ with values ``{"count": int, "size_bytes": int, "label": str}``.
563
+
564
+ Files without an extension are grouped under "(no extension)".
565
+ """
566
+
567
+ stats: dict = defaultdict(lambda: {"count": 0, "size_bytes": 0, "label": ""})
568
+
569
+ for dirpath, dirnames, filenames in os.walk(root_path):
570
+ # Prune ignored directories in-place so os.walk skips them
571
+ dirnames[:] = [
572
+ d for d in dirnames if not should_ignore(d, ignore_set)
573
+ ]
574
+
575
+ for fname in filenames:
576
+ if should_ignore(fname, ignore_set):
577
+ continue
578
+
579
+ filepath = os.path.join(dirpath, fname)
580
+
581
+ # Determine extension
582
+ _, ext = os.path.splitext(fname)
583
+ ext = ext.lower() # normalise
584
+
585
+ if ext and ext.lstrip(".") in exclude_exts:
586
+ continue
587
+
588
+ # Label
589
+ if ext:
590
+ label = f"{get_label(ext)} ({ext})"
591
+ else:
592
+ ext = "(none)"
593
+ label = "(no extension)"
594
+
595
+ try:
596
+ size = os.path.getsize(filepath)
597
+ except (OSError, PermissionError):
598
+ size = 0
599
+
600
+ stats[ext]["count"] += 1
601
+ stats[ext]["size_bytes"] += size
602
+ stats[ext]["label"] = label
603
+
604
+ return dict(stats)
605
+
606
+
607
+ def format_size_kb(size_bytes: int) -> str:
608
+ """Return exact size in KB, rounded to 1 decimal place."""
609
+ kb = size_bytes / 1024
610
+ if kb == 0:
611
+ return "0"
612
+ # Show 1 decimal place for precision, strip trailing zero if whole number
613
+ formatted = f"{kb:,.1f}"
614
+ return formatted
615
+
616
+
617
+ def build_table(stats: dict, sort_by: str) -> list[str]:
618
+ """
619
+ Build a Markdown table from *stats*.
620
+
621
+ Returns a list of lines.
622
+ """
623
+
624
+ # Prepare rows
625
+ rows = []
626
+ total_count = 0
627
+ total_bytes = 0
628
+
629
+ for ext, data in stats.items():
630
+ rows.append(
631
+ {
632
+ "label": data["label"],
633
+ "count": data["count"],
634
+ "size_bytes": data["size_bytes"],
635
+ "ext_key": ext,
636
+ }
637
+ )
638
+ total_count += data["count"]
639
+ total_bytes += data["size_bytes"]
640
+
641
+ # Sort
642
+ if sort_by == "count":
643
+ rows.sort(key=lambda r: (-r["count"], r["label"].lower()))
644
+ elif sort_by == "size":
645
+ rows.sort(key=lambda r: (-r["size_bytes"], r["label"].lower()))
646
+ else: # "ext"
647
+ rows.sort(key=lambda r: r["label"].lower())
648
+
649
+ # Build Markdown lines
650
+ lines = [
651
+ "| File Type | Count | Size (KB) |",
652
+ "| :--- | :--- | :--- |",
653
+ ]
654
+ for row in rows:
655
+ lines.append(
656
+ f"| {row['label']} | {row['count']} | {format_size_kb(row['size_bytes'])} |"
657
+ )
658
+
659
+ # Totals row
660
+ lines.append(f"| **Total** | **{total_count}** | **{format_size_kb(total_bytes)}** |")
661
+
662
+ return lines
663
+
664
+
665
+ def main() -> None:
666
+ parser = argparse.ArgumentParser(
667
+ description="Audit repository tech-stack (file types, counts, sizes)."
668
+ )
669
+ parser.add_argument(
670
+ "path",
671
+ nargs="?",
672
+ default=".",
673
+ help="Root directory to scan (default: current directory).",
674
+ )
675
+ parser.add_argument(
676
+ "--output",
677
+ "-o",
678
+ default=None,
679
+ help="Output Markdown file path (default: TECHSTACK.md in scanned dir).",
680
+ )
681
+ parser.add_argument(
682
+ "--ignore",
683
+ nargs="*",
684
+ default=None,
685
+ help="Extra directory/file names to ignore.",
686
+ )
687
+ parser.add_argument(
688
+ "--no-default-ignore",
689
+ action="store_true",
690
+ help="Disable the built-in ignore list.",
691
+ )
692
+ parser.add_argument(
693
+ "--exclude-ext",
694
+ nargs="*",
695
+ default=None,
696
+ help="File extensions to exclude from output (without dot, e.g. png mp4 git).",
697
+ )
698
+ parser.add_argument(
699
+ "--sort",
700
+ choices=["count", "size", "ext"],
701
+ default="count",
702
+ help="Sort order for the table (default: count descending).",
703
+ )
704
+ args = parser.parse_args()
705
+
706
+ root = os.path.abspath(args.path)
707
+ root_name = os.path.basename(root)
708
+
709
+ # Build ignore set
710
+ ignore_set: set = set() if args.no_default_ignore else set(DEFAULT_IGNORE)
711
+ if args.ignore:
712
+ ignore_set.update(args.ignore)
713
+
714
+ # Always ignore the output file itself
715
+ out_path = args.output or os.path.join(root, "TECHSTACK.md")
716
+ out_name = os.path.basename(out_path)
717
+ ignore_set.add(out_name)
718
+
719
+ # Excluded extensions
720
+ exclude_exts: set = set()
721
+ if args.exclude_ext:
722
+ exclude_exts = {e.lower().lstrip(".") for e in args.exclude_ext}
723
+
724
+ print(f"Scanning: {root}")
725
+ print(f"Ignoring: {', '.join(sorted(ignore_set))}")
726
+ if exclude_exts:
727
+ print(f"Excluding extensions: {', '.join(sorted(exclude_exts))}")
728
+
729
+ stats = scan_files(root, ignore_set, exclude_exts)
730
+ table_lines = build_table(stats, sort_by=args.sort)
731
+
732
+ # Compose Markdown
733
+ md_lines = [
734
+ f"## Techstack\n",
735
+ f"Audit of **{root_name}** project files (excluding environment and cache):\n",
736
+ ]
737
+ md_lines.extend(table_lines)
738
+ md_lines.append("") # trailing newline
739
+
740
+ content = "\n".join(md_lines)
741
+
742
+ with open(out_path, "w", encoding="utf-8") as fh:
743
+ fh.write(content)
744
+
745
+ total = sum(d["count"] for d in stats.values())
746
+ print(f"Done – {total} files across {len(stats)} types written to {out_path}")
747
+
748
+
749
+ if __name__ == "__main__":
750
+ main()