evolver-tools 13.0.0__tar.gz → 17.0.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 (238) hide show
  1. {evolver_tools-13.0.0/src/evolver_tools.egg-info → evolver_tools-17.0.0}/PKG-INFO +19 -2
  2. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/README.md +17 -0
  3. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/pyproject.toml +2 -2
  4. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/cli.py +1 -1
  5. evolver_tools-17.0.0/src/evolver_tools/vendor/ansi_strip.py +34 -0
  6. evolver_tools-17.0.0/src/evolver_tools/vendor/csv_view.py +157 -0
  7. evolver_tools-17.0.0/src/evolver_tools/vendor/env_diff.py +69 -0
  8. evolver_tools-17.0.0/src/evolver_tools/vendor/file_joiner.py +86 -0
  9. evolver_tools-17.0.0/src/evolver_tools/vendor/file_splitter.py +129 -0
  10. evolver_tools-17.0.0/src/evolver_tools/vendor/git_log_pretty.py +51 -0
  11. evolver_tools-17.0.0/src/evolver_tools/vendor/git_stats.py +93 -0
  12. evolver_tools-17.0.0/src/evolver_tools/vendor/hash_check.py +74 -0
  13. evolver_tools-17.0.0/src/evolver_tools/vendor/hash_file.py +63 -0
  14. evolver_tools-17.0.0/src/evolver_tools/vendor/ini2json.py +41 -0
  15. evolver_tools-17.0.0/src/evolver_tools/vendor/json2ini.py +51 -0
  16. evolver_tools-17.0.0/src/evolver_tools/vendor/key_value_store.py +123 -0
  17. evolver_tools-17.0.0/src/evolver_tools/vendor/license.py +158 -0
  18. evolver_tools-17.0.0/src/evolver_tools/vendor/port_scan.py +75 -0
  19. evolver_tools-17.0.0/src/evolver_tools/vendor/qc_calc.py +585 -0
  20. evolver_tools-17.0.0/src/evolver_tools/vendor/qc_report.py +181 -0
  21. evolver_tools-17.0.0/src/evolver_tools/vendor/qc_sample.py +239 -0
  22. evolver_tools-17.0.0/src/evolver_tools/vendor/qr_cli.py +88 -0
  23. evolver_tools-17.0.0/src/evolver_tools/vendor/quote.py +55 -0
  24. evolver_tools-17.0.0/src/evolver_tools/vendor/random.py +104 -0
  25. evolver_tools-17.0.0/src/evolver_tools/vendor/screen_recorder.py +147 -0
  26. evolver_tools-17.0.0/src/evolver_tools/vendor/template.py +207 -0
  27. evolver_tools-17.0.0/src/evolver_tools/vendor/toml2json.py +58 -0
  28. evolver_tools-17.0.0/src/evolver_tools/vendor/tree.py +106 -0
  29. evolver_tools-17.0.0/src/evolver_tools/vendor/uri_encode.py +39 -0
  30. evolver_tools-17.0.0/src/evolver_tools/vendor/url_parser.py +72 -0
  31. evolver_tools-17.0.0/src/evolver_tools/vendor/web_download.py +77 -0
  32. evolver_tools-17.0.0/src/evolver_tools/vendor/yaml2toml.py +63 -0
  33. {evolver_tools-13.0.0 → evolver_tools-17.0.0/src/evolver_tools.egg-info}/PKG-INFO +19 -2
  34. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools.egg-info/SOURCES.txt +28 -0
  35. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/LICENSE +0 -0
  36. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/setup.cfg +0 -0
  37. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/__init__.py +0 -0
  38. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/__main__.py +0 -0
  39. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/autoreg.py +0 -0
  40. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/__init__.py +0 -0
  41. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/agent_b_tool.py +0 -0
  42. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/api_tester.py +0 -0
  43. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ascii_gen.py +0 -0
  44. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/audit_log.py +0 -0
  45. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/b64/__init__.py +0 -0
  46. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/b64/b64.py +0 -0
  47. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/backup.py +0 -0
  48. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/banner/__init__.py +0 -0
  49. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/banner/banner.py +0 -0
  50. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/banner.py +0 -0
  51. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/bookmark.py +0 -0
  52. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/cal_tool/__init__.py +0 -0
  53. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/cal_tool/cli.py +0 -0
  54. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/calendar_cli.py +0 -0
  55. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/cert_check.py +0 -0
  56. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/cert_info.py +0 -0
  57. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/changelog_gen/__init__.py +0 -0
  58. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/changelog_gen/changelog_gen.py +0 -0
  59. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/changelog_gen.py +0 -0
  60. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/chart_cli/__init__.py +0 -0
  61. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/chart_cli/__main__.py +0 -0
  62. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/checksum_dir.py +0 -0
  63. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/clipboard/__init__.py +0 -0
  64. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/clipboard/clipboard.py +0 -0
  65. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/code_auditor.py +0 -0
  66. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/code_stats.py +0 -0
  67. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/colorize.py +0 -0
  68. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/colors/__init__.py +0 -0
  69. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/colors/__main__.py +0 -0
  70. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/config_validator.py +0 -0
  71. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/config_vault.py +0 -0
  72. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/cron/__init__.py +0 -0
  73. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/cron/__main__.py +0 -0
  74. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/cron_pretty.py +0 -0
  75. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/crontab_helper.py +0 -0
  76. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/crypto_box.py +0 -0
  77. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/crypto_price.py +0 -0
  78. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/csv2json.py +0 -0
  79. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/csv_stats/__init__.py +0 -0
  80. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/csv_stats/__main__.py +0 -0
  81. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/csv_stats/analyzer.py +0 -0
  82. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/csv_stats/cli.py +0 -0
  83. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/csv_validate.py +0 -0
  84. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/db_mate.py +0 -0
  85. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/db_schema.py +0 -0
  86. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/dep_graph.py +0 -0
  87. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/dev_dashboard.py +0 -0
  88. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/dice_roll.py +0 -0
  89. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/diff_csv.py +0 -0
  90. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/diff_tool/__init__.py +0 -0
  91. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/diff_tool/__main__.py +0 -0
  92. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/dirsize/__init__.py +0 -0
  93. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/disk_cleanup.py +0 -0
  94. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/disk_usage/__init__.py +0 -0
  95. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/disk_usage/disk_usage.py +0 -0
  96. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/dns_lookup.py +0 -0
  97. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/docker_helper.py +0 -0
  98. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/dt_convert.py +0 -0
  99. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/env_manager.py +0 -0
  100. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/envcheck/__init__.py +0 -0
  101. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/excel2csv.py +0 -0
  102. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ff/__init__.py +0 -0
  103. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ff/__main__.py +0 -0
  104. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/figlet_cli.py +0 -0
  105. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/figlet_tool.py +0 -0
  106. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/file_encrypt.py +0 -0
  107. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/file_watch.py +0 -0
  108. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/find_dups/__init__.py +0 -0
  109. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/find_dups/cli.py +0 -0
  110. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/firewall_rule.py +0 -0
  111. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/fmt/__init__.py +0 -0
  112. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/fmt/fmt.py +0 -0
  113. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/geo_ip.py +0 -0
  114. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/git_branch_cleaner.py +0 -0
  115. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/hashsum/__init__.py +0 -0
  116. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/hashsum/__main__.py +0 -0
  117. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/hex_tool.py +0 -0
  118. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/html2markdown.py +0 -0
  119. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/html2md.py +0 -0
  120. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/http_headers.py +0 -0
  121. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/http_live/__init__.py +0 -0
  122. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/http_live/__main__.py +0 -0
  123. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/image_meta.py +0 -0
  124. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ini_parser/__init__.py +0 -0
  125. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ini_parser/ini_parser.py +0 -0
  126. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ip_location.py +0 -0
  127. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ipcalc/__init__.py +0 -0
  128. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ipcalc/__main__.py +0 -0
  129. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ipinfo/__init__.py +0 -0
  130. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ipinfo/__main__.py +0 -0
  131. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/join.py +0 -0
  132. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/joke.py +0 -0
  133. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/jq_lite/__init__.py +0 -0
  134. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/jq_lite/__main__.py +0 -0
  135. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/json2csv/__init__.py +0 -0
  136. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/json2csv/__main__.py +0 -0
  137. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/json_pretty/__init__.py +0 -0
  138. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/json_pretty/json_pretty.py +0 -0
  139. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/json_schema_validate.py +0 -0
  140. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/jsonql/__init__.py +0 -0
  141. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/jsonql/__main__.py +0 -0
  142. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/license_cli/__init__.py +0 -0
  143. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/license_cli/__main__.py +0 -0
  144. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/license_cli/cli.py +0 -0
  145. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/log_analyzer.py +0 -0
  146. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/log_hawk.py +0 -0
  147. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/log_tail.py +0 -0
  148. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/macrogen.py +0 -0
  149. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/markdown_check/__init__.py +0 -0
  150. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/markdown_preview.py +0 -0
  151. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/markdown_toc.py +0 -0
  152. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/media_studio.py +0 -0
  153. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/morse.py +0 -0
  154. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/nb/__init__.py +0 -0
  155. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/nb/__main__.py +0 -0
  156. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/net_analyzer.py +0 -0
  157. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/net_speed.py +0 -0
  158. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/network_scan.py +0 -0
  159. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/note_taker.py +0 -0
  160. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/otp_gen.py +0 -0
  161. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/passgen/__init__.py +0 -0
  162. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/password_strength.py +0 -0
  163. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/pdf_text.py +0 -0
  164. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/pipe_viewer.py +0 -0
  165. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/portcheck/__init__.py +0 -0
  166. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/portcheck/__main__.py +0 -0
  167. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/pr_tool/__init__.py +0 -0
  168. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/pr_tool/pr_tool.py +0 -0
  169. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/process_kill.py +0 -0
  170. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/progress_bar.py +0 -0
  171. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/project_doctor/__init__.py +0 -0
  172. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/project_doctor/__main__.py +0 -0
  173. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/qrcode.py +0 -0
  174. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/quote_tool/__init__.py +0 -0
  175. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/quote_tool/quote.py +0 -0
  176. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/rainbow.py +0 -0
  177. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/reminder.py +0 -0
  178. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ren/__init__.py +0 -0
  179. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ren/__main__.py +0 -0
  180. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/replace_text.py +0 -0
  181. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/restore.py +0 -0
  182. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/route_trace.py +0 -0
  183. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/scan_ports.py +0 -0
  184. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/screenshot_cli.py +0 -0
  185. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/search_files.py +0 -0
  186. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/search_history.py +0 -0
  187. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/secret_scanner.py +0 -0
  188. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/service_check.py +0 -0
  189. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/shuffle.py +0 -0
  190. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/siege_lite/__init__.py +0 -0
  191. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/siege_lite/__main__.py +0 -0
  192. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/smellfinder/__init__.py +0 -0
  193. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/smellfinder/__main__.py +0 -0
  194. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/sort/__init__.py +0 -0
  195. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/sort/sort.py +0 -0
  196. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/spinner.py +0 -0
  197. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/split.py +0 -0
  198. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/split_tool/__init__.py +0 -0
  199. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/split_tool/split.py +0 -0
  200. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/sql2csv.py +0 -0
  201. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/sqlite_cli/__init__.py +0 -0
  202. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/sqlite_cli/__main__.py +0 -0
  203. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ssh_key_gen.py +0 -0
  204. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/ssl_check.py +0 -0
  205. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/stopwatch.py +0 -0
  206. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/sysmon/__init__.py +0 -0
  207. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/sysmon/__main__.py +0 -0
  208. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/sysmon_pro.py +0 -0
  209. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/system_info.py +0 -0
  210. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/temp_cleaner.py +0 -0
  211. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/text_stats.py +0 -0
  212. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/timer/__init__.py +0 -0
  213. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/timer_pro/__init__.py +0 -0
  214. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/timer_pro/timer_pro.py +0 -0
  215. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/timer_pro.py +0 -0
  216. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/todo_cli.py +0 -0
  217. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/treedir/__init__.py +0 -0
  218. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/treedir/__main__.py +0 -0
  219. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/uniq_tool/__init__.py +0 -0
  220. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/uniq_tool/uniq.py +0 -0
  221. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/unit_convert.py +0 -0
  222. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/urlparse_tool/__init__.py +0 -0
  223. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/urlparse_tool/cli.py +0 -0
  224. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/uuid_tool/__init__.py +0 -0
  225. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/uuid_tool/__main__.py +0 -0
  226. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/weather_cli.py +0 -0
  227. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/web_summary/__init__.py +0 -0
  228. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/web_summary/__main__.py +0 -0
  229. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/whois_lookup.py +0 -0
  230. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/wordcount/__init__.py +0 -0
  231. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/wordcount/__main__.py +0 -0
  232. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/xml2json.py +0 -0
  233. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/yaml2json/__init__.py +0 -0
  234. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/yaml2json/yaml2json.py +0 -0
  235. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools/vendor/yaml_validate.py +0 -0
  236. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools.egg-info/dependency_links.txt +0 -0
  237. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools.egg-info/entry_points.txt +0 -0
  238. {evolver_tools-13.0.0 → evolver_tools-17.0.0}/src/evolver_tools.egg-info/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: evolver-tools
3
- Version: 13.0.0
4
- Summary: 144 CLI tools + 9 flagship projects — one pip install
3
+ Version: 17.0.0
4
+ Summary: 171 CLI tools + 9 flagship projects — one pip install
5
5
  Author: EVOLVER
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://evolver-dev.github.io/evolver-tools
@@ -107,6 +107,23 @@ evtool sort -n data.txt # Numeric sort
107
107
  - Python 3.8+
108
108
  - No external dependencies (38 of 39 tools use stdlib only; ipinfo hits ip-api.com)
109
109
 
110
+ ## Pricing
111
+
112
+ evolver-tools is **MIT open source** — free for everyone, forever.
113
+
114
+ | Tier | Price | What you get |
115
+ |------|-------|-------------|
116
+ | **Free (MIT)** | ¥0 | All 167 tools, full source, forever |
117
+ | **Full Suite** | ¥79 one-time | All tools + priority support + early access + name in credits |
118
+ | **Sponsor** | ¥5/month | GitHub Sponsors badge + Discord + vote on priorities |
119
+ | **Enterprise Basic** | ¥500/year | Custom tool development |
120
+ | **Enterprise Premium** | ¥2,000/year | Dedicated maintenance + 24h emergency fixes |
121
+ | **Enterprise Ultimate** | ¥5,000/year | Full source license + unlimited custom dev + white-label |
122
+
123
+ 👉 **[View full pricing page](https://evolver-dev.github.io/evolver-tools/pricing/)** — includes feature comparison table, testimonials, and FAQ.
124
+
125
+ Support the project via one-time purchase (¥79) or monthly sponsorship on [GitHub Sponsors](https://github.com/sponsors/evolver-dev).
126
+
110
127
  ## License
111
128
 
112
129
  MIT
@@ -85,6 +85,23 @@ evtool sort -n data.txt # Numeric sort
85
85
  - Python 3.8+
86
86
  - No external dependencies (38 of 39 tools use stdlib only; ipinfo hits ip-api.com)
87
87
 
88
+ ## Pricing
89
+
90
+ evolver-tools is **MIT open source** — free for everyone, forever.
91
+
92
+ | Tier | Price | What you get |
93
+ |------|-------|-------------|
94
+ | **Free (MIT)** | ¥0 | All 167 tools, full source, forever |
95
+ | **Full Suite** | ¥79 one-time | All tools + priority support + early access + name in credits |
96
+ | **Sponsor** | ¥5/month | GitHub Sponsors badge + Discord + vote on priorities |
97
+ | **Enterprise Basic** | ¥500/year | Custom tool development |
98
+ | **Enterprise Premium** | ¥2,000/year | Dedicated maintenance + 24h emergency fixes |
99
+ | **Enterprise Ultimate** | ¥5,000/year | Full source license + unlimited custom dev + white-label |
100
+
101
+ 👉 **[View full pricing page](https://evolver-dev.github.io/evolver-tools/pricing/)** — includes feature comparison table, testimonials, and FAQ.
102
+
103
+ Support the project via one-time purchase (¥79) or monthly sponsorship on [GitHub Sponsors](https://github.com/sponsors/evolver-dev).
104
+
88
105
  ## License
89
106
 
90
107
  MIT
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "evolver-tools"
7
- version = "13.0.0"
8
- description = "144 CLI tools + 9 flagship projects — one pip install"
7
+ version = "17.0.0"
8
+ description = "171 CLI tools + 9 flagship projects — one pip install"
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  requires-python = ">=3.8"
@@ -14,7 +14,7 @@ from evolver_tools.autoreg import auto_discover
14
14
  def list_tools():
15
15
  """Display all available tools."""
16
16
  tools = auto_discover()
17
- print(f'\x1b[1;36m===== EVOLVER Tools v13.0.0 =====\x1b[0m')
17
+ print(f'\x1b[1;36m===== EVOLVER Tools v17.0.0 =====\x1b[0m')
18
18
  print()
19
19
  for name, info in sorted(tools.items()):
20
20
  print(f' \033[1;33m{name:<18}\033[0m {info["desc"]}')
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env python3
2
+ """ansi-strip — Strip ANSI escape codes from text."""
3
+ import re
4
+ import sys
5
+
6
+ TOOL_META = {
7
+ "name": "ansi-strip",
8
+ "func": "main",
9
+ "desc": "Strip ANSI escape codes. Usage: ansi-strip [file]",
10
+ }
11
+
12
+ ANSI_PATTERN = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
13
+
14
+ def main():
15
+ args = sys.argv[1:]
16
+ if args and args[0] in ("-h", "--help"):
17
+ print("Usage: ansi-strip [file]")
18
+ print(" command_with_colors | ansi-strip")
19
+ return
20
+ if args:
21
+ filepath = args[0]
22
+ try:
23
+ with open(filepath, "r") as f:
24
+ text = f.read()
25
+ except Exception as e:
26
+ print(f"Error: {e}", file=sys.stderr)
27
+ sys.exit(1)
28
+ else:
29
+ text = sys.stdin.read()
30
+ result = ANSI_PATTERN.sub("", text)
31
+ sys.stdout.write(result)
32
+
33
+ if __name__ == "__main__":
34
+ main()
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env python3
2
+ """csv-view — CSV/TSV viewer that prints formatted tables with auto-delimiter detection."""
3
+
4
+ import csv
5
+ import io
6
+ import os
7
+ import sys
8
+
9
+ TOOL_META = {
10
+ "name": "csv-view",
11
+ "func": "main",
12
+ "desc": "View CSV/TSV files as formatted tables. Usage: csv-view file.csv [--head N] [--tail N]",
13
+ }
14
+
15
+
16
+ def detect_delimiter(first_line):
17
+ """Auto-detect delimiter: tab, comma, semicolon, pipe."""
18
+ candidates = {"\t": 0, ",": 0, ";": 0, "|": 0}
19
+ for ch in candidates:
20
+ candidates[ch] = first_line.count(ch)
21
+ # Prefer tab if it appears, otherwise best comma/separator
22
+ if candidates["\t"] > 0:
23
+ return "\t"
24
+ # Find delimiter with highest count
25
+ best_delim = ","
26
+ best_count = 0
27
+ for d, count in candidates.items():
28
+ if count > best_count:
29
+ best_count = count
30
+ best_delim = d
31
+ if best_count == 0:
32
+ return "," # fallback
33
+ return best_delim
34
+
35
+
36
+ def read_table(filepath, head=None, tail=None):
37
+ """Read and parse CSV/TSV file, return (rows, delimiter, has_header)."""
38
+ if not os.path.isfile(filepath):
39
+ print(f"Error: file not found: {filepath}", file=sys.stderr)
40
+ sys.exit(1)
41
+
42
+ try:
43
+ with open(filepath, "r", encoding="utf-8", errors="replace") as f:
44
+ content = f.read()
45
+ except Exception as e:
46
+ print(f"Error reading file: {e}", file=sys.stderr)
47
+ sys.exit(1)
48
+
49
+ if not content.strip():
50
+ print("(empty file)")
51
+ sys.exit(0)
52
+
53
+ # Detect delimiter from first line
54
+ first_line = content.split("\n", 1)[0]
55
+ delimiter = detect_delimiter(first_line)
56
+
57
+ reader = csv.reader(io.StringIO(content), delimiter=delimiter)
58
+ all_rows = [row for row in reader]
59
+
60
+ if not all_rows:
61
+ print("(no data)")
62
+ sys.exit(0)
63
+
64
+ if head is not None and tail is not None:
65
+ rows = all_rows[:head] + all_rows[-tail:]
66
+ elif head is not None:
67
+ rows = all_rows[:head]
68
+ elif tail is not None:
69
+ rows = all_rows[-tail:]
70
+ else:
71
+ rows = all_rows
72
+
73
+ return rows, delimiter
74
+
75
+
76
+ def format_table(rows):
77
+ """Return a formatted string with aligned columns."""
78
+ if not rows:
79
+ return "(no data)"
80
+
81
+ # Calculate column widths
82
+ num_cols = max(len(row) for row in rows) if rows else 0
83
+ if num_cols == 0:
84
+ return "(no columns)"
85
+
86
+ col_widths = [0] * num_cols
87
+ for row in rows:
88
+ for i, cell in enumerate(row):
89
+ if i < num_cols:
90
+ col_widths[i] = max(col_widths[i], len(cell))
91
+
92
+ # Cap width at 120 to prevent extreme wrapping
93
+ col_widths = [min(w, 120) for w in col_widths]
94
+
95
+ # Build separator line
96
+ sep = "─" * (sum(col_widths) + len(col_widths) * 3 + 1)
97
+
98
+ lines = [sep]
99
+ for row_idx, row in enumerate(rows):
100
+ parts = []
101
+ for i in range(num_cols):
102
+ val = row[i] if i < len(row) else ""
103
+ if len(val) > 120:
104
+ val = val[:117] + "..."
105
+ parts.append(val.ljust(col_widths[i]))
106
+ lines.append("│ " + " │ ".join(parts) + " │")
107
+ if row_idx == 0:
108
+ lines.append(sep) # after header
109
+
110
+ lines.append(sep)
111
+ return "\n".join(lines)
112
+
113
+
114
+ def main():
115
+ args = sys.argv[1:]
116
+ if not args or args[0] in ("-h", "--help"):
117
+ print("Usage: csv-view <file> [--head N] [--tail N]")
118
+ print()
119
+ print("Options:")
120
+ print(" --head N Show only first N rows")
121
+ print(" --tail N Show only last N rows")
122
+ print(" --head N --tail N Show first N and last N rows")
123
+ print()
124
+ print("Auto-detects delimiter (comma, tab, semicolon, pipe).")
125
+ return
126
+
127
+ filepath = args[0]
128
+ head = None
129
+ tail = None
130
+
131
+ i = 1
132
+ while i < len(args):
133
+ if args[i] == "--head" and i + 1 < len(args):
134
+ try:
135
+ head = int(args[i + 1])
136
+ except ValueError:
137
+ print("Error: --head requires an integer", file=sys.stderr)
138
+ sys.exit(1)
139
+ i += 2
140
+ elif args[i] == "--tail" and i + 1 < len(args):
141
+ try:
142
+ tail = int(args[i + 1])
143
+ except ValueError:
144
+ print("Error: --tail requires an integer", file=sys.stderr)
145
+ sys.exit(1)
146
+ i += 2
147
+ else:
148
+ i += 1
149
+
150
+ rows, delimiter = read_table(filepath, head, tail)
151
+ print(f"File: {filepath} (delimiter: {repr(delimiter)})")
152
+ print()
153
+ print(format_table(rows))
154
+
155
+
156
+ if __name__ == "__main__":
157
+ main()
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env python3
2
+ """env-diff — Compare two .env files."""
3
+ import os
4
+ import sys
5
+
6
+ TOOL_META = {
7
+ "name": "env-diff",
8
+ "func": "main",
9
+ "desc": "Compare .env files. Usage: env-diff <file1.env> <file2.env>",
10
+ }
11
+
12
+ def parse_env(filepath):
13
+ vars = {}
14
+ with open(filepath) as f:
15
+ for line in f:
16
+ line = line.strip()
17
+ if not line or line.startswith("#"):
18
+ continue
19
+ if "=" in line:
20
+ key, val = line.split("=", 1)
21
+ vars[key.strip()] = val.strip().strip("\"'")
22
+ return vars
23
+
24
+ def main():
25
+ args = sys.argv[1:]
26
+ if len(args) < 2 or args[0] in ("-h", "--help"):
27
+ print("Usage: env-diff <file1.env> <file2.env>")
28
+ return
29
+ f1, f2 = args[0], args[1]
30
+ for f in [f1, f2]:
31
+ if not os.path.exists(f):
32
+ print(f"File not found: {f}", file=sys.stderr)
33
+ sys.exit(1)
34
+ env1 = parse_env(f1)
35
+ env2 = parse_env(f2)
36
+ keys1 = set(env1.keys())
37
+ keys2 = set(env2.keys())
38
+ only_in_1 = keys1 - keys2
39
+ only_in_2 = keys2 - keys1
40
+ common = keys1 & keys2
41
+ different = {k for k in common if env1[k] != env2[k]}
42
+ print(f"Comparison: {os.path.basename(f1)} vs {os.path.basename(f2)}")
43
+ print(f"Total vars: {len(keys1)} → {len(keys2)}")
44
+ print()
45
+ if only_in_1:
46
+ print(f"Only in {os.path.basename(f1)} ({len(only_in_1)}):")
47
+ for k in sorted(only_in_1):
48
+ print(f" + {k}={env1[k]}")
49
+ print()
50
+ if only_in_2:
51
+ print(f"Only in {os.path.basename(f2)} ({len(only_in_2)}):")
52
+ for k in sorted(only_in_2):
53
+ print(f" + {k}={env2[k]}")
54
+ print()
55
+ if different:
56
+ print(f"Different values ({len(different)}):")
57
+ for k in sorted(different):
58
+ print(f" * {k}")
59
+ print(f" - {env1[k]}")
60
+ print(f" + {env2[k]}")
61
+ print()
62
+ if not only_in_1 and not only_in_2 and not different:
63
+ print("✓ Files are identical")
64
+ else:
65
+ changed = len(only_in_1) + len(only_in_2) + len(different)
66
+ print(f"Summary: {changed} difference(s)")
67
+
68
+ if __name__ == "__main__":
69
+ main()
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env python3
2
+ """file-joiner — Join split file chunks back together."""
3
+ import os
4
+ import re
5
+ import sys
6
+
7
+ TOOL_META = {
8
+ "name": "file-joiner",
9
+ "func": "main",
10
+ "desc": "Join split file chunks. Usage: file-joiner <base_name> [--output file]",
11
+ }
12
+
13
+ def main():
14
+ args = sys.argv[1:]
15
+ if not args or args[0] in ("-h", "--help"):
16
+ print("Usage: file-joiner <base_name> [--output file]")
17
+ print(" Joins files matching base_name.part*")
18
+ return
19
+ base = args[0]
20
+ output = None
21
+ if "--output" in args:
22
+ idx = args.index("--output")
23
+ if idx + 1 < len(args):
24
+ output = args[idx + 1]
25
+ # Find parts
26
+ base_no_ext = os.path.splitext(base)[0]
27
+ ext = os.path.splitext(base)[1]
28
+ parts = []
29
+ pattern = re.compile(re.escape(base_no_ext) + r"\.part(\d+)" + re.escape(ext) + "$")
30
+ for f in os.listdir(os.path.dirname(base) or "."):
31
+ m = pattern.match(f)
32
+ if m:
33
+ parts.append((int(m.group(1)), f))
34
+ if not parts:
35
+ # Try *.part* pattern
36
+ pattern2 = re.compile(re.escape(base) + r"\.part(\d+)$")
37
+ for f in os.listdir("."):
38
+ m = pattern2.match(f)
39
+ if m:
40
+ parts.append((int(m.group(1)), f))
41
+ if not parts:
42
+ print(f"No parts found for: {base}", file=sys.stderr)
43
+ sys.exit(1)
44
+ parts.sort(key=lambda x: x[0])
45
+ if not output:
46
+ # Auto-detect output name
47
+ name_only = os.path.basename(base)
48
+ if ext:
49
+ output = base
50
+ else:
51
+ # Remove .part suffix
52
+ first_part = parts[0][1]
53
+ output = re.sub(r"\.part\d+", "", first_part)
54
+ if not os.path.splitext(output)[1]:
55
+ output = base # fallback
56
+ total_size = 0
57
+ is_binary = False
58
+ for _, part_path in parts:
59
+ try:
60
+ with open(part_path, "rb") as f:
61
+ header = f.read(1024)
62
+ if b"\x00" in header:
63
+ is_binary = True
64
+ break
65
+ except Exception:
66
+ pass
67
+ if is_binary:
68
+ with open(output, "wb") as out:
69
+ for _, part_path in parts:
70
+ with open(part_path, "rb") as pf:
71
+ data = pf.read()
72
+ out.write(data)
73
+ total_size += len(data)
74
+ print(f" + {part_path}")
75
+ else:
76
+ with open(output, "w") as out:
77
+ for _, part_path in parts:
78
+ with open(part_path, "r") as pf:
79
+ data = pf.read()
80
+ out.write(data)
81
+ total_size += len(data.encode())
82
+ print(f" + {part_path}")
83
+ print(f"\nJoined {len(parts)} parts → {output} ({total_size} bytes)")
84
+
85
+ if __name__ == "__main__":
86
+ main()
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env python3
2
+ """file-splitter — Split large files into smaller chunks."""
3
+ import os
4
+ import sys
5
+
6
+ TOOL_META = {
7
+ "name": "file-splitter",
8
+ "func": "main",
9
+ "desc": "Split files into chunks. Usage: file-splitter <file> --lines N | --size N[K|M|G]",
10
+ }
11
+
12
+ def format_size(size):
13
+ for unit in ["B", "KB", "MB", "GB"]:
14
+ if size < 1024:
15
+ return f"{size:.1f}{unit}"
16
+ size /= 1024
17
+ return f"{size:.1f}TB"
18
+
19
+ def main():
20
+ args = sys.argv[1:]
21
+ if not args or args[0] in ("-h", "--help"):
22
+ print("Usage: file-splitter <file> --lines N")
23
+ print(" file-splitter <file> --size N[K|M|G]")
24
+ print(" file-splitter <file> --chunks N")
25
+ return
26
+ filepath = args[0]
27
+ if not os.path.exists(filepath):
28
+ print(f"File not found: {filepath}", file=sys.stderr)
29
+ sys.exit(1)
30
+ split_lines = None
31
+ split_size = None
32
+ num_chunks = None
33
+ i = 1
34
+ while i < len(args):
35
+ if args[i] == "--lines" and i + 1 < len(args):
36
+ split_lines = int(args[i + 1])
37
+ i += 2
38
+ elif args[i] == "--size" and i + 1 < len(args):
39
+ val = args[i + 1].upper()
40
+ if val.endswith("K"):
41
+ split_size = int(val[:-1]) * 1024
42
+ elif val.endswith("M"):
43
+ split_size = int(val[:-1]) * 1024 * 1024
44
+ elif val.endswith("G"):
45
+ split_size = int(val[:-1]) * 1024 * 1024 * 1024
46
+ else:
47
+ split_size = int(val)
48
+ i += 2
49
+ elif args[i] == "--chunks" and i + 1 < len(args):
50
+ num_chunks = int(args[i + 1])
51
+ i += 2
52
+ else:
53
+ i += 1
54
+ total_size = os.path.getsize(filepath)
55
+ total_lines = 0
56
+ with open(filepath) as f:
57
+ for _ in f:
58
+ total_lines += 1
59
+ if num_chunks:
60
+ split_lines = max(1, total_lines // num_chunks)
61
+ if split_lines:
62
+ base, ext = os.path.splitext(filepath)
63
+ chunk_num = 1
64
+ with open(filepath) as f:
65
+ out_lines = []
66
+ out_size = 0
67
+ for line in f:
68
+ out_lines.append(line)
69
+ out_size += len(line)
70
+ if len(out_lines) >= split_lines:
71
+ chunk_file = f"{base}.part{chunk_num:03d}{ext}"
72
+ with open(chunk_file, "w") as cf:
73
+ cf.writelines(out_lines)
74
+ print(f" Created: {chunk_file} ({format_size(out_size)})")
75
+ out_lines = []
76
+ out_size = 0
77
+ chunk_num += 1
78
+ if out_lines:
79
+ chunk_file = f"{base}.part{chunk_num:03d}{ext}"
80
+ with open(chunk_file, "w") as cf:
81
+ cf.writelines(out_lines)
82
+ print(f" Created: {chunk_file} ({format_size(out_size)})")
83
+ print(f"Split {filepath} into {chunk_num} parts ({format_size(total_size)} total)")
84
+ elif split_size:
85
+ base, ext = os.path.splitext(filepath)
86
+ chunk_num = 1
87
+ with open(filepath) as f:
88
+ out_data = b""
89
+ if ext.lower() in (".txt", ".py", ".md", ".json", ".csv", ".yaml", ".yml", ".xml", ".html", ".css", ".js"):
90
+ # Text mode
91
+ f_text = open(filepath, "r")
92
+ out_lines = []
93
+ out_bytes = 0
94
+ for line in f_text:
95
+ out_lines.append(line)
96
+ out_bytes += len(line.encode())
97
+ if out_bytes >= split_size:
98
+ chunk_file = f"{base}.part{chunk_num:03d}{ext}"
99
+ with open(chunk_file, "w") as cf:
100
+ cf.writelines(out_lines)
101
+ print(f" Created: {chunk_file} ({format_size(out_bytes)})")
102
+ out_lines = []
103
+ out_bytes = 0
104
+ chunk_num += 1
105
+ if out_lines:
106
+ chunk_file = f"{base}.part{chunk_num:03d}{ext}"
107
+ with open(chunk_file, "w") as cf:
108
+ cf.writelines(out_lines)
109
+ print(f" Created: {chunk_file} ({format_size(out_bytes)})")
110
+ f_text.close()
111
+ else:
112
+ # Binary mode
113
+ with open(filepath, "rb") as f:
114
+ while True:
115
+ chunk = f.read(split_size)
116
+ if not chunk:
117
+ break
118
+ chunk_file = f"{base}.part{chunk_num:03d}{ext}"
119
+ with open(chunk_file, "wb") as cf:
120
+ cf.write(chunk)
121
+ print(f" Created: {chunk_file} ({format_size(len(chunk))})")
122
+ chunk_num += 1
123
+ print(f"Split {filepath} into {chunk_num - 1} parts ({format_size(total_size)} total)")
124
+ else:
125
+ print("Specify --lines N, --size N, or --chunks N", file=sys.stderr)
126
+ sys.exit(1)
127
+
128
+ if __name__ == "__main__":
129
+ main()
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env python3
2
+ """git-log-pretty — Pretty git log with graph and formatting."""
3
+ import subprocess
4
+ import sys
5
+
6
+ TOOL_META = {
7
+ "name": "git-log-pretty",
8
+ "func": "main",
9
+ "desc": "Pretty git log. Usage: git-log-pretty [--count N] [--author name]",
10
+ }
11
+
12
+ def main():
13
+ args = sys.argv[1:]
14
+ count = 20
15
+ author = None
16
+ i = 0
17
+ while i < len(args):
18
+ if args[i] == "--count" and i + 1 < len(args):
19
+ count = int(args[i + 1])
20
+ i += 2
21
+ elif args[i] == "--author" and i + 1 < len(args):
22
+ author = args[i + 1]
23
+ i += 2
24
+ else:
25
+ i += 1
26
+ # Use pretty git log format
27
+ fmt = "%C(auto)%h%d %C(cyan)%an%Creset %C(green)%ar%Creset%n%s"
28
+ git_cmd = ["git", "log", f"--pretty=format:{fmt}", f"-{count}", "--graph", "--date=relative"]
29
+ if author:
30
+ git_cmd.extend(["--author", author])
31
+ try:
32
+ result = subprocess.run(git_cmd, capture_output=True, text=True, timeout=15)
33
+ if result.returncode != 0:
34
+ print("Not a git repository", file=sys.stderr)
35
+ sys.exit(1)
36
+ output = result.stdout
37
+ if output.strip():
38
+ print(output)
39
+ # Show tag info
40
+ tag_cmd = ["git", "describe", "--tags", "--abbrev=0", "HEAD"]
41
+ tag_result = subprocess.run(tag_cmd, capture_output=True, text=True, timeout=5)
42
+ if tag_result.returncode == 0:
43
+ print(f"\nLatest tag: {tag_result.stdout.strip()}")
44
+ else:
45
+ print("No commits found")
46
+ except subprocess.TimeoutExpired:
47
+ print("Command timed out", file=sys.stderr)
48
+ sys.exit(1)
49
+
50
+ if __name__ == "__main__":
51
+ main()