evolver-tools 1.5.0__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 (82) hide show
  1. evolver_tools-1.5.0/LICENSE +21 -0
  2. evolver_tools-1.5.0/PKG-INFO +107 -0
  3. evolver_tools-1.5.0/README.md +85 -0
  4. evolver_tools-1.5.0/pyproject.toml +72 -0
  5. evolver_tools-1.5.0/setup.cfg +4 -0
  6. evolver_tools-1.5.0/src/evolver_tools/__init__.py +2 -0
  7. evolver_tools-1.5.0/src/evolver_tools/__main__.py +3 -0
  8. evolver_tools-1.5.0/src/evolver_tools/cli.py +93 -0
  9. evolver_tools-1.5.0/src/evolver_tools/vendor/b64/__init__.py +2 -0
  10. evolver_tools-1.5.0/src/evolver_tools/vendor/b64/b64.py +176 -0
  11. evolver_tools-1.5.0/src/evolver_tools/vendor/cal_tool/__init__.py +1 -0
  12. evolver_tools-1.5.0/src/evolver_tools/vendor/cal_tool/cli.py +234 -0
  13. evolver_tools-1.5.0/src/evolver_tools/vendor/chart_cli/__init__.py +444 -0
  14. evolver_tools-1.5.0/src/evolver_tools/vendor/chart_cli/__main__.py +3 -0
  15. evolver_tools-1.5.0/src/evolver_tools/vendor/colors/__init__.py +5 -0
  16. evolver_tools-1.5.0/src/evolver_tools/vendor/colors/__main__.py +97 -0
  17. evolver_tools-1.5.0/src/evolver_tools/vendor/cron/__init__.py +413 -0
  18. evolver_tools-1.5.0/src/evolver_tools/vendor/cron/__main__.py +4 -0
  19. evolver_tools-1.5.0/src/evolver_tools/vendor/csv_stats/__init__.py +5 -0
  20. evolver_tools-1.5.0/src/evolver_tools/vendor/csv_stats/__main__.py +4 -0
  21. evolver_tools-1.5.0/src/evolver_tools/vendor/csv_stats/analyzer.py +258 -0
  22. evolver_tools-1.5.0/src/evolver_tools/vendor/csv_stats/cli.py +45 -0
  23. evolver_tools-1.5.0/src/evolver_tools/vendor/diff_tool/__init__.py +217 -0
  24. evolver_tools-1.5.0/src/evolver_tools/vendor/diff_tool/__main__.py +5 -0
  25. evolver_tools-1.5.0/src/evolver_tools/vendor/dirsize/__init__.py +183 -0
  26. evolver_tools-1.5.0/src/evolver_tools/vendor/dt_convert.py +123 -0
  27. evolver_tools-1.5.0/src/evolver_tools/vendor/envcheck/__init__.py +426 -0
  28. evolver_tools-1.5.0/src/evolver_tools/vendor/ff/__init__.py +427 -0
  29. evolver_tools-1.5.0/src/evolver_tools/vendor/ff/__main__.py +3 -0
  30. evolver_tools-1.5.0/src/evolver_tools/vendor/find_dups/__init__.py +7 -0
  31. evolver_tools-1.5.0/src/evolver_tools/vendor/find_dups/cli.py +392 -0
  32. evolver_tools-1.5.0/src/evolver_tools/vendor/hashsum/__init__.py +211 -0
  33. evolver_tools-1.5.0/src/evolver_tools/vendor/hashsum/__main__.py +5 -0
  34. evolver_tools-1.5.0/src/evolver_tools/vendor/http_live/__init__.py +265 -0
  35. evolver_tools-1.5.0/src/evolver_tools/vendor/http_live/__main__.py +2 -0
  36. evolver_tools-1.5.0/src/evolver_tools/vendor/ipcalc/__init__.py +155 -0
  37. evolver_tools-1.5.0/src/evolver_tools/vendor/ipcalc/__main__.py +5 -0
  38. evolver_tools-1.5.0/src/evolver_tools/vendor/ipinfo/__init__.py +3 -0
  39. evolver_tools-1.5.0/src/evolver_tools/vendor/ipinfo/__main__.py +30 -0
  40. evolver_tools-1.5.0/src/evolver_tools/vendor/jq_lite/__init__.py +257 -0
  41. evolver_tools-1.5.0/src/evolver_tools/vendor/jq_lite/__main__.py +5 -0
  42. evolver_tools-1.5.0/src/evolver_tools/vendor/json2csv/__init__.py +3 -0
  43. evolver_tools-1.5.0/src/evolver_tools/vendor/json2csv/__main__.py +82 -0
  44. evolver_tools-1.5.0/src/evolver_tools/vendor/jsonql/__init__.py +326 -0
  45. evolver_tools-1.5.0/src/evolver_tools/vendor/jsonql/__main__.py +5 -0
  46. evolver_tools-1.5.0/src/evolver_tools/vendor/license_cli/__init__.py +1 -0
  47. evolver_tools-1.5.0/src/evolver_tools/vendor/license_cli/__main__.py +4 -0
  48. evolver_tools-1.5.0/src/evolver_tools/vendor/license_cli/cli.py +289 -0
  49. evolver_tools-1.5.0/src/evolver_tools/vendor/markdown_check/__init__.py +211 -0
  50. evolver_tools-1.5.0/src/evolver_tools/vendor/nb/__init__.py +319 -0
  51. evolver_tools-1.5.0/src/evolver_tools/vendor/nb/__main__.py +3 -0
  52. evolver_tools-1.5.0/src/evolver_tools/vendor/passgen/__init__.py +224 -0
  53. evolver_tools-1.5.0/src/evolver_tools/vendor/portcheck/__init__.py +2 -0
  54. evolver_tools-1.5.0/src/evolver_tools/vendor/portcheck/__main__.py +66 -0
  55. evolver_tools-1.5.0/src/evolver_tools/vendor/project_doctor/__init__.py +412 -0
  56. evolver_tools-1.5.0/src/evolver_tools/vendor/project_doctor/__main__.py +3 -0
  57. evolver_tools-1.5.0/src/evolver_tools/vendor/ren/__init__.py +283 -0
  58. evolver_tools-1.5.0/src/evolver_tools/vendor/ren/__main__.py +3 -0
  59. evolver_tools-1.5.0/src/evolver_tools/vendor/siege_lite/__init__.py +250 -0
  60. evolver_tools-1.5.0/src/evolver_tools/vendor/siege_lite/__main__.py +3 -0
  61. evolver_tools-1.5.0/src/evolver_tools/vendor/smellfinder/__init__.py +376 -0
  62. evolver_tools-1.5.0/src/evolver_tools/vendor/smellfinder/__main__.py +3 -0
  63. evolver_tools-1.5.0/src/evolver_tools/vendor/sqlite_cli/__init__.py +326 -0
  64. evolver_tools-1.5.0/src/evolver_tools/vendor/sqlite_cli/__main__.py +5 -0
  65. evolver_tools-1.5.0/src/evolver_tools/vendor/sysmon/__init__.py +305 -0
  66. evolver_tools-1.5.0/src/evolver_tools/vendor/sysmon/__main__.py +3 -0
  67. evolver_tools-1.5.0/src/evolver_tools/vendor/timer/__init__.py +127 -0
  68. evolver_tools-1.5.0/src/evolver_tools/vendor/treedir/__init__.py +2 -0
  69. evolver_tools-1.5.0/src/evolver_tools/vendor/treedir/__main__.py +128 -0
  70. evolver_tools-1.5.0/src/evolver_tools/vendor/urlparse_tool/__init__.py +3 -0
  71. evolver_tools-1.5.0/src/evolver_tools/vendor/urlparse_tool/cli.py +212 -0
  72. evolver_tools-1.5.0/src/evolver_tools/vendor/uuid_tool/__init__.py +235 -0
  73. evolver_tools-1.5.0/src/evolver_tools/vendor/uuid_tool/__main__.py +6 -0
  74. evolver_tools-1.5.0/src/evolver_tools/vendor/web_summary/__init__.py +341 -0
  75. evolver_tools-1.5.0/src/evolver_tools/vendor/web_summary/__main__.py +3 -0
  76. evolver_tools-1.5.0/src/evolver_tools/vendor/wordcount/__init__.py +2 -0
  77. evolver_tools-1.5.0/src/evolver_tools/vendor/wordcount/__main__.py +101 -0
  78. evolver_tools-1.5.0/src/evolver_tools.egg-info/PKG-INFO +107 -0
  79. evolver_tools-1.5.0/src/evolver_tools.egg-info/SOURCES.txt +80 -0
  80. evolver_tools-1.5.0/src/evolver_tools.egg-info/dependency_links.txt +1 -0
  81. evolver_tools-1.5.0/src/evolver_tools.egg-info/entry_points.txt +38 -0
  82. evolver_tools-1.5.0/src/evolver_tools.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 EVOLVER
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,107 @@
1
+ Metadata-Version: 2.4
2
+ Name: evolver-tools
3
+ Version: 1.5.0
4
+ Summary: 36 essential CLI tools - one pip install
5
+ Author: EVOLVER
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://evolver-dev.github.io/evolver-tools
8
+ Project-URL: Repository, https://github.com/evolver-dev/evolver-tools
9
+ Keywords: cli,devops,productivity,developer-tools,terminal
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Topic :: Utilities
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Dynamic: license-file
22
+
23
+ # EVOLVER Tools
24
+
25
+ **36 essential CLI tools — one `pip install`.**
26
+
27
+ Zero-dependency (35/36), cross-platform, production-ready.
28
+ Monitor systems, analyze code, fuzzy-search data, query databases, and more.
29
+ 104KB total — one install, not 32.
30
+
31
+ ## Quick Start
32
+
33
+ ```bash
34
+ pip install evolver-tools
35
+ evtool list # Show all 32 tools
36
+ evtool ff < data.txt # Fuzzy search through data
37
+ evtool sysmon # Launch system monitor
38
+ evtool sqlite-cli my.db "SELECT * FROM users LIMIT 10"
39
+ ```
40
+
41
+ ## Tools
42
+
43
+ ### Ops
44
+
45
+ | Tool | Description |
46
+ |------|-------------|
47
+ | **sysmon** | Real-time system monitor (curses TUI — CPU/mem/disk/net/processes) |
48
+ | **dirsize** | Recursive directory space analyzer |
49
+ | **envcheck** | Environment variable validator (missing keys, formats) |
50
+ | **portcheck** | TCP port scanner & service detection |
51
+ | **siege-lite** | HTTP load tester (concurrency, latency percentile) |
52
+ | **http-live** | SSE hot-reload HTTP server for development |
53
+ | **ipinfo** | Public IP & geolocation lookup |
54
+ | **hashsum** | File hash verification (MD5/SHA-1/256/512/BLAKE2, auto-detect) |
55
+ | **find-dups** | Find duplicate files by SHA256 hash, size, or name |
56
+
57
+ ### Developer
58
+
59
+ | Tool | Description |
60
+ |------|-------------|
61
+ | **smellfinder** | Python code smell detector (AST-based, 10+ patterns) |
62
+ | **project-doctor** | Project health checker (meta, structure, quality) |
63
+ | **license-cli** | Open-source license generator/validator |
64
+ | **markdown-check** | Markdown format validator & style checker |
65
+ | **sqlite-cli** | SQLite query tool — CSV/JSON/table output |
66
+ | **b64** | Base64 encode/decode with auto-detection |
67
+ | **jsonql** | Zero-dep JSON query tool (SQL-like syntax) |
68
+ | **jq-lite** | jq-style JSON query — filter, extract, transform |
69
+ | **urlparse** | URL parser & debugger |
70
+ | **colors** | 256-color table & HEX↔RGB conversion |
71
+
72
+ ### Data & Analysis
73
+
74
+ | Tool | Description |
75
+ |------|-------------|
76
+ | **csv-stats** | CSV column analysis — histograms, frequencies, correlations |
77
+ | **json2csv** | JSON to CSV converter with nested key flattening |
78
+ | **chart-cli** | Terminal chart generator — bar, line, pie, histogram |
79
+ | **cal** | Calendar & date calculator |
80
+ | **web-summary** | Web page content extractor (title, body, links) |
81
+
82
+ ### Productivity
83
+
84
+ | Tool | Description |
85
+ |------|-------------|
86
+ | **ff** | Interactive fuzzy finder (like fzf, pure Python curses TUI) |
87
+ | **nb** | Command-line notebook (JSON storage, full-text search) |
88
+ | **ren** | Batch file renamer (prefix/suffix/regex/numbering) |
89
+ | **timer** | Countdown timer & stopwatch with desktop notifications |
90
+ | **treedir** | Directory tree visualizer with depth control |
91
+ | **wordcount** | Enhanced word/char/line counter with language detection |
92
+ | **dt** | Date/time format converter (timestamps, timezones) |
93
+
94
+ ### Security
95
+
96
+ | Tool | Description |
97
+ |------|-------------|
98
+ | **passgen** | Password generator with entropy display & charset rules |
99
+
100
+ ## Requirements
101
+
102
+ - Python 3.8+
103
+ - No external dependencies (31 of 32 tools use stdlib only; ipinfo uses ip-api.com)
104
+
105
+ ## License
106
+
107
+ MIT
@@ -0,0 +1,85 @@
1
+ # EVOLVER Tools
2
+
3
+ **36 essential CLI tools — one `pip install`.**
4
+
5
+ Zero-dependency (35/36), cross-platform, production-ready.
6
+ Monitor systems, analyze code, fuzzy-search data, query databases, and more.
7
+ 104KB total — one install, not 32.
8
+
9
+ ## Quick Start
10
+
11
+ ```bash
12
+ pip install evolver-tools
13
+ evtool list # Show all 32 tools
14
+ evtool ff < data.txt # Fuzzy search through data
15
+ evtool sysmon # Launch system monitor
16
+ evtool sqlite-cli my.db "SELECT * FROM users LIMIT 10"
17
+ ```
18
+
19
+ ## Tools
20
+
21
+ ### Ops
22
+
23
+ | Tool | Description |
24
+ |------|-------------|
25
+ | **sysmon** | Real-time system monitor (curses TUI — CPU/mem/disk/net/processes) |
26
+ | **dirsize** | Recursive directory space analyzer |
27
+ | **envcheck** | Environment variable validator (missing keys, formats) |
28
+ | **portcheck** | TCP port scanner & service detection |
29
+ | **siege-lite** | HTTP load tester (concurrency, latency percentile) |
30
+ | **http-live** | SSE hot-reload HTTP server for development |
31
+ | **ipinfo** | Public IP & geolocation lookup |
32
+ | **hashsum** | File hash verification (MD5/SHA-1/256/512/BLAKE2, auto-detect) |
33
+ | **find-dups** | Find duplicate files by SHA256 hash, size, or name |
34
+
35
+ ### Developer
36
+
37
+ | Tool | Description |
38
+ |------|-------------|
39
+ | **smellfinder** | Python code smell detector (AST-based, 10+ patterns) |
40
+ | **project-doctor** | Project health checker (meta, structure, quality) |
41
+ | **license-cli** | Open-source license generator/validator |
42
+ | **markdown-check** | Markdown format validator & style checker |
43
+ | **sqlite-cli** | SQLite query tool — CSV/JSON/table output |
44
+ | **b64** | Base64 encode/decode with auto-detection |
45
+ | **jsonql** | Zero-dep JSON query tool (SQL-like syntax) |
46
+ | **jq-lite** | jq-style JSON query — filter, extract, transform |
47
+ | **urlparse** | URL parser & debugger |
48
+ | **colors** | 256-color table & HEX↔RGB conversion |
49
+
50
+ ### Data & Analysis
51
+
52
+ | Tool | Description |
53
+ |------|-------------|
54
+ | **csv-stats** | CSV column analysis — histograms, frequencies, correlations |
55
+ | **json2csv** | JSON to CSV converter with nested key flattening |
56
+ | **chart-cli** | Terminal chart generator — bar, line, pie, histogram |
57
+ | **cal** | Calendar & date calculator |
58
+ | **web-summary** | Web page content extractor (title, body, links) |
59
+
60
+ ### Productivity
61
+
62
+ | Tool | Description |
63
+ |------|-------------|
64
+ | **ff** | Interactive fuzzy finder (like fzf, pure Python curses TUI) |
65
+ | **nb** | Command-line notebook (JSON storage, full-text search) |
66
+ | **ren** | Batch file renamer (prefix/suffix/regex/numbering) |
67
+ | **timer** | Countdown timer & stopwatch with desktop notifications |
68
+ | **treedir** | Directory tree visualizer with depth control |
69
+ | **wordcount** | Enhanced word/char/line counter with language detection |
70
+ | **dt** | Date/time format converter (timestamps, timezones) |
71
+
72
+ ### Security
73
+
74
+ | Tool | Description |
75
+ |------|-------------|
76
+ | **passgen** | Password generator with entropy display & charset rules |
77
+
78
+ ## Requirements
79
+
80
+ - Python 3.8+
81
+ - No external dependencies (31 of 32 tools use stdlib only; ipinfo uses ip-api.com)
82
+
83
+ ## License
84
+
85
+ MIT
@@ -0,0 +1,72 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "evolver-tools"
7
+ version = "1.5.0"
8
+ description = "36 essential CLI tools - one pip install"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.8"
12
+ keywords = ["cli", "devops", "productivity", "developer-tools", "terminal"]
13
+ authors = [
14
+ {name = "EVOLVER"},
15
+ ]
16
+ classifiers = [
17
+ "Development Status :: 5 - Production/Stable",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "Intended Audience :: System Administrators",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3 :: Only",
24
+ "Topic :: Utilities",
25
+ ]
26
+
27
+ [project.urls]
28
+ Homepage = "https://evolver-dev.github.io/evolver-tools"
29
+ Repository = "https://github.com/evolver-dev/evolver-tools"
30
+
31
+ [project.scripts]
32
+ evtool = "evolver_tools.cli:main"
33
+ b64 = "evolver_tools.vendor.b64:main"
34
+ ff = "evolver_tools.vendor.ff:main"
35
+ cal = "evolver_tools.vendor.cal_tool.cli:main"
36
+ chart-cli = "evolver_tools.vendor.chart_cli:main"
37
+ colors = "evolver_tools.vendor.colors:main"
38
+ cron = "evolver_tools.vendor.cron:main"
39
+ csv-stats = "evolver_tools.vendor.csv_stats.cli:main"
40
+ diff = "evolver_tools.vendor.diff_tool:main"
41
+ dirsize = "evolver_tools.vendor.dirsize:entry"
42
+ dt = "evolver_tools.vendor.dt_convert:main"
43
+ envcheck = "evolver_tools.vendor.envcheck:main"
44
+ find-dups = "evolver_tools.vendor.find_dups.cli:main"
45
+ hashsum = "evolver_tools.vendor.hashsum:main"
46
+ http-live = "evolver_tools.vendor.http_live:main"
47
+ ipcalc = "evolver_tools.vendor.ipcalc:main"
48
+ ipinfo = "evolver_tools.vendor.ipinfo:main"
49
+ jq-lite = "evolver_tools.vendor.jq_lite:main"
50
+ json2csv = "evolver_tools.vendor.json2csv:main"
51
+ jsonql = "evolver_tools.vendor.jsonql:main"
52
+ license-cli = "evolver_tools.vendor.license_cli.cli:main"
53
+ markdown-check = "evolver_tools.vendor.markdown_check:main"
54
+ nb = "evolver_tools.vendor.nb:main"
55
+ passgen = "evolver_tools.vendor.passgen:entry"
56
+ portcheck = "evolver_tools.vendor.portcheck.__main__:main"
57
+ project-doctor = "evolver_tools.vendor.project_doctor:main"
58
+ ren = "evolver_tools.vendor.ren:main"
59
+ siege-lite = "evolver_tools.vendor.siege_lite:main"
60
+ smellfinder = "evolver_tools.vendor.smellfinder:main"
61
+ sqlite-cli = "evolver_tools.vendor.sqlite_cli:main"
62
+ sysmon = "evolver_tools.vendor.sysmon:entry"
63
+ timer = "evolver_tools.vendor.timer:entry"
64
+ treedir = "evolver_tools.vendor.treedir.__main__:main"
65
+ urlparse = "evolver_tools.vendor.urlparse_tool.cli:main"
66
+ uuid = "evolver_tools.vendor.uuid_tool:main"
67
+ web-summary = "evolver_tools.vendor.web_summary:main"
68
+ wordcount = "evolver_tools.vendor.wordcount.__main__:main"
69
+
70
+ [tool.setuptools.packages.find]
71
+ where = ["src"]
72
+ include = ["evolver_tools*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ """evolver-tools: 23 CLI tools in one package."""
2
+ __version__ = "1.0.0"
@@ -0,0 +1,3 @@
1
+ """python -m evolver_tools"""
2
+ from .cli import main
3
+ main()
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env python3
2
+ """evolver CLI - Unified interface for all EVOLVER tools."""
3
+
4
+ import sys, importlib, os
5
+
6
+ # Tool registry
7
+ TOOLS = {
8
+ "b64": {"module": "evolver_tools.vendor.b64", "func": "main", "desc": "b64"},
9
+ "cal": {"module": "evolver_tools.vendor.cal_tool.cli", "func": "main", "desc": "Cal"},
10
+ "chart-cli": {"module": "evolver_tools.vendor.chart_cli", "func": "main", "desc": "Chart CLI"},
11
+ "colors": {"module": "evolver_tools.vendor.colors", "func": "main", "desc": "Colors"},
12
+ "cron": {"module": "evolver_tools.vendor.cron", "func": "main", "desc": "Cron expression parser"},
13
+ "csv-stats": {"module": "evolver_tools.vendor.csv_stats.cli", "func": "main", "desc": "csv-stats"},
14
+ "diff": {"module": "evolver_tools.vendor.diff_tool", "func": "main", "desc": "File comparator"},
15
+ "dirsize": {"module": "evolver_tools.vendor.dirsize", "func": "entry", "desc": "Dirsize"},
16
+ "dt": {"module": "evolver_tools.vendor.dt_convert", "func": "main", "desc": "Dt"},
17
+ "ff": {"module": "evolver_tools.vendor.ff", "func": "main", "desc": "Fuzzy Finder"},
18
+ "envcheck": {"module": "evolver_tools.vendor.envcheck", "func": "main", "desc": "Envcheck"},
19
+ "find-dups": {"module": "evolver_tools.vendor.find_dups.cli", "func": "main", "desc": "Find Dups"},
20
+ "hashsum": {"module": "evolver_tools.vendor.hashsum", "func": "main", "desc": "Hashsum"},
21
+ "http-live": {"module": "evolver_tools.vendor.http_live", "func": "main", "desc": "HTTP Live Server"},
22
+ "ipcalc": {"module": "evolver_tools.vendor.ipcalc", "func": "main", "desc": "IP/CIDR calculator"},
23
+ "ipinfo": {"module": "evolver_tools.vendor.ipinfo", "func": "main", "desc": "Ipinfo"},
24
+ "jq-lite": {"module": "evolver_tools.vendor.jq_lite", "func": "main", "desc": "Jq Lite"},
25
+ "json2csv": {"module": "evolver_tools.vendor.json2csv", "func": "main", "desc": "Json2Csv"},
26
+ "jsonql": {"module": "evolver_tools.vendor.jsonql", "func": "main", "desc": "JSONQL"},
27
+ "license-cli": {"module": "evolver_tools.vendor.license_cli.cli", "func": "main", "desc": "License CLI"},
28
+ "markdown-check": {"module": "evolver_tools.vendor.markdown_check", "func": "main", "desc": "Markdown Check"},
29
+ "nb": {"module": "evolver_tools.vendor.nb", "func": "main", "desc": "nb"},
30
+ "passgen": {"module": "evolver_tools.vendor.passgen", "func": "entry", "desc": "Passgen"},
31
+ "portcheck": {"module": "evolver_tools.vendor.portcheck.__main__", "func": "main", "desc": "Portcheck"},
32
+ "project-doctor": {"module": "evolver_tools.vendor.project_doctor", "func": "main", "desc": "Project Doctor"},
33
+ "ren": {"module": "evolver_tools.vendor.ren", "func": "main", "desc": "Ren"},
34
+ "siege-lite": {"module": "evolver_tools.vendor.siege_lite", "func": "main", "desc": "Siege Lite"},
35
+ "smellfinder": {"module": "evolver_tools.vendor.smellfinder", "func": "main", "desc": "Smellfinder"},
36
+ "sqlite-cli": {"module": "evolver_tools.vendor.sqlite_cli", "func": "main", "desc": "Sqlite CLI"},
37
+ "sysmon": {"module": "evolver_tools.vendor.sysmon", "func": "entry", "desc": "Sysmon"},
38
+ "timer": {"module": "evolver_tools.vendor.timer", "func": "entry", "desc": "Timer"},
39
+ "treedir": {"module": "evolver_tools.vendor.treedir.__main__", "func": "main", "desc": "Treedir"},
40
+ "urlparse": {"module": "evolver_tools.vendor.urlparse_tool.cli", "func": "main", "desc": "URL Parse"},
41
+ "uuid": {"module": "evolver_tools.vendor.uuid_tool", "func": "main", "desc": "UUID generator"},
42
+ "web-summary": {"module": "evolver_tools.vendor.web_summary", "func": "main", "desc": "Web Summary"},
43
+ "wordcount": {"module": "evolver_tools.vendor.wordcount.__main__", "func": "main", "desc": "Wordcount"},
44
+ }
45
+
46
+ def list_tools():
47
+ """Display all available tools."""
48
+ print('\x1b[1;36m===== EVOLVER Tools v1.5.0 =====\x1b[0m')
49
+ print()
50
+ for name, info in sorted(TOOLS.items()):
51
+ print(f' \033[1;33m{name:<18}\033[0m {info["desc"]}')
52
+ print()
53
+ print(f' Total: {len(TOOLS)} tools')
54
+ print()
55
+ print('Usage: evolver <toolname> [args...]')
56
+ print(' evolver list')
57
+
58
+ def run_tool(tool_name, args):
59
+ if tool_name not in TOOLS:
60
+ print(f'Unknown tool: {tool_name}')
61
+ sys.exit(1)
62
+ info = TOOLS[tool_name]
63
+ mod_path = info["module"]
64
+ func_name = info["func"]
65
+ old_argv = sys.argv
66
+ sys.argv = [tool_name] + args
67
+ try:
68
+ mod = importlib.import_module(mod_path)
69
+ func = getattr(mod, func_name)
70
+ result = func()
71
+ if result is not None:
72
+ print(result)
73
+ except KeyboardInterrupt:
74
+ pass
75
+ except Exception as e:
76
+ print(f'Error running {tool_name}: {e}', file=sys.stderr)
77
+ sys.exit(1)
78
+ finally:
79
+ sys.argv = old_argv
80
+
81
+ def main():
82
+ if len(sys.argv) < 2 or sys.argv[1] in ("-h", "--help"):
83
+ list_tools()
84
+ return
85
+ tool_name = sys.argv[1]
86
+ args = sys.argv[2:]
87
+ if tool_name == "list":
88
+ list_tools()
89
+ return
90
+ run_tool(tool_name, args)
91
+
92
+ if __name__ == "__main__":
93
+ main()
@@ -0,0 +1,2 @@
1
+ # b64 package — re-export from single file
2
+ from .b64 import *
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env python3
2
+ """b64 — 零依赖 Base64 编解码工具
3
+
4
+ Usage:
5
+ echo "hello" | b64 encode # 从 stdin 编码
6
+ echo "aGVsbG8K" | b64 decode # 从 stdin 解码
7
+ b64 encode file.txt # 从文件编码
8
+ b64 decode file.b64 # 从文件解码
9
+ b64 -n "hello" encode # 从参数编码
10
+ b64 -n "aGVsbG8K" decode # 从参数解码
11
+ """
12
+
13
+ import sys
14
+ import base64
15
+ import os
16
+
17
+
18
+ STDIN_MODE_AUTO = 'auto' # read stdin if no file and no -n
19
+
20
+
21
+ def encode_bytes(data: bytes) -> str:
22
+ return base64.b64encode(data).decode('ascii')
23
+
24
+
25
+ def decode_bytes(data: bytes, strict: bool = False) -> bytes:
26
+ try:
27
+ if strict:
28
+ # Strict mode: reject non-base64 characters
29
+ return base64.b64decode(data.strip(), validate=True)
30
+ return base64.b64decode(data.strip())
31
+ except Exception as e:
32
+ print(f"Error: invalid base64 input — {e}", file=sys.stderr)
33
+ sys.exit(1)
34
+
35
+ def is_valid_base64(data: bytes) -> bool:
36
+ """Check if data is valid base64 by testing decode+re-encode roundtrip."""
37
+ try:
38
+ # Use strict validation to reject non-base64 chars
39
+ decoded = base64.b64decode(data.strip(), validate=True)
40
+ # Verify roundtrip: re-encode and compare (stripped)
41
+ reencoded = base64.b64encode(decoded).rstrip(b'=')
42
+ cleaned = data.strip().rstrip(b'=')
43
+ return reencoded == cleaned
44
+ except Exception:
45
+ return False
46
+
47
+
48
+ def read_stdin() -> bytes:
49
+ try:
50
+ return sys.stdin.buffer.read()
51
+ except KeyboardInterrupt:
52
+ sys.exit(1)
53
+
54
+
55
+ def main():
56
+ args = sys.argv[1:]
57
+
58
+ # Parse --help / -h
59
+ if not args:
60
+ # Check for piped stdin — auto-detect mode
61
+ if not sys.stdin.isatty():
62
+ raw_stdin = read_stdin()
63
+ if not raw_stdin:
64
+ sys.exit(0)
65
+ if is_valid_base64(raw_stdin):
66
+ result = base64.b64decode(raw_stdin.strip()).decode('utf-8', errors='replace')
67
+ sys.stdout.write(result)
68
+ if not result.endswith('\n'):
69
+ sys.stdout.write('\n')
70
+ else:
71
+ sys.stdout.write(base64.b64encode(raw_stdin).decode('ascii') + '\n')
72
+ return
73
+ print(__doc__.strip())
74
+ return
75
+
76
+ if args[0] in ('-h', '--help'):
77
+ print(__doc__.strip())
78
+ return
79
+
80
+ # Check for -n (inline value)
81
+ if args[0] == '-n':
82
+ if len(args) < 3:
83
+ print("Error: -n requires both <value> and <action>", file=sys.stderr)
84
+ sys.exit(1)
85
+ value = args[1]
86
+ action = args[2]
87
+
88
+ if action == 'encode':
89
+ result = encode_bytes(value.encode('utf-8'))
90
+ elif action == 'decode':
91
+ result = decode_bytes(value)
92
+ result = result.decode('utf-8', errors='replace')
93
+ else:
94
+ print(f"Error: unknown action '{action}' (use encode/decode)", file=sys.stderr)
95
+ sys.exit(1)
96
+
97
+ sys.stdout.write(result)
98
+ if not result.endswith('\n'):
99
+ sys.stdout.write('\n')
100
+ return
101
+
102
+ # Parse <file> <action> or stdin
103
+ action = None
104
+ file_path = None
105
+
106
+ for i, arg in enumerate(args):
107
+ if arg in ('encode', 'decode'):
108
+ action = arg
109
+ elif arg.startswith('-'):
110
+ print(f"Error: unknown option '{arg}'", file=sys.stderr)
111
+ sys.exit(1)
112
+ else:
113
+ file_path = arg
114
+
115
+ if action is None and file_path:
116
+ if not os.path.isfile(file_path):
117
+ print(f"Error: file not found: {file_path}", file=sys.stderr)
118
+ sys.exit(1)
119
+ # Auto-detect: read file, check if it's valid base64
120
+ raw = open(file_path, 'rb').read()
121
+ if is_valid_base64(raw):
122
+ action = 'decode'
123
+ else:
124
+ action = 'encode'
125
+
126
+ if action is None:
127
+ # Remaining args are just the action
128
+ for arg in args:
129
+ if arg in ('encode', 'decode'):
130
+ action = arg
131
+ else:
132
+ file_path = arg
133
+
134
+ if action is None:
135
+ # Try to auto-detect from stdin content if piped
136
+ if not sys.stdin.isatty():
137
+ raw_stdin = read_stdin()
138
+ if not raw_stdin:
139
+ sys.exit(0)
140
+ # Heuristic: if looks like base64, decode; else encode
141
+ try:
142
+ base64.b64decode(raw_stdin.strip())
143
+ result = base64.b64decode(raw_stdin.strip()).decode('utf-8', errors='replace')
144
+ sys.stdout.write(result)
145
+ if not result.endswith('\n'):
146
+ sys.stdout.write('\n')
147
+ except Exception:
148
+ sys.stdout.write(base64.b64encode(raw_stdin).decode('ascii') + '\n')
149
+ return
150
+ print(__doc__.strip())
151
+ return
152
+
153
+ # Read source
154
+ if file_path:
155
+ if not os.path.isfile(file_path):
156
+ print(f"Error: file not found: {file_path}", file=sys.stderr)
157
+ sys.exit(1)
158
+ raw = open(file_path, 'rb').read()
159
+ else:
160
+ raw = read_stdin()
161
+ if not raw:
162
+ sys.exit(0)
163
+
164
+ if action == 'encode':
165
+ result = encode_bytes(raw)
166
+ else:
167
+ decoded = decode_bytes(raw)
168
+ result = decoded.decode('utf-8', errors='replace')
169
+
170
+ sys.stdout.write(result)
171
+ if not result.endswith('\n'):
172
+ sys.stdout.write('\n')
173
+
174
+
175
+ if __name__ == '__main__':
176
+ main()
@@ -0,0 +1 @@
1
+ __version__ = "1.0.0"