evolver-tools 21.0.0__tar.gz → 23.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 (268) hide show
  1. {evolver_tools-21.0.0/src/evolver_tools.egg-info → evolver_tools-23.0.0}/PKG-INFO +2 -2
  2. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/pyproject.toml +2 -2
  3. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/cli.py +1 -1
  4. evolver_tools-23.0.0/src/evolver_tools/vendor/base58.py +93 -0
  5. evolver_tools-23.0.0/src/evolver_tools/vendor/crc_check.py +77 -0
  6. evolver_tools-23.0.0/src/evolver_tools/vendor/date_diff.py +99 -0
  7. evolver_tools-23.0.0/src/evolver_tools/vendor/env_template.py +81 -0
  8. evolver_tools-23.0.0/src/evolver_tools/vendor/file_find.py +91 -0
  9. evolver_tools-23.0.0/src/evolver_tools/vendor/ip_info.py +70 -0
  10. evolver_tools-23.0.0/src/evolver_tools/vendor/json_merge.py +104 -0
  11. evolver_tools-23.0.0/src/evolver_tools/vendor/math_eval.py +86 -0
  12. evolver_tools-23.0.0/src/evolver_tools/vendor/tsv2csv.py +73 -0
  13. evolver_tools-23.0.0/src/evolver_tools/vendor/uuid_gen.py +77 -0
  14. {evolver_tools-21.0.0 → evolver_tools-23.0.0/src/evolver_tools.egg-info}/PKG-INFO +2 -2
  15. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools.egg-info/SOURCES.txt +10 -0
  16. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/LICENSE +0 -0
  17. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/README.md +0 -0
  18. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/setup.cfg +0 -0
  19. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/__init__.py +0 -0
  20. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/__main__.py +0 -0
  21. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/autoreg.py +0 -0
  22. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/__init__.py +0 -0
  23. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/agent_b_tool.py +0 -0
  24. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ansi_strip.py +0 -0
  25. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/api_tester.py +0 -0
  26. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ascii_gen.py +0 -0
  27. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/audit_log.py +0 -0
  28. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/b64/__init__.py +0 -0
  29. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/b64/b64.py +0 -0
  30. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/backup.py +0 -0
  31. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/banner/__init__.py +0 -0
  32. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/banner/banner.py +0 -0
  33. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/banner.py +0 -0
  34. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/base32.py +0 -0
  35. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/bookmark.py +0 -0
  36. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/cal_tool/__init__.py +0 -0
  37. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/cal_tool/cli.py +0 -0
  38. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/calendar_cli.py +0 -0
  39. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/cert_check.py +0 -0
  40. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/cert_info.py +0 -0
  41. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/changelog_gen/__init__.py +0 -0
  42. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/changelog_gen/changelog_gen.py +0 -0
  43. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/changelog_gen.py +0 -0
  44. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/chart_cli/__init__.py +0 -0
  45. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/chart_cli/__main__.py +0 -0
  46. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/checksum_dir.py +0 -0
  47. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/clipboard/__init__.py +0 -0
  48. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/clipboard/clipboard.py +0 -0
  49. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/code_auditor.py +0 -0
  50. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/code_stats.py +0 -0
  51. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/colorize.py +0 -0
  52. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/colors/__init__.py +0 -0
  53. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/colors/__main__.py +0 -0
  54. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/config_validator.py +0 -0
  55. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/config_vault.py +0 -0
  56. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/cowsay.py +0 -0
  57. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/cron/__init__.py +0 -0
  58. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/cron/__main__.py +0 -0
  59. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/cron_pretty.py +0 -0
  60. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/crontab_helper.py +0 -0
  61. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/crypto_box.py +0 -0
  62. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/crypto_price.py +0 -0
  63. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/csv2json.py +0 -0
  64. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/csv_merge.py +0 -0
  65. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/csv_stats/__init__.py +0 -0
  66. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/csv_stats/__main__.py +0 -0
  67. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/csv_stats/analyzer.py +0 -0
  68. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/csv_stats/cli.py +0 -0
  69. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/csv_validate.py +0 -0
  70. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/csv_view.py +0 -0
  71. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/db_mate.py +0 -0
  72. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/db_schema.py +0 -0
  73. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/dep_graph.py +0 -0
  74. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/dev_dashboard.py +0 -0
  75. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/dice_roll.py +0 -0
  76. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/diff_csv.py +0 -0
  77. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/diff_files.py +0 -0
  78. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/diff_tool/__init__.py +0 -0
  79. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/diff_tool/__main__.py +0 -0
  80. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/dirsize/__init__.py +0 -0
  81. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/disk_cleanup.py +0 -0
  82. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/disk_usage/__init__.py +0 -0
  83. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/disk_usage/disk_usage.py +0 -0
  84. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/dns_lookup.py +0 -0
  85. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/docker_helper.py +0 -0
  86. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/dt_convert.py +0 -0
  87. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/env_diff.py +0 -0
  88. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/env_manager.py +0 -0
  89. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/envcheck/__init__.py +0 -0
  90. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/epoch.py +0 -0
  91. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/excel2csv.py +0 -0
  92. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/factor.py +0 -0
  93. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ff/__init__.py +0 -0
  94. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ff/__main__.py +0 -0
  95. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/figlet_cli.py +0 -0
  96. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/figlet_tool.py +0 -0
  97. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/file_encrypt.py +0 -0
  98. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/file_joiner.py +0 -0
  99. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/file_splitter.py +0 -0
  100. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/file_watch.py +0 -0
  101. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/find_dups/__init__.py +0 -0
  102. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/find_dups/cli.py +0 -0
  103. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/firewall_rule.py +0 -0
  104. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/fmt/__init__.py +0 -0
  105. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/fmt/fmt.py +0 -0
  106. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/fold.py +0 -0
  107. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/geo_ip.py +0 -0
  108. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/git_branch_cleaner.py +0 -0
  109. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/git_log_pretty.py +0 -0
  110. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/git_stats.py +0 -0
  111. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/hash_check.py +0 -0
  112. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/hash_file.py +0 -0
  113. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/hashsum/__init__.py +0 -0
  114. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/hashsum/__main__.py +0 -0
  115. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/hex_tool.py +0 -0
  116. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/hexdump.py +0 -0
  117. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/html2markdown.py +0 -0
  118. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/html2md.py +0 -0
  119. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/http_headers.py +0 -0
  120. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/http_live/__init__.py +0 -0
  121. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/http_live/__main__.py +0 -0
  122. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/http_server.py +0 -0
  123. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/image_meta.py +0 -0
  124. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ini2json.py +0 -0
  125. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ini_parser/__init__.py +0 -0
  126. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ini_parser/ini_parser.py +0 -0
  127. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ip_location.py +0 -0
  128. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ipcalc/__init__.py +0 -0
  129. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ipcalc/__main__.py +0 -0
  130. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ipinfo/__init__.py +0 -0
  131. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ipinfo/__main__.py +0 -0
  132. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/join.py +0 -0
  133. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/joke.py +0 -0
  134. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/jq_lite/__init__.py +0 -0
  135. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/jq_lite/__main__.py +0 -0
  136. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/json2csv/__init__.py +0 -0
  137. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/json2csv/__main__.py +0 -0
  138. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/json2ini.py +0 -0
  139. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/json_flatten.py +0 -0
  140. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/json_pretty/__init__.py +0 -0
  141. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/json_pretty/json_pretty.py +0 -0
  142. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/json_schema_validate.py +0 -0
  143. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/jsonql/__init__.py +0 -0
  144. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/jsonql/__main__.py +0 -0
  145. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/key_value_store.py +0 -0
  146. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/license.py +0 -0
  147. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/license_cli/__init__.py +0 -0
  148. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/license_cli/__main__.py +0 -0
  149. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/license_cli/cli.py +0 -0
  150. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/log_analyzer.py +0 -0
  151. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/log_hawk.py +0 -0
  152. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/log_tail.py +0 -0
  153. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/macrogen.py +0 -0
  154. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/markdown_check/__init__.py +0 -0
  155. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/markdown_preview.py +0 -0
  156. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/markdown_toc.py +0 -0
  157. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/media_studio.py +0 -0
  158. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/morse.py +0 -0
  159. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/nb/__init__.py +0 -0
  160. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/nb/__main__.py +0 -0
  161. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/net_analyzer.py +0 -0
  162. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/net_speed.py +0 -0
  163. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/network_scan.py +0 -0
  164. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/nl.py +0 -0
  165. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/note_taker.py +0 -0
  166. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/otp_gen.py +0 -0
  167. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/passgen/__init__.py +0 -0
  168. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/password_strength.py +0 -0
  169. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/pdf_info.py +0 -0
  170. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/pdf_text.py +0 -0
  171. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/pipe_viewer.py +0 -0
  172. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/pomodoro.py +0 -0
  173. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/port_scan.py +0 -0
  174. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/portcheck/__init__.py +0 -0
  175. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/portcheck/__main__.py +0 -0
  176. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/pr_tool/__init__.py +0 -0
  177. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/pr_tool/pr_tool.py +0 -0
  178. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/process_kill.py +0 -0
  179. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/progress_bar.py +0 -0
  180. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/project_doctor/__init__.py +0 -0
  181. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/project_doctor/__main__.py +0 -0
  182. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/qc_calc.py +0 -0
  183. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/qc_report.py +0 -0
  184. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/qc_sample.py +0 -0
  185. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/qr_cli.py +0 -0
  186. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/qrcode.py +0 -0
  187. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/quote.py +0 -0
  188. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/quote_tool/__init__.py +0 -0
  189. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/quote_tool/quote.py +0 -0
  190. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/rainbow.py +0 -0
  191. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/random.py +0 -0
  192. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/reminder.py +0 -0
  193. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ren/__init__.py +0 -0
  194. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ren/__main__.py +0 -0
  195. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/replace_text.py +0 -0
  196. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/restore.py +0 -0
  197. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/rot13.py +0 -0
  198. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/route_trace.py +0 -0
  199. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/scan_ports.py +0 -0
  200. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/screen_recorder.py +0 -0
  201. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/screenshot_cli.py +0 -0
  202. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/search_files.py +0 -0
  203. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/search_history.py +0 -0
  204. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/secret_scanner.py +0 -0
  205. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/seq.py +0 -0
  206. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/service_check.py +0 -0
  207. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/shuffle.py +0 -0
  208. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/siege_lite/__init__.py +0 -0
  209. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/siege_lite/__main__.py +0 -0
  210. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/smellfinder/__init__.py +0 -0
  211. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/smellfinder/__main__.py +0 -0
  212. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/sort/__init__.py +0 -0
  213. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/sort/sort.py +0 -0
  214. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/spinner.py +0 -0
  215. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/split.py +0 -0
  216. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/split_tool/__init__.py +0 -0
  217. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/split_tool/split.py +0 -0
  218. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/sql2csv.py +0 -0
  219. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/sqlite_cli/__init__.py +0 -0
  220. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/sqlite_cli/__main__.py +0 -0
  221. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ssh_key_gen.py +0 -0
  222. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/ssl_check.py +0 -0
  223. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/stopwatch.py +0 -0
  224. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/subnet.py +0 -0
  225. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/sysmon/__init__.py +0 -0
  226. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/sysmon/__main__.py +0 -0
  227. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/sysmon_pro.py +0 -0
  228. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/system_info.py +0 -0
  229. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/temp_cleaner.py +0 -0
  230. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/template.py +0 -0
  231. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/text_stats.py +0 -0
  232. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/timeout.py +0 -0
  233. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/timer/__init__.py +0 -0
  234. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/timer_pro/__init__.py +0 -0
  235. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/timer_pro/timer_pro.py +0 -0
  236. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/timer_pro.py +0 -0
  237. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/todo_cli.py +0 -0
  238. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/toml2json.py +0 -0
  239. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/tr.py +0 -0
  240. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/tree.py +0 -0
  241. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/treedir/__init__.py +0 -0
  242. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/treedir/__main__.py +0 -0
  243. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/uniq_tool/__init__.py +0 -0
  244. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/uniq_tool/uniq.py +0 -0
  245. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/unit_convert.py +0 -0
  246. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/uri_encode.py +0 -0
  247. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/url_parser.py +0 -0
  248. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/urlparse_tool/__init__.py +0 -0
  249. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/urlparse_tool/cli.py +0 -0
  250. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/uuid_tool/__init__.py +0 -0
  251. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/uuid_tool/__main__.py +0 -0
  252. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/watch.py +0 -0
  253. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/weather_cli.py +0 -0
  254. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/web_download.py +0 -0
  255. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/web_summary/__init__.py +0 -0
  256. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/web_summary/__main__.py +0 -0
  257. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/whois_lookup.py +0 -0
  258. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/wordcount/__init__.py +0 -0
  259. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/wordcount/__main__.py +0 -0
  260. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/xml2json.py +0 -0
  261. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/yaml2json/__init__.py +0 -0
  262. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/yaml2json/yaml2json.py +0 -0
  263. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/yaml2toml.py +0 -0
  264. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/yaml_validate.py +0 -0
  265. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools/vendor/yes.py +0 -0
  266. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools.egg-info/dependency_links.txt +0 -0
  267. {evolver_tools-21.0.0 → evolver_tools-23.0.0}/src/evolver_tools.egg-info/entry_points.txt +0 -0
  268. {evolver_tools-21.0.0 → evolver_tools-23.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: 21.0.0
4
- Summary: 191 CLI tools + 9 flagship projects — one pip install
3
+ Version: 23.0.0
4
+ Summary: 201 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 = "21.0.0"
8
- description = "191 CLI tools + 9 flagship projects — one pip install"
7
+ version = "23.0.0"
8
+ description = "201 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 v21.0.0 =====\x1b[0m')
17
+ print(f'\x1b[1;36m===== EVOLVER Tools v23.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,93 @@
1
+ #!/usr/bin/env python3
2
+ """base58 — Base58 encode/decode (Bitcoin-style alphabet).
3
+
4
+ Usage: base58 encode hello
5
+ base58 decode 3yZe7d
6
+ echo hello | base58 encode
7
+
8
+ Base58 uses Bitcoin alphabet (123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz).
9
+ No '0', 'O', 'I', 'l' — safe for human transcription.
10
+ """
11
+
12
+ import sys
13
+
14
+ TOOL_META = {
15
+ "name": "base58",
16
+ "func": "main",
17
+ "desc": "Base58 encode/decode (Bitcoin-style alphabet)",
18
+ }
19
+
20
+ ALPHABET = b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
21
+ BASE = 58
22
+
23
+ def b58encode(data):
24
+ if isinstance(data, str):
25
+ data = data.encode()
26
+ n = int.from_bytes(data, 'big')
27
+ if n == 0:
28
+ return '1'
29
+ res = []
30
+ while n > 0:
31
+ n, r = divmod(n, BASE)
32
+ res.append(chr(ALPHABET[r]))
33
+ # Leading zeros
34
+ leading = 0
35
+ for b in data:
36
+ if b == 0:
37
+ leading += 1
38
+ else:
39
+ break
40
+ return '1' * leading + ''.join(reversed(res))
41
+
42
+
43
+ def b58decode(s):
44
+ n = 0
45
+ for c in s:
46
+ idx = ALPHABET.find(c.encode() if isinstance(c, str) else c)
47
+ if idx == -1:
48
+ raise ValueError(f"Invalid Base58 character: {c}")
49
+ n = n * BASE + idx
50
+ # Count leading '1's
51
+ leading = 0
52
+ for c in s:
53
+ if c == '1':
54
+ leading += 1
55
+ else:
56
+ break
57
+ result = n.to_bytes((n.bit_length() + 7) // 8, 'big') if n > 0 else b''
58
+ return b'\x00' * leading + result
59
+
60
+
61
+ def main():
62
+ args = sys.argv[1:]
63
+ if not args or args[0] in ('-h', '--help'):
64
+ print(__doc__)
65
+ return
66
+
67
+ mode = args[0]
68
+ if mode not in ('encode', 'decode'):
69
+ print("Usage: base58 encode|decode [text]", file=sys.stderr)
70
+ sys.exit(1)
71
+
72
+ if len(args) > 1:
73
+ data = ' '.join(args[1:])
74
+ else:
75
+ data = sys.stdin.read().strip()
76
+
77
+ if not data:
78
+ print("Error: no input", file=sys.stderr)
79
+ sys.exit(1)
80
+
81
+ try:
82
+ if mode == 'encode':
83
+ result = b58encode(data.encode() if isinstance(data, str) else data)
84
+ else:
85
+ result = b58decode(data)
86
+ try:
87
+ result = result.decode('utf-8')
88
+ except UnicodeDecodeError:
89
+ result = result.hex()
90
+ print(result)
91
+ except Exception as e:
92
+ print(f"Error: {e}", file=sys.stderr)
93
+ sys.exit(1)
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env python3
2
+ """crc_check — CRC32/CRC64 checksum calculator for files.
3
+
4
+ Usage: crc_check file.bin
5
+ crc_check --crc64 file.bin
6
+ crc_check --all file.bin
7
+ cat file.bin | crc_check
8
+
9
+ Verify file integrity with CRC checksums.
10
+ Zero external dependencies (zlib.crc32 + pure Python CRC64).
11
+ """
12
+
13
+ import sys
14
+ import os
15
+ import zlib
16
+
17
+ TOOL_META = {
18
+ "name": "crc_check",
19
+ "func": "main",
20
+ "desc": "CRC32/CRC64 checksum calculator for files",
21
+ }
22
+
23
+ def crc64(data):
24
+ """Compute CRC64-ECMA-182."""
25
+ poly = 0xC96C5795D7870F42
26
+ crc = 0xFFFFFFFFFFFFFFFF
27
+ for byte in data:
28
+ crc ^= byte
29
+ for _ in range(8):
30
+ if crc & 1:
31
+ crc = (crc >> 1) ^ poly
32
+ else:
33
+ crc >>= 1
34
+ return crc ^ 0xFFFFFFFFFFFFFFFF
35
+
36
+
37
+ def main():
38
+ args = sys.argv[1:]
39
+ mode = 'crc32'
40
+ files = []
41
+
42
+ i = 0
43
+ while i < len(args):
44
+ if args[i] in ('-h', '--help'):
45
+ print(__doc__)
46
+ return
47
+ elif args[i] == '--crc64':
48
+ mode = 'crc64'
49
+ i += 1
50
+ elif args[i] == '--all':
51
+ mode = 'all'
52
+ i += 1
53
+ elif args[i].startswith('--'):
54
+ print(f"Unknown flag: {args[i]}", file=sys.stderr)
55
+ sys.exit(1)
56
+ else:
57
+ files.append(args[i])
58
+ i += 1
59
+
60
+ if files:
61
+ for path in files:
62
+ if not os.path.exists(path):
63
+ print(f"Error: file not found: {path}", file=sys.stderr)
64
+ sys.exit(1)
65
+ with open(path, 'rb') as f:
66
+ data = f.read()
67
+ name = os.path.basename(path)
68
+ if mode in ('crc32', 'all'):
69
+ print(f"CRC32({name}) = {zlib.crc32(data) & 0xFFFFFFFF:08x}")
70
+ if mode in ('crc64', 'all'):
71
+ print(f"CRC64({name}) = {crc64(data):016x}")
72
+ else:
73
+ data = sys.stdin.buffer.read()
74
+ if mode in ('crc32', 'all'):
75
+ print(f"CRC32 = {zlib.crc32(data) & 0xFFFFFFFF:08x}")
76
+ if mode in ('crc64', 'all'):
77
+ print(f"CRC64 = {crc64(data):016x}")
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env python3
2
+ """date_diff — Calculate date/time differences.
3
+
4
+ Usage: date_diff 2026-01-01 2026-06-01
5
+ date_diff 2026-01-01 2026-06-01 --unit hours
6
+ date_diff now "2026-12-25"
7
+ date_diff "2026-01-01 09:00" "2026-01-01 17:30" --unit minutes
8
+
9
+ Show difference in days, hours, minutes, or seconds between two dates.
10
+ Accepts ISO 8601 dates, 'now', and datetime strings.
11
+ """
12
+
13
+ import sys
14
+ from datetime import datetime
15
+
16
+ TOOL_META = {
17
+ "name": "date_diff",
18
+ "func": "main",
19
+ "desc": "Calculate date/time differences",
20
+ }
21
+
22
+ def parse_date(s):
23
+ if s.lower() == 'now':
24
+ return datetime.now()
25
+ for fmt in ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d',
26
+ '%Y/%m/%d %H:%M:%S', '%Y/%m/%d %H:%M', '%Y/%m/%d',
27
+ '%m/%d/%Y', '%d/%m/%Y'):
28
+ try:
29
+ return datetime.strptime(s, fmt)
30
+ except ValueError:
31
+ continue
32
+ raise ValueError(f"Cannot parse date: {s}")
33
+
34
+
35
+ def main():
36
+ args = sys.argv[1:]
37
+ if not args or args[0] in ('-h', '--help'):
38
+ print(__doc__)
39
+ return
40
+
41
+ unit = 'days'
42
+ date_strs = []
43
+
44
+ i = 0
45
+ while i < len(args):
46
+ if args[i] == '--unit' and i + 1 < len(args):
47
+ unit = args[i + 1].lower()
48
+ i += 2
49
+ elif args[i].startswith('--'):
50
+ print(f"Unknown flag: {args[i]}", file=sys.stderr)
51
+ sys.exit(1)
52
+ else:
53
+ date_strs.append(args[i])
54
+ i += 1
55
+
56
+ if len(date_strs) < 2:
57
+ print("Error: need two dates", file=sys.stderr)
58
+ sys.exit(1)
59
+
60
+ try:
61
+ d1 = parse_date(date_strs[0])
62
+ d2 = parse_date(date_strs[1])
63
+ except ValueError as e:
64
+ print(f"Error: {e}", file=sys.stderr)
65
+ sys.exit(1)
66
+
67
+ delta = abs(d2 - d1)
68
+ total_seconds = delta.total_seconds()
69
+
70
+ if unit in ('days', 'day', 'd'):
71
+ result = total_seconds / 86400
72
+ label = 'days'
73
+ elif unit in ('hours', 'hour', 'h'):
74
+ result = total_seconds / 3600
75
+ label = 'hours'
76
+ elif unit in ('minutes', 'minute', 'min', 'm'):
77
+ result = total_seconds / 60
78
+ label = 'minutes'
79
+ elif unit in ('seconds', 'second', 'sec', 's'):
80
+ result = total_seconds
81
+ label = 'seconds'
82
+ elif unit in ('weeks', 'week', 'w'):
83
+ result = total_seconds / 604800
84
+ label = 'weeks'
85
+ elif unit in ('months', 'month'):
86
+ # Approximate
87
+ result = total_seconds / (86400 * 30.44)
88
+ label = 'months'
89
+ elif unit in ('years', 'year', 'y'):
90
+ result = total_seconds / (86400 * 365.25)
91
+ label = 'years'
92
+ else:
93
+ print(f"Error: unknown unit: {unit}", file=sys.stderr)
94
+ sys.exit(1)
95
+
96
+ if result == int(result):
97
+ print(f"{int(result)} {label}")
98
+ else:
99
+ print(f"{result:.2f} {label}")
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env python3
2
+ """env_template — Generate .env.example from .env (strip values, keep keys).
3
+
4
+ Usage: env_template # Reads .env, writes .env.example
5
+ env_template .env.prod # Reads specific file
6
+ env_template --stdout # Print to stdout instead
7
+
8
+ Strip all values from .env files, keeping only the keys and comments.
9
+ Useful for committing a safe .env.example to version control.
10
+ """
11
+
12
+ import sys
13
+ import os
14
+ import re
15
+
16
+ TOOL_META = {
17
+ "name": "env_template",
18
+ "func": "main",
19
+ "desc": "Generate .env.example from .env (strip values, keep keys)",
20
+ }
21
+
22
+
23
+ def main():
24
+ args = sys.argv[1:]
25
+ input_file = '.env'
26
+ stdout_mode = False
27
+ output_file = '.env.example'
28
+
29
+ for arg in args:
30
+ if arg == '--stdout':
31
+ stdout_mode = True
32
+ elif arg in ('-h', '--help'):
33
+ print(__doc__)
34
+ return
35
+ elif not arg.startswith('--'):
36
+ input_file = arg
37
+ else:
38
+ print(f"Unknown flag: {arg}", file=sys.stderr)
39
+ sys.exit(1)
40
+
41
+ if not os.path.exists(input_file):
42
+ print(f"Error: {input_file} not found", file=sys.stderr)
43
+ sys.exit(1)
44
+
45
+ with open(input_file) as f:
46
+ lines = f.readlines()
47
+
48
+ result = []
49
+ for line in lines:
50
+ stripped = line.rstrip('\n')
51
+ # Comment line — keep as-is
52
+ if stripped.strip().startswith('#'):
53
+ result.append(stripped)
54
+ # Empty line — keep
55
+ elif not stripped.strip():
56
+ result.append('')
57
+ # Key=value line — strip value
58
+ elif '=' in stripped:
59
+ key = stripped.split('=', 1)[0].strip()
60
+ # Detect inline comments after key
61
+ comment = ''
62
+ cm = re.search(r'\s+#.*$', stripped)
63
+ if cm:
64
+ comment = cm.group()
65
+ result.append(f"{key}={comment.strip() if comment else ''}")
66
+ else:
67
+ # Keep lines that don't match known patterns
68
+ result.append(stripped)
69
+
70
+ output = '\n'.join(result)
71
+
72
+ if stdout_mode:
73
+ print(output)
74
+ else:
75
+ if not output_file:
76
+ base, _ = os.path.splitext(input_file)
77
+ output_file = f"{base}.example"
78
+ with open(output_file, 'w') as f:
79
+ f.write(output)
80
+ f.write('\n')
81
+ print(f"Written {output_file} ({len([l for l in result if '=' in l])} keys)")
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env python3
2
+ """file_find — Find files by name pattern with recursive search.
3
+
4
+ Usage: file_find *.txt # Find all .txt files
5
+ file_find config* --dir . # In current dir
6
+ file_find test_*.py --max 10 # Limit results
7
+ file_find Dockerfile # Exact name match
8
+
9
+ Lightweight alternative to 'find' with simpler syntax.
10
+ Uses fnmatch pattern matching. Zero dependencies.
11
+ """
12
+
13
+ import os
14
+ import sys
15
+ import fnmatch
16
+
17
+ TOOL_META = {
18
+ "name": "file_find",
19
+ "func": "main",
20
+ "desc": "Find files by name pattern with recursive search",
21
+ }
22
+
23
+
24
+ def main():
25
+ args = sys.argv[1:]
26
+ if not args or args[0] in ('-h', '--help'):
27
+ print(__doc__)
28
+ return
29
+
30
+ pattern = None
31
+ search_dir = os.getcwd()
32
+ max_results = 0
33
+ case_insensitive = False
34
+ type_filter = None # 'f' or 'd'
35
+
36
+ i = 0
37
+ while i < len(args):
38
+ if args[i] == '--dir' and i + 1 < len(args):
39
+ search_dir = os.path.abspath(args[i + 1])
40
+ i += 2
41
+ elif args[i] == '--max' and i + 1 < len(args):
42
+ max_results = int(args[i + 1])
43
+ i += 2
44
+ elif args[i] == '--type' and i + 1 < len(args):
45
+ type_filter = args[i + 1]
46
+ i += 2
47
+ elif args[i] == '--ignore-case' or args[i] == '-i':
48
+ case_insensitive = True
49
+ i += 1
50
+ elif not args[i].startswith('--'):
51
+ pattern = args[i]
52
+ i += 1
53
+ else:
54
+ i += 1
55
+
56
+ if not pattern:
57
+ print("Error: no pattern specified", file=sys.stderr)
58
+ sys.exit(1)
59
+
60
+ if not os.path.isdir(search_dir):
61
+ print(f"Error: directory not found: {search_dir}", file=sys.stderr)
62
+ sys.exit(1)
63
+
64
+ count = 0
65
+ for root, dirs, files in os.walk(search_dir):
66
+ # Skip hidden dirs by default
67
+ dirs[:] = [d for d in dirs if not d.startswith('.')]
68
+
69
+ targets = []
70
+ if type_filter in (None, 'f'):
71
+ targets.extend(files)
72
+ if type_filter in (None, 'd'):
73
+ targets.extend(dirs)
74
+
75
+ for name in targets:
76
+ matched = False
77
+ if case_insensitive:
78
+ matched = fnmatch.fnmatch(name.lower(), pattern.lower())
79
+ else:
80
+ matched = fnmatch.fnmatch(name, pattern)
81
+
82
+ if matched:
83
+ path = os.path.join(root, name)
84
+ print(path)
85
+ count += 1
86
+ if max_results and count >= max_results:
87
+ print(f"--- {count} results (max: {max_results}) ---")
88
+ return
89
+
90
+ if count == 0:
91
+ print(f"No files matching '{pattern}' in {search_dir}")
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env python3
2
+ """ip_info — Show public IP address and geolocation info.
3
+
4
+ Usage: ip_info # Your public IP
5
+ ip_info 8.8.8.8 # Lookup specific IP
6
+ ip_info --json # JSON output
7
+
8
+ Uses ip-api.com for geolocation data.
9
+ """
10
+
11
+ import sys
12
+ import json
13
+ import urllib.request
14
+ import urllib.error
15
+
16
+ TOOL_META = {
17
+ "name": "ip_info",
18
+ "func": "main",
19
+ "desc": "Show public IP address and geolocation info",
20
+ }
21
+
22
+
23
+ def main():
24
+ args = sys.argv[1:]
25
+ ip = None
26
+ json_mode = False
27
+
28
+ for arg in args:
29
+ if arg in ('-h', '--help'):
30
+ print(__doc__)
31
+ return
32
+ elif arg == '--json' or arg == '-j':
33
+ json_mode = True
34
+ elif not arg.startswith('--'):
35
+ ip = arg
36
+ else:
37
+ print(f"Unknown flag: {arg}", file=sys.stderr)
38
+ sys.exit(1)
39
+
40
+ target = ip or ''
41
+ url = f"http://ip-api.com/json/{target}?fields=status,message,query,country,regionName,city,zip,lat,lon,isp,org,as,timezone"
42
+
43
+ try:
44
+ resp = urllib.request.urlopen(url, timeout=10)
45
+ data = json.loads(resp.read().decode())
46
+ except urllib.error.URLError as e:
47
+ print(f"Error: {e.reason}", file=sys.stderr)
48
+ sys.exit(1)
49
+ except json.JSONDecodeError:
50
+ print("Error: invalid response from API", file=sys.stderr)
51
+ sys.exit(1)
52
+
53
+ if data.get('status') == 'fail':
54
+ print(f"Error: {data.get('message', 'unknown')}", file=sys.stderr)
55
+ sys.exit(1)
56
+
57
+ if json_mode:
58
+ print(json.dumps(data, indent=2))
59
+ return
60
+
61
+ print(f" IP: {data['query']}")
62
+ print(f" Country: {data.get('country', 'N/A')}")
63
+ print(f" Region: {data.get('regionName', 'N/A')}")
64
+ print(f" City: {data.get('city', 'N/A')}")
65
+ print(f" ZIP: {data.get('zip', 'N/A')}")
66
+ print(f" Lat/Lon: {data.get('lat', '')}, {data.get('lon', '')}")
67
+ print(f" ISP: {data.get('isp', 'N/A')}")
68
+ print(f" Org: {data.get('org', 'N/A')}")
69
+ print(f" AS: {data.get('as', 'N/A')}")
70
+ print(f" Timezone: {data.get('timezone', 'N/A')}")
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env python3
2
+ """json_merge — Merge multiple JSON files into one.
3
+
4
+ Usage: json_merge file1.json file2.json
5
+ json_merge *.json --output merged.json
6
+ json_merge base.json override.json --strategy deep
7
+
8
+ Merge strategies:
9
+ - shallow (default): top-level keys only. Later files override earlier.
10
+ - deep: recursive merge of nested dicts.
11
+ - array: concatenate arrays.
12
+ """
13
+
14
+ import json
15
+ import sys
16
+ import os
17
+ from copy import deepcopy
18
+
19
+ TOOL_META = {
20
+ "name": "json_merge",
21
+ "func": "main",
22
+ "desc": "Merge multiple JSON files into one",
23
+ }
24
+
25
+
26
+ def deep_merge(a, b):
27
+ """Recursively merge b into a."""
28
+ result = deepcopy(a)
29
+ for key in b:
30
+ if key in result and isinstance(result[key], dict) and isinstance(b[key], dict):
31
+ result[key] = deep_merge(result[key], b[key])
32
+ else:
33
+ result[key] = deepcopy(b[key])
34
+ return result
35
+
36
+
37
+ def array_merge(a, b):
38
+ """Merge arrays by concatenation."""
39
+ if isinstance(a, dict) and isinstance(b, dict):
40
+ result = deepcopy(a)
41
+ for key in b:
42
+ if key in result and isinstance(result[key], list) and isinstance(b[key], list):
43
+ result[key] = result[key] + b[key]
44
+ elif key in result and isinstance(result[key], dict) and isinstance(b[key], dict):
45
+ result[key] = deep_merge(result[key], b[key])
46
+ else:
47
+ result[key] = deepcopy(b[key])
48
+ return result
49
+ elif isinstance(a, list) and isinstance(b, list):
50
+ return a + b
51
+ return b
52
+
53
+
54
+ def main():
55
+ args = sys.argv[1:]
56
+ files = []
57
+ strategy = 'shallow'
58
+ output = None
59
+
60
+ i = 0
61
+ while i < len(args):
62
+ if args[i] in ('-h', '--help'):
63
+ print(__doc__)
64
+ return
65
+ elif args[i] == '--strategy' and i + 1 < len(args):
66
+ strategy = args[i + 1].lower()
67
+ i += 2
68
+ elif args[i] == '--output' and i + 1 < len(args):
69
+ output = args[i + 1]
70
+ i += 2
71
+ elif not args[i].startswith('--'):
72
+ files.append(args[i])
73
+ i += 1
74
+ else:
75
+ i += 1
76
+
77
+ if len(files) < 2:
78
+ print("Error: need at least 2 JSON files", file=sys.stderr)
79
+ sys.exit(1)
80
+
81
+ data = []
82
+ for path in files:
83
+ if not os.path.exists(path):
84
+ print(f"Error: file not found: {path}", file=sys.stderr)
85
+ sys.exit(1)
86
+ with open(path) as f:
87
+ data.append(json.load(f))
88
+
89
+ result = data[0]
90
+ for d in data[1:]:
91
+ if strategy == 'deep':
92
+ result = deep_merge(result, d)
93
+ elif strategy == 'array':
94
+ result = array_merge(result, d)
95
+ else:
96
+ # shallow
97
+ result.update(d)
98
+
99
+ if output:
100
+ with open(output, 'w') as f:
101
+ json.dump(result, f, indent=2)
102
+ print(f"Merged {len(files)} files -> {output}")
103
+ else:
104
+ print(json.dumps(result, indent=2))