chutils 3.4.1__tar.gz → 3.4.2__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 (572) hide show
  1. {chutils-3.4.1 → chutils-3.4.2}/PKG-INFO +1 -1
  2. {chutils-3.4.1 → chutils-3.4.2}/api_map.md +3 -3
  3. chutils-3.4.2/conductor/tracks/telegram_access_20260729/index.md +5 -0
  4. chutils-3.4.2/conductor/tracks/telegram_access_20260729/metadata.json +8 -0
  5. chutils-3.4.2/conductor/tracks/telegram_access_20260729/plan.md +18 -0
  6. chutils-3.4.2/conductor/tracks/telegram_access_20260729/spec.md +24 -0
  7. chutils-3.4.2/conductor/tracks/telegram_formatting_20260729/index.md +5 -0
  8. chutils-3.4.2/conductor/tracks/telegram_formatting_20260729/metadata.json +8 -0
  9. chutils-3.4.2/conductor/tracks/telegram_formatting_20260729/plan.md +17 -0
  10. chutils-3.4.2/conductor/tracks/telegram_formatting_20260729/spec.md +14 -0
  11. chutils-3.4.2/conductor/tracks/telegram_keyboard_20260729/index.md +5 -0
  12. chutils-3.4.2/conductor/tracks/telegram_keyboard_20260729/metadata.json +8 -0
  13. chutils-3.4.2/conductor/tracks/telegram_keyboard_20260729/plan.md +18 -0
  14. chutils-3.4.2/conductor/tracks/telegram_keyboard_20260729/spec.md +15 -0
  15. chutils-3.4.2/conductor/tracks/telegram_logging_20260729/index.md +5 -0
  16. chutils-3.4.2/conductor/tracks/telegram_logging_20260729/metadata.json +8 -0
  17. chutils-3.4.2/conductor/tracks/telegram_logging_20260729/plan.md +17 -0
  18. chutils-3.4.2/conductor/tracks/telegram_logging_20260729/spec.md +16 -0
  19. chutils-3.4.2/conductor/tracks/telegram_media_20260729/index.md +5 -0
  20. chutils-3.4.2/conductor/tracks/telegram_media_20260729/metadata.json +8 -0
  21. chutils-3.4.2/conductor/tracks/telegram_media_20260729/plan.md +18 -0
  22. chutils-3.4.2/conductor/tracks/telegram_media_20260729/spec.md +15 -0
  23. chutils-3.4.2/conductor/tracks/telegram_notifier_20260729/index.md +5 -0
  24. chutils-3.4.2/conductor/tracks/telegram_notifier_20260729/metadata.json +8 -0
  25. chutils-3.4.2/conductor/tracks/telegram_notifier_20260729/plan.md +17 -0
  26. chutils-3.4.2/conductor/tracks/telegram_notifier_20260729/spec.md +18 -0
  27. chutils-3.4.2/conductor/tracks/telegram_ratelimit_20260729/index.md +5 -0
  28. chutils-3.4.2/conductor/tracks/telegram_ratelimit_20260729/metadata.json +8 -0
  29. chutils-3.4.2/conductor/tracks/telegram_ratelimit_20260729/plan.md +19 -0
  30. chutils-3.4.2/conductor/tracks/telegram_ratelimit_20260729/spec.md +21 -0
  31. chutils-3.4.2/conductor/tracks/telegram_send_file_20260729/index.md +5 -0
  32. chutils-3.4.2/conductor/tracks/telegram_send_file_20260729/metadata.json +8 -0
  33. chutils-3.4.2/conductor/tracks/telegram_send_file_20260729/plan.md +18 -0
  34. chutils-3.4.2/conductor/tracks/telegram_send_file_20260729/spec.md +14 -0
  35. chutils-3.4.2/conductor/tracks/telegram_whitelist_20260729/index.md +5 -0
  36. chutils-3.4.2/conductor/tracks/telegram_whitelist_20260729/metadata.json +8 -0
  37. chutils-3.4.2/conductor/tracks/telegram_whitelist_20260729/plan.md +17 -0
  38. chutils-3.4.2/conductor/tracks/telegram_whitelist_20260729/spec.md +19 -0
  39. chutils-3.4.2/conductor/tracks.md +91 -0
  40. {chutils-3.4.1 → chutils-3.4.2}/docs/INTEGRATION_AI.md +25 -2
  41. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_lint.md +24 -5
  42. chutils-3.4.2/docs/cli/check.md +97 -0
  43. {chutils-3.4.1 → chutils-3.4.2}/docs/cli/dev.md +138 -17
  44. chutils-3.4.2/docs/cli/validate.md +130 -0
  45. {chutils-3.4.1 → chutils-3.4.2}/project_index.json +172 -48
  46. {chutils-3.4.1 → chutils-3.4.2}/pyproject.toml +1 -1
  47. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/__init__.py +8 -1
  48. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/cli.py +4 -0
  49. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/__init__.py +2 -0
  50. chutils-3.4.2/src/chutils/commands/check.py +238 -0
  51. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/diagnostics.py +6 -2
  52. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/generate_context.py +30 -5
  53. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/utils.py +19 -2
  54. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/validate.py +17 -4
  55. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/ai_lint.py +4 -7
  56. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/ast_indexer.py +18 -4
  57. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/changelog_parser.py +3 -3
  58. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/project_metadata.py +7 -0
  59. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/dependency_sync.py +5 -13
  60. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/upgrade_client.py +33 -4
  61. chutils-3.4.2/tests/unit/cli/test_cli_check.py +60 -0
  62. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_utils_internal.py +15 -0
  63. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_changelog_parser.py +8 -0
  64. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_upgrade_client.py +21 -2
  65. {chutils-3.4.1 → chutils-3.4.2}/uv.lock +251 -125
  66. chutils-3.4.1/conductor/tracks.md +0 -37
  67. chutils-3.4.1/docs/cli/validate.md +0 -78
  68. {chutils-3.4.1 → chutils-3.4.2}/.chutilsignore +0 -0
  69. {chutils-3.4.1 → chutils-3.4.2}/.gitattributes +0 -0
  70. {chutils-3.4.1 → chutils-3.4.2}/.github/workflows/ci.yml +0 -0
  71. {chutils-3.4.1 → chutils-3.4.2}/.github/workflows/publish-docs.yml +0 -0
  72. {chutils-3.4.1 → chutils-3.4.2}/.gitignore +0 -0
  73. {chutils-3.4.1 → chutils-3.4.2}/CODE_OF_CONDUCT.md +0 -0
  74. {chutils-3.4.1 → chutils-3.4.2}/CONTRIBUTING.md +0 -0
  75. {chutils-3.4.1 → chutils-3.4.2}/GEMINI.md +0 -0
  76. {chutils-3.4.1 → chutils-3.4.2}/LICENSE +0 -0
  77. {chutils-3.4.1 → chutils-3.4.2}/README.md +0 -0
  78. {chutils-3.4.1 → chutils-3.4.2}/ai-lint.toml +0 -0
  79. {chutils-3.4.1 → chutils-3.4.2}/benchmarks/cold_start.py +0 -0
  80. {chutils-3.4.1 → chutils-3.4.2}/conductor/.gitignore +0 -0
  81. {chutils-3.4.1 → chutils-3.4.2}/conductor/GEMINI.md +0 -0
  82. {chutils-3.4.1 → chutils-3.4.2}/conductor/code_styleguides/python.md +0 -0
  83. {chutils-3.4.1 → chutils-3.4.2}/conductor/index.md +0 -0
  84. {chutils-3.4.1 → chutils-3.4.2}/conductor/product-guidelines.md +0 -0
  85. {chutils-3.4.1 → chutils-3.4.2}/conductor/product.md +0 -0
  86. {chutils-3.4.1 → chutils-3.4.2}/conductor/setup_state.json +0 -0
  87. {chutils-3.4.1 → chutils-3.4.2}/conductor/tech-stack.md +0 -0
  88. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/ai_context_opt_20260728/index.md +0 -0
  89. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/ai_context_opt_20260728/metadata.json +0 -0
  90. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/ai_context_opt_20260728/plan.md +0 -0
  91. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/ai_context_opt_20260728/spec.md +0 -0
  92. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/async_lifecycle_20260728/index.md +0 -0
  93. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/async_lifecycle_20260728/metadata.json +0 -0
  94. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/async_lifecycle_20260728/plan.md +0 -0
  95. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/async_lifecycle_20260728/spec.md +0 -0
  96. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/browser_profiles_20260728/index.md +0 -0
  97. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/browser_profiles_20260728/metadata.json +0 -0
  98. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/browser_profiles_20260728/plan.md +0 -0
  99. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/browser_profiles_20260728/spec.md +0 -0
  100. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/queue_monitoring_20260728/index.md +0 -0
  101. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/queue_monitoring_20260728/metadata.json +0 -0
  102. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/queue_monitoring_20260728/plan.md +0 -0
  103. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/queue_monitoring_20260728/spec.md +0 -0
  104. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/stream_crypto_20260728/index.md +0 -0
  105. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/stream_crypto_20260728/metadata.json +0 -0
  106. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/stream_crypto_20260728/plan.md +0 -0
  107. {chutils-3.4.1 → chutils-3.4.2}/conductor/tracks/stream_crypto_20260728/spec.md +0 -0
  108. {chutils-3.4.1 → chutils-3.4.2}/conductor/workflow.md +0 -0
  109. {chutils-3.4.1 → chutils-3.4.2}/docs/CODE_OF_CONDUCT_RU.md +0 -0
  110. {chutils-3.4.1 → chutils-3.4.2}/docs/CONTRIBUTING_RU.md +0 -0
  111. {chutils-3.4.1 → chutils-3.4.2}/docs/README_RU.md +0 -0
  112. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/README.md +0 -0
  113. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/configuration/README.md +0 -0
  114. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/configuration/bad_pattern.py +0 -0
  115. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/configuration/good_pattern.py +0 -0
  116. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/error_handling/README.md +0 -0
  117. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/error_handling/bad_pattern.py +0 -0
  118. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/error_handling/good_pattern.py +0 -0
  119. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/logging/README.md +0 -0
  120. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/logging/bad_pattern.py +0 -0
  121. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/logging/good_pattern.py +0 -0
  122. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/optional_deps/README.md +0 -0
  123. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/optional_deps/bad_pattern.py +0 -0
  124. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/optional_deps/good_pattern.py +0 -0
  125. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/secrets/README.md +0 -0
  126. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/secrets/bad_pattern.py +0 -0
  127. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_examples/secrets/good_pattern.py +0 -0
  128. {chutils-3.4.1 → chutils-3.4.2}/docs/ai_hints.md +0 -0
  129. {chutils-3.4.1 → chutils-3.4.2}/docs/api.md +0 -0
  130. {chutils-3.4.1 → chutils-3.4.2}/docs/audit.md +0 -0
  131. {chutils-3.4.1 → chutils-3.4.2}/docs/captcha.md +0 -0
  132. {chutils-3.4.1 → chutils-3.4.2}/docs/cli/config.md +0 -0
  133. {chutils-3.4.1 → chutils-3.4.2}/docs/cli/db.md +0 -0
  134. {chutils-3.4.1 → chutils-3.4.2}/docs/cli/env.md +0 -0
  135. {chutils-3.4.1 → chutils-3.4.2}/docs/cli/index.md +0 -0
  136. {chutils-3.4.1 → chutils-3.4.2}/docs/cli/init.md +0 -0
  137. {chutils-3.4.1 → chutils-3.4.2}/docs/cli/pypi.md +0 -0
  138. {chutils-3.4.1 → chutils-3.4.2}/docs/cli/secrets.md +0 -0
  139. {chutils-3.4.1 → chutils-3.4.2}/docs/cli/show_paths.md +0 -0
  140. {chutils-3.4.1 → chutils-3.4.2}/docs/cli/template.md +0 -0
  141. {chutils-3.4.1 → chutils-3.4.2}/docs/custom_config_providers.md +0 -0
  142. {chutils-3.4.1 → chutils-3.4.2}/docs/dependencies.md +0 -0
  143. {chutils-3.4.1 → chutils-3.4.2}/docs/http.md +0 -0
  144. {chutils-3.4.1 → chutils-3.4.2}/docs/index.md +0 -0
  145. {chutils-3.4.1 → chutils-3.4.2}/docs/migration.md +0 -0
  146. {chutils-3.4.1 → chutils-3.4.2}/docs/plugins.md +0 -0
  147. {chutils-3.4.1 → chutils-3.4.2}/docs/qt.md +0 -0
  148. {chutils-3.4.1 → chutils-3.4.2}/docs/recipes.md +0 -0
  149. {chutils-3.4.1 → chutils-3.4.2}/docs/scraping.md +0 -0
  150. {chutils-3.4.1 → chutils-3.4.2}/docs/store.md +0 -0
  151. {chutils-3.4.1 → chutils-3.4.2}/docs/testing.md +0 -0
  152. {chutils-3.4.1 → chutils-3.4.2}/docs/web.md +0 -0
  153. {chutils-3.4.1 → chutils-3.4.2}/examples/.env +0 -0
  154. {chutils-3.4.1 → chutils-3.4.2}/examples/01_configuration.py +0 -0
  155. {chutils-3.4.1 → chutils-3.4.2}/examples/02_logging.py +0 -0
  156. {chutils-3.4.1 → chutils-3.4.2}/examples/03_secrets.py +0 -0
  157. {chutils-3.4.1 → chutils-3.4.2}/examples/04_full_example.py +0 -0
  158. {chutils-3.4.1 → chutils-3.4.2}/examples/05_different_log_levels.py +0 -0
  159. {chutils-3.4.1 → chutils-3.4.2}/examples/06_local_config_override.py +0 -0
  160. {chutils-3.4.1 → chutils-3.4.2}/examples/07_decorators_example.py +0 -0
  161. {chutils-3.4.1 → chutils-3.4.2}/examples/08_multiple_loggers_example.py +0 -0
  162. {chutils-3.4.1 → chutils-3.4.2}/examples/09_disable_keyring.py +0 -0
  163. {chutils-3.4.1 → chutils-3.4.2}/examples/10_universal_env_override.py +0 -0
  164. {chutils-3.4.1 → chutils-3.4.2}/examples/11_retry_decorator.py +0 -0
  165. {chutils-3.4.1 → chutils-3.4.2}/examples/12_secret_masking.py +0 -0
  166. {chutils-3.4.1 → chutils-3.4.2}/examples/13_pydantic_validation.py +0 -0
  167. {chutils-3.4.1 → chutils-3.4.2}/examples/15_context_logging.py +0 -0
  168. {chutils-3.4.1 → chutils-3.4.2}/examples/16_cloud_secret_managers.py +0 -0
  169. {chutils-3.4.1 → chutils-3.4.2}/examples/17_timeout_decorator.py +0 -0
  170. {chutils-3.4.1 → chutils-3.4.2}/examples/18_config_hot_reload.py +0 -0
  171. {chutils-3.4.1 → chutils-3.4.2}/examples/19_remote_config.py +0 -0
  172. {chutils-3.4.1 → chutils-3.4.2}/examples/20_opentelemetry_tracing.py +0 -0
  173. {chutils-3.4.1 → chutils-3.4.2}/examples/21_config_diagnostics.py +0 -0
  174. {chutils-3.4.1 → chutils-3.4.2}/examples/22_circuit_breaker_decorator.py +0 -0
  175. {chutils-3.4.1 → chutils-3.4.2}/examples/22_qt_logging.py +0 -0
  176. {chutils-3.4.1 → chutils-3.4.2}/examples/22_safe_path_resolution.py +0 -0
  177. {chutils-3.4.1 → chutils-3.4.2}/examples/23_event_bus.py +0 -0
  178. {chutils-3.4.1 → chutils-3.4.2}/examples/23_qt_async.py +0 -0
  179. {chutils-3.4.1 → chutils-3.4.2}/examples/24_qt_typed_signals.py +0 -0
  180. {chutils-3.4.1 → chutils-3.4.2}/examples/24_task_scheduler.py +0 -0
  181. {chutils-3.4.1 → chutils-3.4.2}/examples/25_testing_fixtures_example.py +0 -0
  182. {chutils-3.4.1 → chutils-3.4.2}/examples/26_metrics_prometheus.py +0 -0
  183. {chutils-3.4.1 → chutils-3.4.2}/examples/27_rate_limiting.py +0 -0
  184. {chutils-3.4.1 → chutils-3.4.2}/examples/28_dependency_injection.py +0 -0
  185. {chutils-3.4.1 → chutils-3.4.2}/examples/captcha_solvers_usage.py +0 -0
  186. {chutils-3.4.1 → chutils-3.4.2}/examples/concurrency_scraping_usage.py +0 -0
  187. {chutils-3.4.1 → chutils-3.4.2}/examples/config.yml +0 -0
  188. {chutils-3.4.1 → chutils-3.4.2}/examples/scraping_humanize_usage.py +0 -0
  189. {chutils-3.4.1 → chutils-3.4.2}/examples/web_client_usage.py +0 -0
  190. {chutils-3.4.1 → chutils-3.4.2}/mkdocs.yml +0 -0
  191. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/__init__.pyi +0 -0
  192. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/__main__.py +0 -0
  193. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/antigravity.md +0 -0
  194. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/audit/__init__.py +0 -0
  195. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/audit/_hash.py +0 -0
  196. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/audit/api.py +0 -0
  197. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/audit/backends/__init__.py +0 -0
  198. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/audit/backends/base.py +0 -0
  199. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/audit/backends/file.py +0 -0
  200. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/audit/backends/postgres.py +0 -0
  201. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/audit/backends/sqlite.py +0 -0
  202. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/audit/schema.py +0 -0
  203. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/cache/__init__.py +0 -0
  204. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/cache/base.py +0 -0
  205. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/cache/decorator.py +0 -0
  206. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/cache/in_memory.py +0 -0
  207. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/cache/utils.py +0 -0
  208. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/cli_booster.py +0 -0
  209. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/cli_utils.py +0 -0
  210. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/base.py +0 -0
  211. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/config.py +0 -0
  212. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/db.py +0 -0
  213. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/__init__.py +0 -0
  214. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/ai_lint.py +0 -0
  215. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/base.py +0 -0
  216. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/chat_context.py +0 -0
  217. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/clean.py +0 -0
  218. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/dashboard.py +0 -0
  219. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/few_shot.py +0 -0
  220. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/hooks.py +0 -0
  221. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/mock.py +0 -0
  222. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/profile_imports.py +0 -0
  223. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/scaffold.py +0 -0
  224. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/setup_github_actions.py +0 -0
  225. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/sync_env.py +0 -0
  226. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/dev/watch.py +0 -0
  227. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/env.py +0 -0
  228. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/init.py +0 -0
  229. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/paths.py +0 -0
  230. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/pypi.py +0 -0
  231. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/secrets.py +0 -0
  232. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/commands/template.py +0 -0
  233. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/GEMINI.md +0 -0
  234. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/__init__.py +0 -0
  235. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/ast_fallback_parser.py +0 -0
  236. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/core.py +0 -0
  237. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/custom_providers.py +0 -0
  238. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/dev.py +0 -0
  239. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/diagnostics.py +0 -0
  240. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/generator.py +0 -0
  241. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/getters.py +0 -0
  242. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/integrations.py +0 -0
  243. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/manager.py +0 -0
  244. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/providers.py +0 -0
  245. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/schema.py +0 -0
  246. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/sse.py +0 -0
  247. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/utils.py +0 -0
  248. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/watcher.py +0 -0
  249. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/config/webhook_server.py +0 -0
  250. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/context.py +0 -0
  251. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/crypto.py +0 -0
  252. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/db.py +0 -0
  253. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/decorators.py +0 -0
  254. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/__init__.py +0 -0
  255. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/chat_context.py +0 -0
  256. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/cleaner.py +0 -0
  257. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/constants.py +0 -0
  258. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/dashboard/__init__.py +0 -0
  259. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/dashboard/indexer.py +0 -0
  260. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/dashboard/input.py +0 -0
  261. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/dashboard/tui.py +0 -0
  262. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/env_parser.py +0 -0
  263. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/env_sync.py +0 -0
  264. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/few_shot/__init__.py +0 -0
  265. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/few_shot/detector.py +0 -0
  266. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/few_shot/models.py +0 -0
  267. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/few_shot/renderer.py +0 -0
  268. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/few_shot/writer.py +0 -0
  269. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/github_actions.py +0 -0
  270. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/mock_server.py +0 -0
  271. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/models/__init__.py +0 -0
  272. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/models/base.py +0 -0
  273. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/models/index.py +0 -0
  274. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/models/node.py +0 -0
  275. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/models/symbol.py +0 -0
  276. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/profile_imports.py +0 -0
  277. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/__init__.py +0 -0
  278. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/api_map.py +0 -0
  279. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/decomposition.py +0 -0
  280. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/docstring.py +0 -0
  281. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/env.py +0 -0
  282. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/integration.py +0 -0
  283. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/linter_coverage.py +0 -0
  284. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/manifest.py +0 -0
  285. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/security.py +0 -0
  286. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/rules/upgrade_check.py +0 -0
  287. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/runners.py +0 -0
  288. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/scaffold.py +0 -0
  289. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/version_detector.py +0 -0
  290. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/dev/watcher.py +0 -0
  291. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/di/__init__.py +0 -0
  292. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/di/__init__.pyi +0 -0
  293. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/di/container.py +0 -0
  294. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/diagnostics/__init__.py +0 -0
  295. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/diagnostics/manager.py +0 -0
  296. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/diagnostics/models.py +0 -0
  297. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/diagnostics/web.py +0 -0
  298. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/env.py +0 -0
  299. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/env.pyi +0 -0
  300. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/events/__init__.py +0 -0
  301. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/events/core.py +0 -0
  302. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/__init__.py +0 -0
  303. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/audit.py +0 -0
  304. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/base.py +0 -0
  305. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/cache.py +0 -0
  306. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/config.py +0 -0
  307. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/di.py +0 -0
  308. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/events.py +0 -0
  309. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/logger.py +0 -0
  310. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/resilience.py +0 -0
  311. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/secrets.py +0 -0
  312. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/system.py +0 -0
  313. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/validation.py +0 -0
  314. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/exceptions/watcher.py +0 -0
  315. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/features.py +0 -0
  316. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/fs.py +0 -0
  317. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/http/__init__.py +0 -0
  318. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/http/api.py +0 -0
  319. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/http/client.py +0 -0
  320. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/http/fallback.py +0 -0
  321. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/http/resilience.py +0 -0
  322. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/http/streaming.py +0 -0
  323. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/http/tracing.py +0 -0
  324. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/lifecycle.py +0 -0
  325. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/logger/GEMINI.md +0 -0
  326. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/logger/__init__.py +0 -0
  327. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/logger/core.py +0 -0
  328. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/logger/formatters.py +0 -0
  329. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/logger/handlers.py +0 -0
  330. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/logger/internal/builder.py +0 -0
  331. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/logger/internal/levels.py +0 -0
  332. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/logger/internal/utils.py +0 -0
  333. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/logger/masking.py +0 -0
  334. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/metrics/__init__.py +0 -0
  335. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/metrics/base.py +0 -0
  336. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/metrics/in_memory.py +0 -0
  337. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/metrics/prometheus.py +0 -0
  338. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/metrics/timer.py +0 -0
  339. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/plugins/__init__.py +0 -0
  340. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/plugins/core.py +0 -0
  341. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/plugins/interfaces.py +0 -0
  342. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/qt/__init__.py +0 -0
  343. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/qt/asyncio.py +0 -0
  344. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/qt/logging.py +0 -0
  345. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/qt/shim.py +0 -0
  346. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/qt/signals.py +0 -0
  347. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/qt/widgets.py +0 -0
  348. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/__init__.py +0 -0
  349. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/captcha/__init__.py +0 -0
  350. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/captcha/anticaptcha.py +0 -0
  351. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/captcha/base.py +0 -0
  352. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/captcha/capmonster.py +0 -0
  353. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/captcha/exceptions.py +0 -0
  354. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/captcha/rucaptcha.py +0 -0
  355. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/concurrency/__init__.py +0 -0
  356. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/concurrency/base.py +0 -0
  357. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/concurrency/limiter.py +0 -0
  358. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/concurrency/models.py +0 -0
  359. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/concurrency/pool.py +0 -0
  360. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/concurrency/queues.py +0 -0
  361. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/humanize/__init__.py +0 -0
  362. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/humanize/actions.py +0 -0
  363. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/humanize/antidetect.py +0 -0
  364. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/humanize/math_utils.py +0 -0
  365. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/scraping/humanize/warmer.py +0 -0
  366. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/secret_manager/GEMINI.md +0 -0
  367. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/secret_manager/__init__.py +0 -0
  368. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/secret_manager/core.py +0 -0
  369. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/secret_manager/providers/__init__.py +0 -0
  370. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/secret_manager/providers/aws.py +0 -0
  371. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/secret_manager/providers/base.py +0 -0
  372. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/secret_manager/providers/dotenv.py +0 -0
  373. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/secret_manager/providers/env.py +0 -0
  374. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/secret_manager/providers/gcp.py +0 -0
  375. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/secret_manager/providers/keyring_provider.py +0 -0
  376. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/store/__init__.py +0 -0
  377. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/store/backends/__init__.py +0 -0
  378. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/store/backends/base.py +0 -0
  379. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/store/backends/memcached.py +0 -0
  380. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/store/backends/memory.py +0 -0
  381. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/store/backends/redis.py +0 -0
  382. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/store/decorator.py +0 -0
  383. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/store/manager.py +0 -0
  384. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/tasks/__init__.py +0 -0
  385. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/tasks/__init__.pyi +0 -0
  386. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/tasks/core.py +0 -0
  387. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/testing/__init__.py +0 -0
  388. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/testing/fixtures.py +0 -0
  389. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/text.py +0 -0
  390. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/time.py +0 -0
  391. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/tracing.py +0 -0
  392. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/typing.py +0 -0
  393. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/validation.py +0 -0
  394. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/validation.pyi +0 -0
  395. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/web/__init__.py +0 -0
  396. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/web/client.py +0 -0
  397. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/web/proxy_pool.py +0 -0
  398. {chutils-3.4.1 → chutils-3.4.2}/src/chutils/web/user_agent.py +0 -0
  399. {chutils-3.4.1 → chutils-3.4.2}/tests/conftest.py +0 -0
  400. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/__init__.py +0 -0
  401. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/test_ai_lint_integration.py +0 -0
  402. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/test_cli_e2e.py +0 -0
  403. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/test_db_migrations.py +0 -0
  404. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/test_event_loops.py +0 -0
  405. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/test_examples.py +0 -0
  406. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/test_hooks_integration.py +0 -0
  407. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/test_masking_integration.py +0 -0
  408. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/test_otel_tracing.py +0 -0
  409. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/test_remote_config_integration.py +0 -0
  410. {chutils-3.4.1 → chutils-3.4.2}/tests/integration/test_setup_github_actions_integration.py +0 -0
  411. {chutils-3.4.1 → chutils-3.4.2}/tests/manual/manual_test_cli_booster.py +0 -0
  412. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/conftest.py +0 -0
  413. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli.py +0 -0
  414. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_booster.py +0 -0
  415. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_config.py +0 -0
  416. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_config_cmd.py +0 -0
  417. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_config_schema.py +0 -0
  418. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_dev.py +0 -0
  419. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_dev_cmd.py +0 -0
  420. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_dev_tree.py +0 -0
  421. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_dev_watch.py +0 -0
  422. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_diagnostics.py +0 -0
  423. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_extras_suggestion.py +0 -0
  424. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_init.py +0 -0
  425. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_init_interactive.py +0 -0
  426. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_paths.py +0 -0
  427. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_pypi.py +0 -0
  428. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_rich.py +0 -0
  429. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_rich_width.py +0 -0
  430. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_secrets.py +0 -0
  431. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_setup_github_actions.py +0 -0
  432. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_template.py +0 -0
  433. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/cli/test_cli_validate.py +0 -0
  434. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config.py +0 -0
  435. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_ast_parser.py +0 -0
  436. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_dev.py +0 -0
  437. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_diagnostics.py +0 -0
  438. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_env.py +0 -0
  439. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_env_loading.py +0 -0
  440. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_generator.py +0 -0
  441. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_integrations.py +0 -0
  442. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_json.py +0 -0
  443. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_pydantic.py +0 -0
  444. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_required.py +0 -0
  445. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_schema.py +0 -0
  446. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_sse.py +0 -0
  447. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_sse_integration.py +0 -0
  448. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_tracing.py +0 -0
  449. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_universal_env.py +0 -0
  450. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_utils.py +0 -0
  451. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_validation_group.py +0 -0
  452. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_watcher.py +0 -0
  453. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_config_webhook.py +0 -0
  454. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_custom_config_providers.py +0 -0
  455. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_priority_unification.py +0 -0
  456. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/config/test_remote_config.py +0 -0
  457. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_ast_indexer.py +0 -0
  458. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_ast_indexer_abstract.py +0 -0
  459. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_ast_indexer_graph.py +0 -0
  460. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_ast_indexer_layers.py +0 -0
  461. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_ast_indexer_metadata.py +0 -0
  462. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_cache.py +0 -0
  463. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_dev_models.py +0 -0
  464. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_exceptions.py +0 -0
  465. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_features.py +0 -0
  466. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_fs.py +0 -0
  467. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_lifecycle.py +0 -0
  468. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_thread_safety.py +0 -0
  469. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/core/test_time.py +0 -0
  470. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/decorators/test_decorator_circuit_breaker.py +0 -0
  471. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/decorators/test_decorator_retry.py +0 -0
  472. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/decorators/test_decorator_timeout.py +0 -0
  473. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/decorators/test_decorators.py +0 -0
  474. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/decorators/test_rate_limit.py +0 -0
  475. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_ai_lint.py +0 -0
  476. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_ai_lint_staged.py +0 -0
  477. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_chat_context.py +0 -0
  478. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_cleaner.py +0 -0
  479. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_env_parser.py +0 -0
  480. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_env_sync.py +0 -0
  481. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_generate_few_shot.py +0 -0
  482. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_linter_coverage_rule.py +0 -0
  483. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_mock_server.py +0 -0
  484. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_runners.py +0 -0
  485. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_scaffold.py +0 -0
  486. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_setup_github_actions.py +0 -0
  487. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_upgrade_check_rule.py +0 -0
  488. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_version_detector.py +0 -0
  489. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/dev/test_watcher.py +0 -0
  490. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/di/test_di.py +0 -0
  491. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/events/test_event_bus.py +0 -0
  492. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/conftest.py +0 -0
  493. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_basics.py +0 -0
  494. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_compression.py +0 -0
  495. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_config_sections.py +0 -0
  496. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_configuration.py +0 -0
  497. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_context.py +0 -0
  498. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_env_control.py +0 -0
  499. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_files.py +0 -0
  500. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_json_format.py +0 -0
  501. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_logger_rich_width.py +0 -0
  502. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_masking.py +0 -0
  503. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_performance_security.py +0 -0
  504. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_rich.py +0 -0
  505. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/logger/test_rotation.py +0 -0
  506. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/metrics/test_metrics.py +0 -0
  507. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/plugins/test_integration.py +0 -0
  508. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/plugins/test_interfaces.py +0 -0
  509. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/plugins/test_plugins.py +0 -0
  510. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/secret_manager/test_secret_manager.py +0 -0
  511. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/secret_manager/test_secret_manager_env.py +0 -0
  512. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/secret_manager/test_secret_manager_providers.py +0 -0
  513. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/secret_manager/test_secrets_required.py +0 -0
  514. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/tasks/test_scheduler.py +0 -0
  515. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_ai_lint_ignore.py +0 -0
  516. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_anticaptcha.py +0 -0
  517. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_antidetect.py +0 -0
  518. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_async_web_client.py +0 -0
  519. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_audit.py +0 -0
  520. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_audit_phase2.py +0 -0
  521. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_capmonster.py +0 -0
  522. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_captcha_base.py +0 -0
  523. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_captcha_imports.py +0 -0
  524. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_cli_db.py +0 -0
  525. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_concurrency_imports.py +0 -0
  526. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_concurrency_limiter.py +0 -0
  527. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_concurrency_pool.py +0 -0
  528. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_concurrency_queues.py +0 -0
  529. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_config_alias_choices.py +0 -0
  530. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_config_fallback.py +0 -0
  531. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_crypto.py +0 -0
  532. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_crypto_dependencies.py +0 -0
  533. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_dashboard.py +0 -0
  534. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_db_init.py +0 -0
  535. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_db_operations.py +0 -0
  536. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_decorators_bulkhead.py +0 -0
  537. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_diagnostics.py +0 -0
  538. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_env.py +0 -0
  539. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_events_exception_group.py +0 -0
  540. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_http_api.py +0 -0
  541. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_http_client.py +0 -0
  542. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_http_fallback.py +0 -0
  543. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_http_resilience.py +0 -0
  544. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_http_streaming.py +0 -0
  545. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_http_tracing.py +0 -0
  546. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_humanize_math.py +0 -0
  547. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_install_hooks.py +0 -0
  548. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_minimal_imports.py +0 -0
  549. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_nodriver_humanize.py +0 -0
  550. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_playwright_humanize.py +0 -0
  551. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_profile_imports.py +0 -0
  552. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_profile_warmer.py +0 -0
  553. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_proxy_pool.py +0 -0
  554. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_qt_asyncio.py +0 -0
  555. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_qt_logging.py +0 -0
  556. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_qt_shim.py +0 -0
  557. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_qt_signals.py +0 -0
  558. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_qt_widgets.py +0 -0
  559. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_rucaptcha.py +0 -0
  560. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_scraping_imports.py +0 -0
  561. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_selenium_humanize.py +0 -0
  562. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_store_backends_external.py +0 -0
  563. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_store_integrations.py +0 -0
  564. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_store_manager.py +0 -0
  565. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_store_memory.py +0 -0
  566. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_text.py +0 -0
  567. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_text_dependencies.py +0 -0
  568. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_user_agent.py +0 -0
  569. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_validation.py +0 -0
  570. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_web_client.py +0 -0
  571. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/test_web_imports.py +0 -0
  572. {chutils-3.4.1 → chutils-3.4.2}/tests/unit/testing/test_fixtures.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chutils
3
- Version: 3.4.1
3
+ Version: 3.4.2
4
4
  Summary: Набор простых и удобных утилит для Python, который избавляет от рутины при работе с конфигурацией и логированием в новых проектах.
5
5
  Author-email: Chu4hel <sergeiivanov636@gmail.com>
6
6
  License-Expression: MIT
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  chutils_version: 3.4.1
3
3
  project_version: 3.4.1
4
- git_commit: 824417aa80b19bbfbb6cbb86151e5139be92b981 (dirty)
5
- generated_at: 2026-07-28T19:53:16.120390+00:00
6
- project_hash: 1001ffd89333fcf5c07c42b89dfebc67f38e7574da9f7166e3845fa464c5bc81
4
+ git_commit: 35b0abb02583ebebbd7a918dd74a5056d6b40c5c (dirty)
5
+ generated_at: 2026-07-30T21:04:30.356972+00:00
6
+ project_hash: 73c182750cd7e4d409a97fe4e3797cb39064637a44fe36638c5c113466639683
7
7
  ---
8
8
 
9
9
  # Public API Map: chutils
@@ -0,0 +1,5 @@
1
+ # Track telegram_access_20260729 Context
2
+
3
+ - [Specification](./spec.md)
4
+ - [Implementation Plan](./plan.md)
5
+ - [Metadata](./metadata.json)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "telegram_access_20260729",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-29T00:04:00Z",
6
+ "updated_at": "2026-07-29T00:04:00Z",
7
+ "description": "Безопасность и ограничение доступа для Telegram ботов: @admin_only, AdminFilter с fallback-ом на chutils config"
8
+ }
@@ -0,0 +1,18 @@
1
+ # Implementation Plan: Telegram Bot Access Control (`telegram_access_20260729`)
2
+
3
+ ## Phase 1: Core Access Control Logic & Exception Hierarchy
4
+ - [ ] Task: Create `chutils.exceptions.telegram` module with `TelegramAccessDeniedError`
5
+ - [ ] Task: Create core `chutils.telegram.access` module with `is_admin()` predicate logic and config fallback
6
+ - [ ] Task: Implement `@admin_only` decorator for sync/async handler functions with refusal handling options (`refusal_text`, `silent`, raise exception)
7
+ - [ ] Task: Unit tests for core `is_admin` and `@admin_only` decorator
8
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: Core Access Control' (Protocol in workflow.md)
9
+
10
+ ## Phase 2: Framework Integrations & Lazy Exports
11
+ - [ ] Task: Implement `AdminFilter` for `aiogram 3.x` with safe import handling if `aiogram` is not installed
12
+ - [ ] Task: Register lazy exports in `src/chutils/telegram/__init__.py` and root `src/chutils/__init__.py`
13
+ - [ ] Task: Unit tests for `aiogram` filter and framework compatibility
14
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: Framework Integrations' (Protocol in workflow.md)
15
+
16
+ ## Phase 3: Documentation & Indexing
17
+ - [ ] Task: Document `chutils.telegram` usage in `docs/` and update `api_map.md` / `project_index.json`
18
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Documentation' (Protocol in workflow.md)
@@ -0,0 +1,24 @@
1
+ # Track Specification: Telegram Bot Access Control (`telegram_access_20260729`)
2
+
3
+ ## Overview
4
+ Добавление модуля `chutils.telegram` с универсальным механизмом проверки прав доступа и ограничения вызовов для Telegram-ботов (`@admin_only`, `AdminFilter`). Подсистема решает задачу безопасного разграничения доступа админов/пользователей с автоматическим фоллбэком на конфигурацию `chutils` и поддержкой популярнейших фреймворков (`aiogram 3.x`, `python-telegram-bot`, `telebot`).
5
+
6
+ ## Functional Requirements
7
+ - **Декоратор `@admin_only`**:
8
+ - Поддержка синхронных и асинхронных функций-хэндлеров.
9
+ - Поддержка явного списка `admin_ids` (int) и `admin_usernames` (str без/с `@`).
10
+ - Поддержка кастомной функции-предиката `is_admin_func(user_id, username) -> bool`.
11
+ - Автоматический fallback на конфигурацию `chutils`: чтение списка админов из `get_config_value("Telegram", "admin_ids")` / `admin_usernames` при отсутствии явных аргументов.
12
+ - **Отказ в доступе (Refusal Handling)**:
13
+ - Настройка кастомного ответа (`refusal_text="⛔ Доступ запрещен"`).
14
+ - Поддержка тихого режима (`silent=True`), когда неавторизованные запросы игнорируются без ответа.
15
+ - Поддержка выброса исключения `TelegramAccessDeniedError` для тонкой обработки в Middleware.
16
+ - **Интеграция с Telegram-фреймворками**:
17
+ - `AdminFilter` для `aiogram 3.x` (реализация `BaseFilter`).
18
+ - Универсальная функция-предикат `is_admin(user_id, username, ...)` для использования в `python-telegram-bot`, `telebot` и чистых Webhook/Polling обновлениях.
19
+ - **Типизация и Zero-Any**:
20
+ - Полная типизация через Python 3.10+ unions (`int | str`), отсутствие `Any` в бизнес-логике.
21
+
22
+ ## Out of Scope
23
+ - Хранение прав пользователей в БД (управление ролями).
24
+ - Пагинаторы и UI-клавиатуры (будут вынесены в отдельные треки).
@@ -0,0 +1,5 @@
1
+ # Track telegram_formatting_20260729 Context
2
+
3
+ - [Specification](./spec.md)
4
+ - [Implementation Plan](./plan.md)
5
+ - [Metadata](./metadata.json)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "telegram_formatting_20260729",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-29T00:11:00Z",
6
+ "updated_at": "2026-07-29T00:11:00Z",
7
+ "description": "chutils.telegram.formatting: Экранирование MarkdownV2/HTML (escape_markdown, escape_html) и умное разбиение сообщений (smart_truncate)"
8
+ }
@@ -0,0 +1,17 @@
1
+ # Implementation Plan: Telegram Safe Formatting & Message Truncation (`telegram_formatting_20260729`)
2
+
3
+ ## Phase 1: Core Escaping Functions & Unit Tests
4
+ - [ ] Task: Create `chutils.telegram.formatting` module with `escape_markdown` and `escape_html`
5
+ - [ ] Task: Write comprehensive unit tests for `escape_markdown` (v1/v2) and `escape_html`
6
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: Escaping Functions' (Protocol in workflow.md)
7
+
8
+ ## Phase 2: Smart Truncation & Message Splitting
9
+ - [ ] Task: Implement `smart_truncate` with code block (```) and HTML tag closure
10
+ - [ ] Task: Implement `split_message` helper for splitting logs/long reports
11
+ - [ ] Task: Export functions in `src/chutils/telegram/__init__.py` and root `src/chutils/__init__.py`
12
+ - [ ] Task: Unit tests for `smart_truncate` and `split_message`
13
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: Smart Truncation & Splitting' (Protocol in workflow.md)
14
+
15
+ ## Phase 3: Documentation & Indexing
16
+ - [ ] Task: Add examples in `docs/` and update `api_map.md` / `project_index.json`
17
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Documentation' (Protocol in workflow.md)
@@ -0,0 +1,14 @@
1
+ # Track Specification: Telegram Safe Formatting & Message Truncation (`telegram_formatting_20260729`)
2
+
3
+ ## Overview
4
+ Реализация модуля `chutils.telegram.formatting` для безопасной работы с разметкой сообщений Telegram. Модуль гарантирует защиту от ошибок `BadRequest: Can't parse entities` за счет надежного экранирования `MarkdownV2` / `HTML` и предотвращает вылеты по превышению 4096 символов благодаря умному сплиттингу сообщений с сохранением парности тегов и кодовых блоков.
5
+
6
+ ## Functional Requirements
7
+ - **Экранирование символов (`escape_markdown` / `escape_html`)**:
8
+ - `escape_markdown(text, version=2)`: Экранирование спецсимволов (`_`, `*`, `[`, `]`, `(`, `)`, `~`, `` ` ``, `>`, `#`, `+`, `-`, `=`, `|`, `{`, `}`, `.`, `!`). Поддержка v1 и v2.
9
+ - `escape_html(text)`: Экранирование `<`, `>`, `&`, `"`.
10
+ - **Умное разбиение сообщений (`smart_truncate` & `split_message`)**:
11
+ - `smart_truncate(text, max_length=4096)`: Обрезка текста до `max_length` с автоматическим закрытием незавершенных кодовых блоков (```) или HTML-тегов.
12
+ - `split_message(text, max_length=4096)`: Разбиение длинного текста/логов на список валидных чанков не превышающих `max_length` символов.
13
+ - **Типизация**:
14
+ - Строгие аннотации типов Python 3.10+.
@@ -0,0 +1,5 @@
1
+ # Track telegram_keyboard_20260729 Context
2
+
3
+ - [Specification](./spec.md)
4
+ - [Implementation Plan](./plan.md)
5
+ - [Metadata](./metadata.json)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "telegram_keyboard_20260729",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-29T20:20:00Z",
6
+ "updated_at": "2026-07-29T20:20:00Z",
7
+ "description": "chutils.telegram.keyboard: build_inline_keyboard генератор сетки и PaginatorKeyboard для пагинации списков"
8
+ }
@@ -0,0 +1,18 @@
1
+ # Implementation Plan: Telegram Dynamic & Paginated Keyboards (`telegram_keyboard_20260729`)
2
+
3
+ ## Phase 1: Core Inline Keyboard Generator
4
+ - [ ] Task: Create `chutils.telegram.keyboard` module with `build_inline_keyboard` function
5
+ - [ ] Task: Support grid alignment (`buttons_per_row`), custom URLs, and dict/tuple inputs
6
+ - [ ] Task: Unit tests for `build_inline_keyboard` logic
7
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: Core Inline Keyboard' (Protocol in workflow.md)
8
+
9
+ ## Phase 2: PaginatorKeyboard & Framework Integrations
10
+ - [ ] Task: Implement `PaginatorKeyboard` class with page slicing, state labels, and navigation buttons
11
+ - [ ] Task: Support `footer_buttons` and `aiogram` `InlineKeyboardMarkup` conversion
12
+ - [ ] Task: Export symbols in `src/chutils/telegram/__init__.py` and root `src/chutils/__init__.py`
13
+ - [ ] Task: Unit tests for `PaginatorKeyboard` pagination and navigation
14
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: PaginatorKeyboard & Integration' (Protocol in workflow.md)
15
+
16
+ ## Phase 3: Documentation & Indexing
17
+ - [ ] Task: Add examples in `docs/` and update `api_map.md` / `project_index.json`
18
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Documentation' (Protocol in workflow.md)
@@ -0,0 +1,15 @@
1
+ # Track Specification: Telegram Dynamic & Paginated Keyboards (`telegram_keyboard_20260729`)
2
+
3
+ ## Overview
4
+ Реализация модуля `chutils.telegram.keyboard` для конструирования динамических Inline-клавиатур и управления пагинацией списков. Подсистема исключает рутинное написание сетки кнопок, автоматизирует навигацию (`« Назад`, `1/5`, `Вперед »`) и поддерживает экспорт в формате чистых Python-словарей или готовых `InlineKeyboardMarkup` для `aiogram 3.x`.
5
+
6
+ ## Functional Requirements
7
+ - **Генератор сетки `build_inline_keyboard`**:
8
+ - Принимает список элементов `(text, callback_data)` или словарей `{"text": ..., "callback_data": ..., "url": ...}`.
9
+ - Автоматическое разбиение на ряды с помощью параметра `buttons_per_row` (по умолчанию 2).
10
+ - Опция `as_aiogram` для приведения к объекту `InlineKeyboardMarkup` при наличии `aiogram`.
11
+ - **Пагинатор `PaginatorKeyboard`**:
12
+ - Универсальный класс пагинации для списков любых объектов.
13
+ - Генерация строки состояния (например, `1/5`) и навигационных кнопок (`«`, `»`).
14
+ - Метод `get_page(page: int, per_page: int)` для сбора подмножества данных.
15
+ - Поддержка прикрепления дополнительных фиктивных или постоянных кнопок (`footer_buttons`, например "Закрыть").
@@ -0,0 +1,5 @@
1
+ # Track telegram_logging_20260729 Context
2
+
3
+ - [Specification](./spec.md)
4
+ - [Implementation Plan](./plan.md)
5
+ - [Metadata](./metadata.json)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "telegram_logging_20260729",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-29T00:09:00Z",
6
+ "updated_at": "2026-07-29T00:09:00Z",
7
+ "description": "TelegramLogFilter / TelegramMiddleware: Автоматическое логирование команд, нажатий inline-кнопок и авто-проброс контекста в chutils.logger"
8
+ }
@@ -0,0 +1,17 @@
1
+ # Implementation Plan: Telegram Update Logging & Context Tracing (`telegram_logging_20260729`)
2
+
3
+ ## Phase 1: Core Context Tracing Engine & Decorator
4
+ - [ ] Task: Create `chutils.telegram.logging` module with context binding logic (`telegram_user_id`, `chat_id`, `update_id`)
5
+ - [ ] Task: Implement `trace_telegram_update` sync/async context manager and decorator with `execution_time_ms` calculation and PII masking
6
+ - [ ] Task: Unit tests for core `trace_telegram_update` and logger context binding
7
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: Core Context Tracing Engine' (Protocol in workflow.md)
8
+
9
+ ## Phase 2: aiogram Middleware & Lazy Exports
10
+ - [ ] Task: Implement `TelegramLoggingMiddleware` for `aiogram 3.x`
11
+ - [ ] Task: Register lazy exports in `src/chutils/telegram/__init__.py` and root `src/chutils/__init__.py`
12
+ - [ ] Task: Unit tests for `aiogram` logging middleware
13
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: aiogram Middleware' (Protocol in workflow.md)
14
+
15
+ ## Phase 3: Documentation & Indexing
16
+ - [ ] Task: Add examples in `docs/` and update `api_map.md` / `project_index.json`
17
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Documentation' (Protocol in workflow.md)
@@ -0,0 +1,16 @@
1
+ # Track Specification: Telegram Update Logging & Context Tracing (`telegram_logging_20260729`)
2
+
3
+ ## Overview
4
+ Добавление подсистемы прозрачного логирования и контекстного трейсинга Telegram-апдейтов в `chutils.telegram.logging`. Модуль автоматически обогащает все логи, вызывемые внутри хэндлеров, контекстными полями `telegram_user_id` и `chat_id`, измеряет время выполнения (`execution_time_ms`), маскирует PII-данные и предоставляет удобную мидлварь для `aiogram 3.x`.
5
+
6
+ ## Functional Requirements
7
+ - **Авто-проброс контекста (`chutils.logger.bind_context`)**:
8
+ - При получении любого апдейта автоматически устанавливается локальный контекст потока/таски (`telegram_user_id`, `chat_id`, `update_id`).
9
+ - Гарантированный сброс контекста (cleanup) после завершения работы хэндлера.
10
+ - **Метрики и структура логов**:
11
+ - Логирование успешных команд, нажатий inline-кнопок и необработанных исключений.
12
+ - Измерение точности выполнения в миллисекундах (`execution_time_ms`).
13
+ - Маскирование PII через `chutils.logger.masking`.
14
+ - **Интеграции с фреймворками**:
15
+ - `TelegramLoggingMiddleware` для `aiogram 3.x` (Outer / Inner Middleware).
16
+ - Декоратор и асинхронный контекстный менеджер `trace_telegram_update` для `python-telegram-bot`, `telebot` и пользовательских скриптов.
@@ -0,0 +1,5 @@
1
+ # Track telegram_media_20260729 Context
2
+
3
+ - [Specification](./spec.md)
4
+ - [Implementation Plan](./plan.md)
5
+ - [Metadata](./metadata.json)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "telegram_media_20260729",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-29T20:23:00Z",
6
+ "updated_at": "2026-07-29T20:23:00Z",
7
+ "description": "chutils.telegram.media: download_user_file с автоматической проверкой resolve_safe_path и опцией отключения allow_unsafe_path"
8
+ }
@@ -0,0 +1,18 @@
1
+ # Implementation Plan: Telegram Safe File Downloader (`telegram_media_20260729`)
2
+
3
+ ## Phase 1: Core File Download Logic & Path Safety
4
+ - [ ] Task: Create `chutils.telegram.media` module with `download_user_file` function
5
+ - [ ] Task: Integrate `chutils.fs.resolve_safe_path` and `safe_filename` with `allow_unsafe_path=False` toggle
6
+ - [ ] Task: Implement file size validation (`max_size_bytes`) and HTTP/Bot API stream saving
7
+ - [ ] Task: Unit tests for path traversal attacks, `allow_unsafe_path` override, and file size limits
8
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: Core File Downloader' (Protocol in workflow.md)
9
+
10
+ ## Phase 2: Framework Integrations & Lazy Exports
11
+ - [ ] Task: Support `aiogram 3.x` `Bot` instance and raw `bot_token` HTTP download fallback
12
+ - [ ] Task: Export symbols in `src/chutils/telegram/__init__.py` and root `src/chutils/__init__.py`
13
+ - [ ] Task: Unit tests for framework compatibility and download fallbacks
14
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: Framework Support' (Protocol in workflow.md)
15
+
16
+ ## Phase 3: Documentation & Indexing
17
+ - [ ] Task: Add examples in `docs/` and update `api_map.md` / `project_index.json`
18
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Documentation' (Protocol in workflow.md)
@@ -0,0 +1,15 @@
1
+ # Track Specification: Telegram Safe File Downloader (`telegram_media_20260729`)
2
+
3
+ ## Overview
4
+ Реализация модуля `chutils.telegram.media` для безопасного выкачивания файлов пользователей из Telegram (`download_user_file`). Модуль решает проблему уязвимости Path Traversal при передаче имени файла пользователем через механизмы `chutils.fs.resolve_safe_path` и `safe_filename`, с опциональной возможностью отключения защиты разработчиком (`allow_unsafe_path=True`).
5
+
6
+ ## Functional Requirements
7
+ - **Функция `download_user_file`**:
8
+ - Принимает `bot` (aiogram/python-telegram-bot или bot_token), `file_id`, `target_dir` и `custom_filename` (опционально).
9
+ - Интеграция с `chutils.fs.resolve_safe_path`: гарантирует, что итоговый файл сохраняется строго в пределах `target_dir`.
10
+ - Защита от Path Traversal: санитизация имени файла (удаление `../`, `..\`, замена через `safe_filename`).
11
+ - Опция отключения: параметр `allow_unsafe_path: bool = False`, позволяющий разработчику при необходимости отключить проверку с записью предупреждения в лог (`logger.warning`).
12
+ - Контроль размера файла: `max_size_bytes: int | None` с выбросом `ChutilsException` при превышении.
13
+ - **Типизация и исключения**:
14
+ - Поддержка `async def` и `def` вызова.
15
+ - Понятные ошибки при недоступности файла или нарушении безопасности.
@@ -0,0 +1,5 @@
1
+ # Track telegram_notifier_20260729 Context
2
+
3
+ - [Specification](./spec.md)
4
+ - [Implementation Plan](./plan.md)
5
+ - [Metadata](./metadata.json)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "telegram_notifier_20260729",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-29T00:13:00Z",
6
+ "updated_at": "2026-07-29T00:13:00Z",
7
+ "description": "chutils.telegram.notifier: TelegramLogHandler для алертов об ошибках со стеком и HealthCheckAlertBridge для моста с chutils.diagnostics"
8
+ }
@@ -0,0 +1,17 @@
1
+ # Implementation Plan: Telegram Admin Notifications & Diagnostics Alert Bridge (`telegram_notifier_20260729`)
2
+
3
+ ## Phase 1: TelegramLogHandler & Alert Throttling
4
+ - [ ] Task: Create `chutils.telegram.notifier` module with `TelegramLogHandler` class for standard `logging`
5
+ - [ ] Task: Implement rate-limiting / deduplication of log alerts to prevent spam during cascading failures
6
+ - [ ] Task: Unit tests for `TelegramLogHandler` formatting, rate-limiting, and error handling
7
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: TelegramLogHandler' (Protocol in workflow.md)
8
+
9
+ ## Phase 2: HealthCheckAlertBridge & Diagnostics Integration
10
+ - [ ] Task: Implement `HealthCheckAlertBridge` connected to `chutils.diagnostics`
11
+ - [ ] Task: Export symbols in `src/chutils/telegram/__init__.py` and root `src/chutils/__init__.py`
12
+ - [ ] Task: Unit tests for `HealthCheckAlertBridge` notification triggers
13
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: HealthCheckAlertBridge' (Protocol in workflow.md)
14
+
15
+ ## Phase 3: Documentation & Indexing
16
+ - [ ] Task: Add examples in `docs/` and update `api_map.md` / `project_index.json`
17
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Documentation' (Protocol in workflow.md)
@@ -0,0 +1,18 @@
1
+ # Track Specification: Telegram Admin Notifications & Diagnostics Alert Bridge (`telegram_notifier_20260729`)
2
+
3
+ ## Overview
4
+ Реализация модуля `chutils.telegram.notifier` для немедленного оповещения администраторов о критических сбоях и проблемах здоровья приложения в Telegram. Модуль содержит встроенный лог-хэндлер `TelegramLogHandler` с защитой от флуда и мост `HealthCheckAlertBridge` для отправки алертов при деградации проверок `chutils.diagnostics`.
5
+
6
+ ## Functional Requirements
7
+ - **Лог-хэндлер `TelegramLogHandler`**:
8
+ - Перехват исключений уровня `ERROR` / `CRITICAL`.
9
+ - Форматирование сообщений с трейсбэками, именем модуля и меткой времени.
10
+ - Встроенный Rate-Limiter (дросселирование одинаковых или каскадных алертов, например, не более N сообщений в минуту).
11
+ - Автоматическое чтение `bot_token` и `chat_id` из секции `[Telegram]` конфигурации `chutils`.
12
+ - **Мост алертов диагностики `HealthCheckAlertBridge`**:
13
+ - Подписка на результаты проверок `chutils.diagnostics`.
14
+ - Автоматическая отправка уведомления при переходах статусов здоровья в `DEGRADED` или `UNHEALTHY`.
15
+ - Информативные алерты с форматированием деталей сбоя.
16
+ - **Асинхронность и изоляция**:
17
+ - Отправка алертов не блокирует основной поток приложения (неблокирующий I/O или фоновые таски).
18
+ - Ошибки отправки самого Telegram API не падают с крашем основного приложения.
@@ -0,0 +1,5 @@
1
+ # Track telegram_ratelimit_20260729 Context
2
+
3
+ - [Specification](./spec.md)
4
+ - [Implementation Plan](./plan.md)
5
+ - [Metadata](./metadata.json)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "telegram_ratelimit_20260729",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-29T00:06:00Z",
6
+ "updated_at": "2026-07-29T00:06:00Z",
7
+ "description": "@rate_limit(rate=3, per=60): Защита от спама/флуда пользователей с автоматической отправкой сообщения 'Пожалуйста, подождите X сек.'"
8
+ }
@@ -0,0 +1,19 @@
1
+ # Implementation Plan: Telegram Bot Rate Limiting & Throttling (`telegram_ratelimit_20260729`)
2
+
3
+ ## Phase 1: Core Telegram Rate Limiter Engine & Decorator
4
+ - [ ] Task: Create `chutils.telegram.rate_limit` module with `TelegramRateLimiter` class wrapping `chutils.decorators.rate_limit`
5
+ - [ ] Task: Implement `wait_sec` calculation logic and template formatting (`{wait_sec}`)
6
+ - [ ] Task: Implement `@tg_rate_limit` decorator for sync/async handlers with scope (`user_id`/`chat_id`), `warning_text` and `silent` options
7
+ - [ ] Task: Unit tests for `TelegramRateLimiter` and `@tg_rate_limit` decorator
8
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: Core Telegram Rate Limiter Engine' (Protocol in workflow.md)
9
+
10
+ ## Phase 2: aiogram Middleware & Redis Storage Backend
11
+ - [ ] Task: Implement `TelegramThrottlingMiddleware` for `aiogram 3.x`
12
+ - [ ] Task: Support Redis / `chutils.cache` storage adapter for distributed rate limiting
13
+ - [ ] Task: Export symbols in `src/chutils/telegram/__init__.py` and root `src/chutils/__init__.py`
14
+ - [ ] Task: Unit tests for `aiogram` throttling middleware and Redis storage logic
15
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: aiogram Middleware & Storage' (Protocol in workflow.md)
16
+
17
+ ## Phase 3: Documentation & Indexing
18
+ - [ ] Task: Add examples in `docs/` and update `api_map.md` / `project_index.json`
19
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Documentation' (Protocol in workflow.md)
@@ -0,0 +1,21 @@
1
+ # Track Specification: Telegram Bot Rate Limiting & Throttling (`telegram_ratelimit_20260729`)
2
+
3
+ ## Overview
4
+ Добавление специализированных механизмов защиты от флуда/спама в Telegram-ботах: декоратор `@tg_rate_limit(rate=3, per=60)` и `TelegramThrottlingMiddleware` (для `aiogram 3.x`). Утилита опирается на проверенное ядро `chutils.decorators.rate_limit`, высчитывает точное время ожидания `wait_sec` и автоматически высылает пользователю информативное предупреждение.
5
+
6
+ ## Functional Requirements
7
+ - **Декоратор `@tg_rate_limit` & `TelegramThrottlingMiddleware`**:
8
+ - Параметры: `rate` (количество вызовов), `per` (период в секундах), `strategy` (`token_bucket` / `leaky_bucket`).
9
+ - Шаблон предупреждения: `warning_text="⏱ Пожалуйста, подождите {wait_sec} сек. перед повторной отправкой."`.
10
+ - Тихий режим: `silent=True` для полного отбрасывания спам-запросов без вызова Telegram API и расхода лимитов бота.
11
+ - Ключи лимитирования (`scope`): по `user_id` (дефолт), по `chat_id` или комбинированный `user_and_chat`.
12
+ - Динамический рассчет `wait_sec`: точное количество секунд, оставшихся до возобновления лимита.
13
+ - **Хранение состояний (Storage Backends)**:
14
+ - `In-Memory` (по умолчанию, с TTL-очисткой).
15
+ - Поддержка внешних бэкендов (Redis / `chutils.cache`) для распределенных Telegram-ботов.
16
+ - **Совместимость с фреймворками**:
17
+ - `TelegramThrottlingMiddleware` для `aiogram 3.x`.
18
+ - Синхронный и асинхронный декоратор `@tg_rate_limit` для `python-telegram-bot`, `telebot` и асинхронных хэндлеров.
19
+
20
+ ## Out of Scope
21
+ - Глобальное ограничение скорости ответа самого Telegram API (обработка HTTP 429 от Telegram сервера).
@@ -0,0 +1,5 @@
1
+ # Track telegram_send_file_20260729 Context
2
+
3
+ - [Specification](./spec.md)
4
+ - [Implementation Plan](./plan.md)
5
+ - [Metadata](./metadata.json)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "telegram_send_file_20260729",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-29T20:27:00Z",
6
+ "updated_at": "2026-07-29T20:27:00Z",
7
+ "description": "chutils.telegram.media: send_telegram_file для отправки локальных файлов/папок с авто-архивацией в ZIP и безопасным экранированием подписи"
8
+ }
@@ -0,0 +1,18 @@
1
+ # Implementation Plan: Telegram File Upload Helper (`telegram_send_file_20260729`)
2
+
3
+ ## Phase 1: Core send_telegram_file Implementation
4
+ - [ ] Task: Create `send_telegram_file` function in `chutils.telegram.media`
5
+ - [ ] Task: Integrate `resolve_safe_path` check and directory auto-zipping (`zip_folder`)
6
+ - [ ] Task: Implement safe caption formatting, 1024 char truncation, and 50MB file size limit check
7
+ - [ ] Task: Unit tests for path safety, directory auto-zipping, and caption truncation
8
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: Core File Upload Logic' (Protocol in workflow.md)
9
+
10
+ ## Phase 2: Framework Integrations & Lazy Exports
11
+ - [ ] Task: Support `aiogram 3.x` `Bot` sendDocument call and raw HTTP upload fallback
12
+ - [ ] Task: Export `send_telegram_file` in `src/chutils/telegram/__init__.py` and root `src/chutils/__init__.py`
13
+ - [ ] Task: Unit tests for framework compatibility and fallback mechanisms
14
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: Framework Integrations' (Protocol in workflow.md)
15
+
16
+ ## Phase 3: Documentation & Indexing
17
+ - [ ] Task: Add examples in `docs/` and update `api_map.md` / `project_index.json`
18
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Documentation' (Protocol in workflow.md)
@@ -0,0 +1,14 @@
1
+ # Track Specification: Telegram File Upload Helper (`telegram_send_file_20260729`)
2
+
3
+ ## Overview
4
+ Реализация функции `send_telegram_file` в подсистеме `chutils.telegram.media` для надежной и безопасной отправки локальных файлов и директорий из приложения в Telegram. Функция берет на себя защиту от Path Traversal, экранирование и обрезку подписей (`caption`), контроль лимитов размера Telegram API (50 МБ) и авто-упаковку папок в ZIP-архивы.
5
+
6
+ ## Functional Requirements
7
+ - **Функция `send_telegram_file`**:
8
+ - Аргументы: `bot`, `chat_id: int | str`, `file_path: str | Path`, `caption: str | None = None`, `parse_mode: str | None = None`, `allow_unsafe_path: bool = False`.
9
+ - Проверка безопасности пути через `chutils.fs.resolve_safe_path()` (с возможностью отключения через `allow_unsafe_path=True`).
10
+ - Авто-упаковка: если `file_path` указывает на папку, функция автоматически создает временный ZIP-архив через `chutils.fs.zip_folder` и отправляет его как файл.
11
+ - Обработка подписи (`caption`): безопасное экранирование спецсимволов и обрезка текста под 1024 символа (`smart_truncate`) во избежание вылетов по `BadRequest`.
12
+ - Проверка размера: проверка превышения лимита ботов Telegram (50 МБ) перед вызовом API.
13
+ - **Совместимость с фреймворками**:
14
+ - Поддержка экземпляров `Bot` (`aiogram 3.x`, `python-telegram-bot`) и отправка через прямой `HTTP POST` по `bot_token`.
@@ -0,0 +1,5 @@
1
+ # Track telegram_whitelist_20260729 Context
2
+
3
+ - [Specification](./spec.md)
4
+ - [Implementation Plan](./plan.md)
5
+ - [Metadata](./metadata.json)
@@ -0,0 +1,8 @@
1
+ {
2
+ "track_id": "telegram_whitelist_20260729",
3
+ "type": "feature",
4
+ "status": "new",
5
+ "created_at": "2026-07-29T00:07:00Z",
6
+ "updated_at": "2026-07-29T00:07:00Z",
7
+ "description": "SecretUserFilter: Разграничение прав по белым/черным спискам Telegram ID / хэндлов"
8
+ }
@@ -0,0 +1,17 @@
1
+ # Implementation Plan: Secret User & Access Whitelist/Blacklist Filter (`telegram_whitelist_20260729`)
2
+
3
+ ## Phase 1: Core Access List Engine & Decorator
4
+ - [ ] Task: Create `chutils.telegram.whitelist` module with `AccessListManager` class supporting allow/block lists and file persistence
5
+ - [ ] Task: Implement `@allowed_only` decorator with config fallback (`allowed_users`/`blocked_users`)
6
+ - [ ] Task: Unit tests for `AccessListManager` and `@allowed_only` decorator
7
+ - [ ] Task: Conductor - User Manual Verification 'Phase 1: Core Access List Engine' (Protocol in workflow.md)
8
+
9
+ ## Phase 2: aiogram Integration & Framework Support
10
+ - [ ] Task: Implement `SecretUserFilter` for `aiogram 3.x`
11
+ - [ ] Task: Export symbols in `src/chutils/telegram/__init__.py` and root `src/chutils/__init__.py`
12
+ - [ ] Task: Unit tests for `aiogram` filter and framework compatibility
13
+ - [ ] Task: Conductor - User Manual Verification 'Phase 2: aiogram Integration' (Protocol in workflow.md)
14
+
15
+ ## Phase 3: Documentation & Indexing
16
+ - [ ] Task: Add examples in `docs/` and update `api_map.md` / `project_index.json`
17
+ - [ ] Task: Conductor - User Manual Verification 'Phase 3: Documentation' (Protocol in workflow.md)
@@ -0,0 +1,19 @@
1
+ # Track Specification: Secret User & Access Whitelist/Blacklist Filter (`telegram_whitelist_20260729`)
2
+
3
+ ## Overview
4
+ Реализация специализированных фильтров белых и черных списков доступа для Telegram-ботов (`SecretUserFilter`, `@allowed_only`). Компонент позволяет ограничивать доступ к боту или конкретным фичам только определенной группе пользователей (по Telegram ID и @username), с поддержкой динамического пополнения/удаления записей и сохранения в файл/БД.
5
+
6
+ ## Functional Requirements
7
+ - **Класс `SecretUserFilter` & Декоратор `@allowed_only`**:
8
+ - Фильтрация по `allowed_ids` (int) и `allowed_usernames` (str).
9
+ - Настройка черного списка: `blocked_ids` / `blocked_usernames`.
10
+ - Автоматический fallback на конфигурацию `chutils`: `get_config_value("Telegram", "allowed_users")` / `blocked_users`.
11
+ - **Динамический менеджер списков (`AccessListManager`)**:
12
+ - Методы `allow_user(user_id_or_username)`, `block_user(user_id_or_username)`, `remove_user(...)`.
13
+ - Опциональное сохранение изменений в JSON-файл (`atomic_write`) или пользовательский провайдер.
14
+ - **Интеграции с фреймворками**:
15
+ - `SecretUserFilter` для `aiogram 3.x` (реализация `BaseFilter`).
16
+ - `@allowed_only` для `python-telegram-bot`, `telebot` и кастомных асинхронных хэндлеров.
17
+
18
+ ## Out of Scope
19
+ - Хранение сложных ролей и прав групп в СУБД (RBAC).