evolver-tools 12.0.0__tar.gz → 14.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 (225) hide show
  1. {evolver_tools-12.0.0/src/evolver_tools.egg-info → evolver_tools-14.0.0}/PKG-INFO +2 -2
  2. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/pyproject.toml +2 -2
  3. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/cli.py +1 -1
  4. evolver_tools-14.0.0/src/evolver_tools/vendor/ansi_strip.py +34 -0
  5. evolver_tools-14.0.0/src/evolver_tools/vendor/calendar_cli.py +45 -0
  6. evolver_tools-14.0.0/src/evolver_tools/vendor/cert_info.py +95 -0
  7. evolver_tools-14.0.0/src/evolver_tools/vendor/cron_pretty.py +128 -0
  8. evolver_tools-14.0.0/src/evolver_tools/vendor/disk_cleanup.py +107 -0
  9. evolver_tools-14.0.0/src/evolver_tools/vendor/docker_helper.py +74 -0
  10. evolver_tools-14.0.0/src/evolver_tools/vendor/env_diff.py +69 -0
  11. evolver_tools-14.0.0/src/evolver_tools/vendor/file_joiner.py +86 -0
  12. evolver_tools-14.0.0/src/evolver_tools/vendor/file_splitter.py +129 -0
  13. evolver_tools-14.0.0/src/evolver_tools/vendor/geo_ip.py +71 -0
  14. evolver_tools-14.0.0/src/evolver_tools/vendor/git_log_pretty.py +51 -0
  15. evolver_tools-14.0.0/src/evolver_tools/vendor/git_stats.py +93 -0
  16. evolver_tools-14.0.0/src/evolver_tools/vendor/hash_file.py +63 -0
  17. evolver_tools-14.0.0/src/evolver_tools/vendor/hex_tool.py +59 -0
  18. evolver_tools-14.0.0/src/evolver_tools/vendor/ini2json.py +41 -0
  19. evolver_tools-14.0.0/src/evolver_tools/vendor/json2ini.py +51 -0
  20. evolver_tools-14.0.0/src/evolver_tools/vendor/key_value_store.py +123 -0
  21. evolver_tools-14.0.0/src/evolver_tools/vendor/macrogen.py +113 -0
  22. evolver_tools-14.0.0/src/evolver_tools/vendor/markdown_preview.py +100 -0
  23. evolver_tools-14.0.0/src/evolver_tools/vendor/network_scan.py +81 -0
  24. evolver_tools-14.0.0/src/evolver_tools/vendor/pipe_viewer.py +77 -0
  25. evolver_tools-14.0.0/src/evolver_tools/vendor/replace_text.py +73 -0
  26. evolver_tools-14.0.0/src/evolver_tools/vendor/screen_recorder.py +147 -0
  27. evolver_tools-14.0.0/src/evolver_tools/vendor/search_files.py +101 -0
  28. evolver_tools-14.0.0/src/evolver_tools/vendor/system_info.py +132 -0
  29. evolver_tools-14.0.0/src/evolver_tools/vendor/temp_cleaner.py +99 -0
  30. evolver_tools-14.0.0/src/evolver_tools/vendor/toml2json.py +58 -0
  31. evolver_tools-14.0.0/src/evolver_tools/vendor/uri_encode.py +39 -0
  32. evolver_tools-14.0.0/src/evolver_tools/vendor/web_download.py +77 -0
  33. evolver_tools-14.0.0/src/evolver_tools/vendor/yaml2toml.py +63 -0
  34. {evolver_tools-12.0.0 → evolver_tools-14.0.0/src/evolver_tools.egg-info}/PKG-INFO +2 -2
  35. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools.egg-info/SOURCES.txt +30 -0
  36. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/LICENSE +0 -0
  37. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/README.md +0 -0
  38. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/setup.cfg +0 -0
  39. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/__init__.py +0 -0
  40. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/__main__.py +0 -0
  41. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/autoreg.py +0 -0
  42. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/__init__.py +0 -0
  43. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/agent_b_tool.py +0 -0
  44. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/api_tester.py +0 -0
  45. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ascii_gen.py +0 -0
  46. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/audit_log.py +0 -0
  47. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/b64/__init__.py +0 -0
  48. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/b64/b64.py +0 -0
  49. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/backup.py +0 -0
  50. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/banner/__init__.py +0 -0
  51. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/banner/banner.py +0 -0
  52. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/banner.py +0 -0
  53. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/bookmark.py +0 -0
  54. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/cal_tool/__init__.py +0 -0
  55. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/cal_tool/cli.py +0 -0
  56. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/cert_check.py +0 -0
  57. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/changelog_gen/__init__.py +0 -0
  58. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/changelog_gen/changelog_gen.py +0 -0
  59. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/changelog_gen.py +0 -0
  60. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/chart_cli/__init__.py +0 -0
  61. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/chart_cli/__main__.py +0 -0
  62. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/checksum_dir.py +0 -0
  63. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/clipboard/__init__.py +0 -0
  64. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/clipboard/clipboard.py +0 -0
  65. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/code_auditor.py +0 -0
  66. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/code_stats.py +0 -0
  67. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/colorize.py +0 -0
  68. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/colors/__init__.py +0 -0
  69. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/colors/__main__.py +0 -0
  70. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/config_validator.py +0 -0
  71. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/config_vault.py +0 -0
  72. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/cron/__init__.py +0 -0
  73. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/cron/__main__.py +0 -0
  74. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/crontab_helper.py +0 -0
  75. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/crypto_box.py +0 -0
  76. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/crypto_price.py +0 -0
  77. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/csv2json.py +0 -0
  78. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/csv_stats/__init__.py +0 -0
  79. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/csv_stats/__main__.py +0 -0
  80. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/csv_stats/analyzer.py +0 -0
  81. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/csv_stats/cli.py +0 -0
  82. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/csv_validate.py +0 -0
  83. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/db_mate.py +0 -0
  84. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/db_schema.py +0 -0
  85. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/dep_graph.py +0 -0
  86. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/dev_dashboard.py +0 -0
  87. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/dice_roll.py +0 -0
  88. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/diff_csv.py +0 -0
  89. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/diff_tool/__init__.py +0 -0
  90. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/diff_tool/__main__.py +0 -0
  91. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/dirsize/__init__.py +0 -0
  92. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/disk_usage/__init__.py +0 -0
  93. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/disk_usage/disk_usage.py +0 -0
  94. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/dns_lookup.py +0 -0
  95. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/dt_convert.py +0 -0
  96. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/env_manager.py +0 -0
  97. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/envcheck/__init__.py +0 -0
  98. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/excel2csv.py +0 -0
  99. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ff/__init__.py +0 -0
  100. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ff/__main__.py +0 -0
  101. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/figlet_cli.py +0 -0
  102. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/figlet_tool.py +0 -0
  103. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/file_encrypt.py +0 -0
  104. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/file_watch.py +0 -0
  105. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/find_dups/__init__.py +0 -0
  106. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/find_dups/cli.py +0 -0
  107. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/firewall_rule.py +0 -0
  108. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/fmt/__init__.py +0 -0
  109. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/fmt/fmt.py +0 -0
  110. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/git_branch_cleaner.py +0 -0
  111. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/hashsum/__init__.py +0 -0
  112. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/hashsum/__main__.py +0 -0
  113. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/html2markdown.py +0 -0
  114. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/html2md.py +0 -0
  115. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/http_headers.py +0 -0
  116. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/http_live/__init__.py +0 -0
  117. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/http_live/__main__.py +0 -0
  118. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/image_meta.py +0 -0
  119. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ini_parser/__init__.py +0 -0
  120. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ini_parser/ini_parser.py +0 -0
  121. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ip_location.py +0 -0
  122. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ipcalc/__init__.py +0 -0
  123. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ipcalc/__main__.py +0 -0
  124. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ipinfo/__init__.py +0 -0
  125. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ipinfo/__main__.py +0 -0
  126. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/join.py +0 -0
  127. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/joke.py +0 -0
  128. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/jq_lite/__init__.py +0 -0
  129. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/jq_lite/__main__.py +0 -0
  130. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/json2csv/__init__.py +0 -0
  131. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/json2csv/__main__.py +0 -0
  132. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/json_pretty/__init__.py +0 -0
  133. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/json_pretty/json_pretty.py +0 -0
  134. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/json_schema_validate.py +0 -0
  135. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/jsonql/__init__.py +0 -0
  136. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/jsonql/__main__.py +0 -0
  137. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/license_cli/__init__.py +0 -0
  138. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/license_cli/__main__.py +0 -0
  139. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/license_cli/cli.py +0 -0
  140. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/log_analyzer.py +0 -0
  141. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/log_hawk.py +0 -0
  142. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/log_tail.py +0 -0
  143. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/markdown_check/__init__.py +0 -0
  144. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/markdown_toc.py +0 -0
  145. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/media_studio.py +0 -0
  146. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/morse.py +0 -0
  147. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/nb/__init__.py +0 -0
  148. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/nb/__main__.py +0 -0
  149. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/net_analyzer.py +0 -0
  150. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/net_speed.py +0 -0
  151. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/note_taker.py +0 -0
  152. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/otp_gen.py +0 -0
  153. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/passgen/__init__.py +0 -0
  154. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/password_strength.py +0 -0
  155. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/pdf_text.py +0 -0
  156. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/portcheck/__init__.py +0 -0
  157. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/portcheck/__main__.py +0 -0
  158. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/pr_tool/__init__.py +0 -0
  159. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/pr_tool/pr_tool.py +0 -0
  160. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/process_kill.py +0 -0
  161. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/progress_bar.py +0 -0
  162. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/project_doctor/__init__.py +0 -0
  163. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/project_doctor/__main__.py +0 -0
  164. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/qrcode.py +0 -0
  165. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/quote_tool/__init__.py +0 -0
  166. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/quote_tool/quote.py +0 -0
  167. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/rainbow.py +0 -0
  168. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/reminder.py +0 -0
  169. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ren/__init__.py +0 -0
  170. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ren/__main__.py +0 -0
  171. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/restore.py +0 -0
  172. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/route_trace.py +0 -0
  173. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/scan_ports.py +0 -0
  174. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/screenshot_cli.py +0 -0
  175. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/search_history.py +0 -0
  176. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/secret_scanner.py +0 -0
  177. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/service_check.py +0 -0
  178. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/shuffle.py +0 -0
  179. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/siege_lite/__init__.py +0 -0
  180. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/siege_lite/__main__.py +0 -0
  181. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/smellfinder/__init__.py +0 -0
  182. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/smellfinder/__main__.py +0 -0
  183. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/sort/__init__.py +0 -0
  184. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/sort/sort.py +0 -0
  185. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/spinner.py +0 -0
  186. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/split.py +0 -0
  187. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/split_tool/__init__.py +0 -0
  188. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/split_tool/split.py +0 -0
  189. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/sql2csv.py +0 -0
  190. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/sqlite_cli/__init__.py +0 -0
  191. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/sqlite_cli/__main__.py +0 -0
  192. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ssh_key_gen.py +0 -0
  193. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/ssl_check.py +0 -0
  194. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/stopwatch.py +0 -0
  195. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/sysmon/__init__.py +0 -0
  196. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/sysmon/__main__.py +0 -0
  197. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/sysmon_pro.py +0 -0
  198. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/text_stats.py +0 -0
  199. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/timer/__init__.py +0 -0
  200. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/timer_pro/__init__.py +0 -0
  201. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/timer_pro/timer_pro.py +0 -0
  202. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/timer_pro.py +0 -0
  203. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/todo_cli.py +0 -0
  204. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/treedir/__init__.py +0 -0
  205. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/treedir/__main__.py +0 -0
  206. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/uniq_tool/__init__.py +0 -0
  207. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/uniq_tool/uniq.py +0 -0
  208. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/unit_convert.py +0 -0
  209. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/urlparse_tool/__init__.py +0 -0
  210. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/urlparse_tool/cli.py +0 -0
  211. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/uuid_tool/__init__.py +0 -0
  212. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/uuid_tool/__main__.py +0 -0
  213. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/weather_cli.py +0 -0
  214. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/web_summary/__init__.py +0 -0
  215. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/web_summary/__main__.py +0 -0
  216. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/whois_lookup.py +0 -0
  217. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/wordcount/__init__.py +0 -0
  218. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/wordcount/__main__.py +0 -0
  219. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/xml2json.py +0 -0
  220. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/yaml2json/__init__.py +0 -0
  221. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/yaml2json/yaml2json.py +0 -0
  222. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools/vendor/yaml_validate.py +0 -0
  223. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools.egg-info/dependency_links.txt +0 -0
  224. {evolver_tools-12.0.0 → evolver_tools-14.0.0}/src/evolver_tools.egg-info/entry_points.txt +0 -0
  225. {evolver_tools-12.0.0 → evolver_tools-14.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: 12.0.0
4
- Summary: 129 CLI tools + 9 flagship projects — one pip install
3
+ Version: 14.0.0
4
+ Summary: 159 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
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "evolver-tools"
7
- version = "12.0.0"
8
- description = "129 CLI tools + 9 flagship projects — one pip install"
7
+ version = "14.0.0"
8
+ description = "159 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 v12.0.0 =====\x1b[0m')
17
+ print(f'\x1b[1;36m===== EVOLVER Tools v14.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,45 @@
1
+ #!/usr/bin/env python3
2
+ """calendar-cli — Display a terminal calendar."""
3
+ import calendar
4
+ import sys
5
+ from datetime import datetime
6
+
7
+ TOOL_META = {
8
+ "name": "calendar-cli",
9
+ "func": "main",
10
+ "desc": "Display terminal calendar. Usage: calendar-cli [year] [month]",
11
+ }
12
+
13
+ def main():
14
+ args = sys.argv[1:]
15
+ now = datetime.now()
16
+ year = now.year
17
+ month = now.month
18
+ if len(args) >= 2:
19
+ try:
20
+ year = int(args[0])
21
+ month = int(args[1])
22
+ except ValueError:
23
+ print("Usage: calendar-cli [year] [month]", file=sys.stderr)
24
+ sys.exit(1)
25
+ elif len(args) >= 1:
26
+ try:
27
+ year = int(args[0])
28
+ month = None
29
+ except ValueError:
30
+ print("Usage: calendar-cli [year] [month]", file=sys.stderr)
31
+ sys.exit(1)
32
+ cal = calendar.TextCalendar()
33
+ if month:
34
+ cal_str = cal.formatmonth(year, month)
35
+ # Highlight today
36
+ if year == now.year and month == now.month:
37
+ today = str(now.day)
38
+ cal_str = cal_str.replace(f" {today} ", f"[{today}]")
39
+ cal_str = cal_str.replace(f"{today} ", f"[{today}]")
40
+ print(cal_str)
41
+ else:
42
+ print(cal.formatyear(year))
43
+
44
+ if __name__ == "__main__":
45
+ main()
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env python3
2
+ """cert-info — Display SSL certificate details for a domain."""
3
+ import ssl
4
+ import socket
5
+ import sys
6
+ from datetime import datetime
7
+
8
+ TOOL_META = {
9
+ "name": "cert-info",
10
+ "func": "main",
11
+ "desc": "Show SSL certificate info for a domain. Usage: cert-info <domain> [port]",
12
+ }
13
+
14
+ def main():
15
+ args = sys.argv[1:]
16
+ if not args or args[0] in ("-h", "--help"):
17
+ print("Usage: cert-info <domain> [port]", file=sys.stderr)
18
+ print(" Default port: 443", file=sys.stderr)
19
+ sys.exit(1)
20
+ host = args[0]
21
+ port = int(args[1]) if len(args) > 1 else 443
22
+ try:
23
+ ctx = ssl.create_default_context()
24
+ with socket.create_connection((host, port), timeout=10) as sock:
25
+ with ctx.wrap_socket(sock, server_hostname=host) as ssock:
26
+ cert = ssock.getpeercert()
27
+ if not cert:
28
+ print(f"No certificate returned by {host}:{port}", file=sys.stderr)
29
+ sys.exit(1)
30
+ print(f"SSL Certificate for {host}:{port}")
31
+ print("=" * 50)
32
+ # Subject
33
+ subject = dict(x[0] for x in cert.get("subject", []))
34
+ print(f"Subject:")
35
+ for key, val in subject.items():
36
+ print(f" {key}: {val}")
37
+ # Issuer
38
+ issuer = dict(x[0] for x in cert.get("issuer", []))
39
+ print(f"Issuer:")
40
+ for key, val in issuer.items():
41
+ print(f" {key}: {val}")
42
+ # Validity
43
+ print(f"Valid from: {cert.get('notBefore', 'N/A')}")
44
+ print(f"Valid until: {cert.get('notAfter', 'N/A')}")
45
+ # Check expiry
46
+ try:
47
+ not_after = cert.get("notAfter", "")
48
+ expiry = datetime.strptime(not_after, "%b %d %H:%M:%S %Y %Z")
49
+ now = datetime.utcnow()
50
+ remaining = (expiry - now).days
51
+ if remaining < 0:
52
+ print(f"⚠ EXPIRED {abs(remaining)} days ago!")
53
+ elif remaining < 30:
54
+ print(f"⚠ Expires in {remaining} days (soon!)")
55
+ else:
56
+ print(f"✓ Expires in {remaining} days")
57
+ except Exception:
58
+ pass
59
+ # SAN
60
+ san = cert.get("subjectAltName", [])
61
+ if san:
62
+ print(f"Subject Alt Names ({len(san)}):")
63
+ for _, name in san[:10]:
64
+ print(f" {name}")
65
+ if len(san) > 10:
66
+ print(f" ... and {len(san) - 10} more")
67
+ # Serial
68
+ serial = cert.get("serialNumber", "")
69
+ if serial:
70
+ print(f"Serial: {serial}")
71
+ # Version
72
+ print(f"Version: {cert.get('version', 'N/A')}")
73
+ # Fingerprints
74
+ try:
75
+ der = ssock.getpeercert(binary_form=True)
76
+ import hashlib
77
+ print(f"SHA256: {hashlib.sha256(der).hexdigest()}")
78
+ print(f"SHA1: {hashlib.sha1(der).hexdigest()}")
79
+ except Exception:
80
+ pass
81
+ except ssl.SSLError as e:
82
+ print(f"SSL Error: {e}", file=sys.stderr)
83
+ sys.exit(1)
84
+ except socket.gaierror:
85
+ print(f"Could not resolve: {host}", file=sys.stderr)
86
+ sys.exit(1)
87
+ except socket.timeout:
88
+ print(f"Connection timed out: {host}:{port}", file=sys.stderr)
89
+ sys.exit(1)
90
+ except Exception as e:
91
+ print(f"Error: {e}", file=sys.stderr)
92
+ sys.exit(1)
93
+
94
+ if __name__ == "__main__":
95
+ main()
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env python3
2
+ """cron-pretty — Pretty-print cron expressions in human-readable format."""
3
+ import re
4
+ import sys
5
+
6
+ TOOL_META = {
7
+ "name": "cron-pretty",
8
+ "func": "main",
9
+ "desc": "Describe cron schedule in plain English. Usage: cron-pretty '*/5 * * * *'",
10
+ }
11
+
12
+ WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
13
+ MONTHS = [None, "January", "February", "March", "April", "May", "June",
14
+ "July", "August", "September", "October", "November", "December"]
15
+
16
+ def describe(minute, hour, dom, month, dow):
17
+ parts = []
18
+ # Minute
19
+ if minute == "*":
20
+ min_desc = "every minute"
21
+ elif re.match(r"^\d+$", minute):
22
+ min_desc = f"at minute {minute}"
23
+ elif minute.startswith("*/"):
24
+ step = minute[2:]
25
+ min_desc = f"every {step} minutes"
26
+ else:
27
+ min_desc = f"minute {minute}"
28
+ parts.append(min_desc)
29
+ # Hour
30
+ if hour == "*":
31
+ hour_desc = "of every hour"
32
+ elif re.match(r"^\d+$", hour):
33
+ hour_desc = f"past hour {hour}"
34
+ elif hour.startswith("*/"):
35
+ step = hour[2:]
36
+ hour_desc = f"every {step} hours"
37
+ else:
38
+ hour_desc = f"hour {hour}"
39
+ parts.append(hour_desc)
40
+ # Day of month
41
+ if dom == "*":
42
+ dom_desc = "every day"
43
+ elif dom.startswith("*/"):
44
+ step = dom[2:]
45
+ dom_desc = f"every {step} days"
46
+ elif "," in dom:
47
+ days = dom.split(",")
48
+ dom_desc = f"on days {', '.join(days)}"
49
+ else:
50
+ dom_desc = f"on day {dom}"
51
+ parts.append(dom_desc)
52
+ # Month
53
+ if month == "*":
54
+ month_desc = "of every month"
55
+ elif re.match(r"^\d+$", month):
56
+ m = int(month)
57
+ month_desc = f"in {MONTHS[m] if m <= 12 else month}"
58
+ elif month.startswith("*/"):
59
+ step = month[2:]
60
+ month_desc = f"every {step} months"
61
+ else:
62
+ month_desc = f"in month {month}"
63
+ parts.append(month_desc)
64
+ # Day of week
65
+ if dow == "*":
66
+ dow_desc = ""
67
+ elif re.match(r"^\d+$", dow):
68
+ d = int(dow)
69
+ dow_desc = f"on {WEEKDAYS[d]}"
70
+ elif "," in dow:
71
+ days = [WEEKDAYS[int(d)] if d.isdigit() else d for d in dow.split(",")]
72
+ dow_desc = f"on {', '.join(days)}"
73
+ else:
74
+ dow_desc = f"on {dow}"
75
+ if dow_desc:
76
+ parts.append(dow_desc)
77
+ # Special cases
78
+ if minute == "0" and hour == "0" and dom == "*" and month == "*" and dow == "*":
79
+ return "At midnight, every day"
80
+ if minute == "0" and hour == "12" and dom == "*" and month == "*" and dow == "*":
81
+ return "At noon, every day"
82
+ if minute == "0" and hour in ("0", "12") and dom == "1" and month == "*" and dow == "*":
83
+ return f"At {hour}:00 AM, on the 1st of every month"
84
+ if minute == "0" and hour == "9" and dom == "*" and month == "*" and dow in ("1", "1-5"):
85
+ return "At 9:00 AM, Monday through Friday"
86
+ if minute == "30" and hour == "9" and dom == "*" and month == "*" and dow in ("1", "1-5"):
87
+ return "At 9:30 AM, Monday through Friday"
88
+ # Build description
89
+ result = f"{parts[0]} {parts[1]} {parts[2]} {parts[3]}"
90
+ if len(parts) > 4:
91
+ result += f" {parts[4]}"
92
+ return result
93
+
94
+ def main():
95
+ args = sys.argv[1:]
96
+ if not args or args[0] in ("-h", "--help"):
97
+ print("Usage: cron-pretty '*/5 * * * *'", file=sys.stderr)
98
+ print(" cron-pretty '30 9 * * 1-5'", file=sys.stderr)
99
+ sys.exit(1)
100
+ expr = args[0].strip()
101
+ fields = expr.split()
102
+ # Handle special strings
103
+ special = {
104
+ "@yearly": "0 0 1 1 *",
105
+ "@annually": "0 0 1 1 *",
106
+ "@monthly": "0 0 1 * *",
107
+ "@weekly": "0 0 * * 0",
108
+ "@daily": "0 0 * * *",
109
+ "@hourly": "0 * * * *",
110
+ "@reboot": None,
111
+ }
112
+ if expr in special:
113
+ resolved = special[expr]
114
+ if resolved is None:
115
+ print(f"'{expr}' — runs at system startup/reboot")
116
+ return
117
+ fields = resolved.split()
118
+ if len(fields) != 5:
119
+ print(f"Invalid cron expression: '{expr}'", file=sys.stderr)
120
+ print("Expected format: minute hour day-of-month month day-of-week", file=sys.stderr)
121
+ sys.exit(1)
122
+ minute, hour, dom, month, dow = fields
123
+ description = describe(minute, hour, dom, month, dow)
124
+ print(f" {expr}")
125
+ print(f" → {description}")
126
+
127
+ if __name__ == "__main__":
128
+ main()
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env python3
2
+ """disk-cleanup — Analyze disk usage and suggest cleanup actions."""
3
+ import os
4
+ import sys
5
+
6
+ TOOL_META = {
7
+ "name": "disk-cleanup",
8
+ "func": "main",
9
+ "desc": "Analyze disk usage and suggest cleanup. Usage: disk-cleanup [path] [--deep]",
10
+ }
11
+
12
+ COMMON_CLEANUP = [
13
+ ("~/.cache", "Cache files"),
14
+ ("~/.local/share/Trash", "Trash"),
15
+ ("/tmp", "Temp files"),
16
+ ("~/.npm/_cacache", "npm cache"),
17
+ ("~/.rustup/tmp", "rustup temp"),
18
+ ("~/.cargo/registry/cache", "Cargo cache"),
19
+ ("~/.gradle/caches", "Gradle cache"),
20
+ ("~/.m2/repository", "Maven cache"),
21
+ ("~/.local/share/pip/cache", "pip cache"),
22
+ ]
23
+
24
+ def get_size(path):
25
+ try:
26
+ if os.path.isfile(path):
27
+ return os.path.getsize(path)
28
+ total = 0
29
+ for root, dirs, files in os.walk(path):
30
+ for f in files:
31
+ try:
32
+ total += os.path.getsize(os.path.join(root, f))
33
+ except Exception:
34
+ pass
35
+ return total
36
+ except Exception:
37
+ return 0
38
+
39
+ def format_size(size):
40
+ for unit in ["B", "KB", "MB", "GB"]:
41
+ if size < 1024:
42
+ return f"{size:.1f} {unit}"
43
+ size /= 1024
44
+ return f"{size:.1f} TB"
45
+
46
+ def find_large_files(path, limit=20, min_mb=50):
47
+ large = []
48
+ for root, dirs, files in os.walk(path):
49
+ dirs[:] = [d for d in dirs if not d.startswith(".") or d == "."]
50
+ for f in files:
51
+ try:
52
+ fp = os.path.join(root, f)
53
+ size = os.path.getsize(fp)
54
+ if size >= min_mb * 1024 * 1024:
55
+ large.append((fp, size))
56
+ except Exception:
57
+ pass
58
+ large.sort(key=lambda x: -x[1])
59
+ return large[:limit]
60
+
61
+ def main():
62
+ args = sys.argv[1:]
63
+ root_path = args[0] if args and not args[0].startswith("-") else os.path.expanduser("~")
64
+ deep = "--deep" in args
65
+ root_path = os.path.abspath(root_path)
66
+ print(f"Disk Cleanup Analysis: {root_path}")
67
+ print("=" * 50)
68
+ # Check common cleanup locations
69
+ print("\nCommon cleanup locations:")
70
+ any_found = False
71
+ for rel_path, label in COMMON_CLEANUP:
72
+ path = os.path.expanduser(rel_path)
73
+ if os.path.exists(path):
74
+ size = get_size(path)
75
+ if size > 0:
76
+ any_found = True
77
+ print(f" {format_size(size):>8} {label} ({path})")
78
+ if not any_found:
79
+ print(" (none found)")
80
+ # Check directory sizes if root path is a directory
81
+ if os.path.isdir(root_path):
82
+ print(f"\nLargest directories in {root_path}:")
83
+ dirs = []
84
+ for entry in os.listdir(root_path):
85
+ full = os.path.join(root_path, entry)
86
+ if os.path.isdir(full):
87
+ size = get_size(full)
88
+ dirs.append((entry, size))
89
+ dirs.sort(key=lambda x: -x[1])
90
+ for name, size in dirs[:10]:
91
+ if size > 1024 * 1024: # > 1MB
92
+ print(f" {format_size(size):>8} {name}")
93
+ if deep:
94
+ print(f"\nLargest files (>50MB):")
95
+ large = find_large_files(root_path)
96
+ if large:
97
+ for fp, size in large:
98
+ rel = os.path.relpath(fp, os.path.expanduser("~"))
99
+ print(f" {format_size(size):>8} ~/{rel}")
100
+ else:
101
+ print(" (none found)")
102
+ print("\nSuggestions:")
103
+ print(" temp-cleaner --dry-run Preview temp file cleanup")
104
+ print(" disk-usage Show disk usage summary")
105
+
106
+ if __name__ == "__main__":
107
+ main()
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env python3
2
+ """docker-helper — Common Docker commands helper."""
3
+ import subprocess
4
+ import sys
5
+
6
+ TOOL_META = {
7
+ "name": "docker-helper",
8
+ "func": "main",
9
+ "desc": "Docker command helper. Usage: docker-helper <command> [args]",
10
+ }
11
+
12
+ COMMANDS = {
13
+ "ps": "docker ps",
14
+ "images": "docker images",
15
+ "stats": "docker stats --no-stream",
16
+ "logs": "docker logs",
17
+ "stop-all": "docker stop $(docker ps -q)",
18
+ "rm-all": "docker rm $(docker ps -aq)",
19
+ "rmi-none": "docker rmi $(docker images -f dangling=true -q)",
20
+ "prune": "docker system prune -f",
21
+ "prune-all": "docker system prune -af --volumes",
22
+ "compose-ps": "docker compose ps",
23
+ "top": "docker top",
24
+ "inspect": "docker inspect",
25
+ "network-ls": "docker network ls",
26
+ "volume-ls": "docker volume ls",
27
+ "clean": "docker system prune -f",
28
+ "exec": "docker exec -it",
29
+ "build": "docker build",
30
+ "pull": "docker pull",
31
+ "push": "docker push",
32
+ "info": "docker info",
33
+ }
34
+
35
+ def main():
36
+ args = sys.argv[1:]
37
+ if not args or args[0] in ("-h", "--help"):
38
+ print("Usage: docker-helper <command> [extra args...]")
39
+ print("\nAvailable commands:")
40
+ for cmd, desc in sorted(COMMANDS.items()):
41
+ print(f" {cmd:<15} {desc}")
42
+ print()
43
+ print("Examples:")
44
+ print(" docker-helper ps")
45
+ print(" docker-helper logs mycontainer")
46
+ print(" docker-helper stop-all")
47
+ return
48
+ cmd = args[0]
49
+ if cmd not in COMMANDS:
50
+ print(f"Unknown command: {cmd}", file=sys.stderr)
51
+ print("Available: " + ", ".join(sorted(COMMANDS.keys())), file=sys.stderr)
52
+ sys.exit(1)
53
+ docker_cmd = COMMANDS[cmd]
54
+ extra = args[1:]
55
+ full_cmd = docker_cmd + " " + " ".join(extra) if extra else docker_cmd
56
+ # Handle docker exec -it specially (needs pty, just show the command)
57
+ if cmd == "exec":
58
+ print(f"Run: {full_cmd}")
59
+ print("Note: Use 'docker exec -it' directly for interactive sessions")
60
+ return
61
+ print(f"$ {full_cmd}")
62
+ try:
63
+ result = subprocess.run(full_cmd, shell=True, capture_output=False, timeout=60)
64
+ if result.returncode != 0:
65
+ sys.exit(result.returncode)
66
+ except subprocess.TimeoutExpired:
67
+ print("Command timed out", file=sys.stderr)
68
+ sys.exit(1)
69
+ except FileNotFoundError:
70
+ print("Docker not found. Is Docker installed?", file=sys.stderr)
71
+ sys.exit(1)
72
+
73
+ if __name__ == "__main__":
74
+ 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()