django-cfg 1.3.11__py3-none-any.whl → 1.4.0__py3-none-any.whl

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 (439) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/inlines.py +11 -5
  3. django_cfg/apps/accounts/admin/user_admin.py +39 -16
  4. django_cfg/apps/accounts/serializers/profile.py +1 -1
  5. django_cfg/apps/accounts/services/otp_service.py +18 -11
  6. django_cfg/apps/accounts/signals.py +15 -24
  7. django_cfg/apps/accounts/utils/notifications.py +217 -358
  8. django_cfg/apps/accounts/views/otp.py +2 -2
  9. django_cfg/apps/accounts/views/webhook.py +1 -1
  10. django_cfg/apps/agents/core/django_agent.py +1 -1
  11. django_cfg/apps/api/commands/views.py +66 -83
  12. django_cfg/apps/api/health/drf_views.py +269 -0
  13. django_cfg/apps/api/health/serializers.py +45 -0
  14. django_cfg/apps/api/health/urls.py +6 -1
  15. django_cfg/apps/knowbase/admin/actions/__init__.py +13 -0
  16. django_cfg/apps/knowbase/admin/actions/visibility_actions.py +56 -0
  17. django_cfg/apps/knowbase/admin/document_admin.py +136 -270
  18. django_cfg/apps/knowbase/admin/helpers/__init__.py +17 -0
  19. django_cfg/apps/knowbase/admin/helpers/configs.py +72 -0
  20. django_cfg/apps/knowbase/admin/helpers/display_helpers.py +156 -0
  21. django_cfg/apps/knowbase/admin/helpers/statistics.py +108 -0
  22. django_cfg/apps/knowbase/config/constance_fields.py +1 -1
  23. django_cfg/apps/knowbase/config/settings.py +2 -2
  24. django_cfg/apps/knowbase/mixins/__init__.py +19 -2
  25. django_cfg/apps/knowbase/mixins/config/__init__.py +14 -0
  26. django_cfg/apps/knowbase/mixins/config/defaults.py +75 -0
  27. django_cfg/apps/knowbase/mixins/config/meta_config.py +120 -0
  28. django_cfg/apps/knowbase/mixins/creator.py +10 -10
  29. django_cfg/apps/knowbase/mixins/external_data_mixin.py +105 -403
  30. django_cfg/apps/knowbase/mixins/generators/__init__.py +16 -0
  31. django_cfg/apps/knowbase/mixins/generators/content_generator.py +218 -0
  32. django_cfg/apps/knowbase/mixins/generators/field_analyzer.py +76 -0
  33. django_cfg/apps/knowbase/mixins/generators/metadata_generator.py +124 -0
  34. django_cfg/apps/knowbase/mixins/service.py +2 -2
  35. django_cfg/apps/knowbase/services/archive/__init__.py +1 -0
  36. django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +17 -0
  37. django_cfg/apps/knowbase/services/archive/analyzers/complexity_analyzer.py +33 -0
  38. django_cfg/apps/knowbase/services/archive/analyzers/purpose_detector.py +36 -0
  39. django_cfg/apps/knowbase/services/archive/analyzers/quality_analyzer.py +39 -0
  40. django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +103 -0
  41. django_cfg/apps/knowbase/services/archive/chunking/__init__.py +19 -0
  42. django_cfg/apps/knowbase/services/archive/chunking/base.py +81 -0
  43. django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +62 -0
  44. django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +107 -0
  45. django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +248 -0
  46. django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +70 -0
  47. django_cfg/apps/knowbase/services/archive/chunking_service.py +110 -729
  48. django_cfg/apps/knowbase/services/archive/context/__init__.py +14 -0
  49. django_cfg/apps/knowbase/services/archive/context/builders.py +220 -0
  50. django_cfg/apps/knowbase/services/archive/context/models.py +38 -0
  51. django_cfg/apps/knowbase/services/embedding/models.py +18 -14
  52. django_cfg/apps/knowbase/services/embedding/processors.py +6 -3
  53. django_cfg/apps/knowbase/tasks/document_processing.py +11 -3
  54. django_cfg/apps/leads/tests.py +1 -1
  55. django_cfg/apps/payments/admin/api_keys_admin.py +1 -1
  56. django_cfg/apps/payments/admin/balance_admin.py +1 -1
  57. django_cfg/apps/payments/admin/currencies_admin.py +1 -1
  58. django_cfg/apps/payments/admin/payments_admin.py +1 -1
  59. django_cfg/apps/payments/admin/subscriptions_admin.py +1 -1
  60. django_cfg/apps/payments/admin_interface/templates/payments/base.html +59 -126
  61. django_cfg/apps/payments/admin_interface/views/api/payments.py +1 -1
  62. django_cfg/apps/payments/admin_interface/views/api/stats.py +1 -1
  63. django_cfg/apps/payments/admin_interface/views/api/users.py +1 -1
  64. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +1 -1
  65. django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +1 -1
  66. django_cfg/apps/payments/admin_interface/views/base.py +29 -2
  67. django_cfg/apps/payments/apps.py +1 -1
  68. django_cfg/apps/payments/config/django_cfg_integration.py +2 -2
  69. django_cfg/apps/payments/config/helpers.py +3 -2
  70. django_cfg/apps/payments/management/commands/cleanup_expired_data.py +1 -1
  71. django_cfg/apps/payments/management/commands/currency_stats.py +1 -1
  72. django_cfg/apps/payments/management/commands/manage_currencies.py +1 -1
  73. django_cfg/apps/payments/management/commands/manage_providers.py +1 -1
  74. django_cfg/apps/payments/management/commands/process_pending_payments.py +1 -1
  75. django_cfg/apps/payments/management/commands/test_providers.py +1 -1
  76. django_cfg/apps/payments/middleware/api_access.py +1 -1
  77. django_cfg/apps/payments/middleware/rate_limiting.py +1 -1
  78. django_cfg/apps/payments/middleware/usage_tracking.py +1 -1
  79. django_cfg/apps/payments/models/balance.py +2 -2
  80. django_cfg/apps/payments/models/managers/api_key_managers.py +1 -1
  81. django_cfg/apps/payments/models/managers/balance_managers.py +1 -1
  82. django_cfg/apps/payments/models/managers/currency_managers.py +1 -1
  83. django_cfg/apps/payments/models/managers/payment_managers.py +1 -1
  84. django_cfg/apps/payments/models/managers/subscription_managers.py +1 -1
  85. django_cfg/apps/payments/models/payments.py +2 -2
  86. django_cfg/apps/payments/services/cache_service/__init__.py +1 -1
  87. django_cfg/apps/payments/services/cache_service/simple_cache.py +10 -5
  88. django_cfg/apps/payments/services/core/base.py +1 -1
  89. django_cfg/apps/payments/services/core/currency/__init__.py +13 -0
  90. django_cfg/apps/payments/services/core/currency/currency_converter.py +57 -0
  91. django_cfg/apps/payments/services/core/currency/currency_validator.py +61 -0
  92. django_cfg/apps/payments/services/core/operations/__init__.py +15 -0
  93. django_cfg/apps/payments/services/core/operations/payment_canceller.py +100 -0
  94. django_cfg/apps/payments/services/core/operations/payment_creator.py +196 -0
  95. django_cfg/apps/payments/services/core/operations/status_checker.py +100 -0
  96. django_cfg/apps/payments/services/core/payment_service.py +124 -612
  97. django_cfg/apps/payments/services/core/providers/__init__.py +13 -0
  98. django_cfg/apps/payments/services/core/providers/provider_client.py +132 -0
  99. django_cfg/apps/payments/services/core/providers/status_mapper.py +89 -0
  100. django_cfg/apps/payments/services/core/utils/__init__.py +13 -0
  101. django_cfg/apps/payments/services/core/utils/data_converter.py +48 -0
  102. django_cfg/apps/payments/services/core/utils/statistics_calculator.py +69 -0
  103. django_cfg/apps/payments/services/providers/base.py +1 -1
  104. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +3 -3
  105. django_cfg/apps/payments/services/providers/nowpayments/parsers/__init__.py +9 -0
  106. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +23 -0
  107. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/constants.py +23 -0
  108. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/currency_names.py +244 -0
  109. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +511 -0
  110. django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +168 -0
  111. django_cfg/apps/payments/services/providers/nowpayments/provider.py +1 -1
  112. django_cfg/apps/payments/services/providers/nowpayments/sync.py +1 -1
  113. django_cfg/apps/payments/services/providers/registry.py +1 -1
  114. django_cfg/apps/payments/services/providers/sync_service.py +1 -1
  115. django_cfg/apps/payments/signals/__init__.py +1 -1
  116. django_cfg/apps/payments/signals/api_key_signals.py +1 -1
  117. django_cfg/apps/payments/signals/balance_signals.py +1 -1
  118. django_cfg/apps/payments/signals/payment_signals.py +1 -1
  119. django_cfg/apps/payments/signals/subscription_signals.py +1 -1
  120. django_cfg/apps/payments/views/api/api_keys.py +1 -1
  121. django_cfg/apps/payments/views/api/balances.py +1 -1
  122. django_cfg/apps/payments/views/api/base.py +1 -1
  123. django_cfg/apps/payments/views/api/currencies.py +1 -1
  124. django_cfg/apps/payments/views/api/payments.py +1 -1
  125. django_cfg/apps/payments/views/api/subscriptions.py +1 -1
  126. django_cfg/apps/payments/views/api/webhooks.py +1 -1
  127. django_cfg/apps/payments/views/serializers/api_keys.py +1 -1
  128. django_cfg/apps/payments/views/serializers/balances.py +1 -1
  129. django_cfg/apps/payments/views/serializers/currencies.py +1 -1
  130. django_cfg/apps/payments/views/serializers/payments.py +1 -1
  131. django_cfg/apps/payments/views/serializers/subscriptions.py +1 -1
  132. django_cfg/apps/payments/views/serializers/webhooks.py +1 -1
  133. django_cfg/apps/support/admin/support_admin.py +21 -13
  134. django_cfg/apps/support/templates/support/chat/access_denied.html +21 -27
  135. django_cfg/apps/support/templates/support/chat/ticket_chat.html +183 -254
  136. django_cfg/apps/support/utils/support_email_service.py +1 -1
  137. django_cfg/apps/tasks/templates/tasks/layout/base.html +20 -115
  138. django_cfg/apps/tasks/utils/simulator.py +1 -1
  139. django_cfg/apps/tasks/views/dashboard.py +33 -3
  140. django_cfg/apps/urls.py +5 -1
  141. django_cfg/cli/README.md +57 -471
  142. django_cfg/cli/commands/create_project.py +140 -529
  143. django_cfg/cli/main.py +13 -10
  144. django_cfg/core/__init__.py +63 -6
  145. django_cfg/core/base/__init__.py +5 -0
  146. django_cfg/core/base/config_model.py +652 -0
  147. django_cfg/core/builders/__init__.py +11 -0
  148. django_cfg/core/builders/apps_builder.py +258 -0
  149. django_cfg/core/builders/middleware_builder.py +115 -0
  150. django_cfg/core/builders/security_builder.py +96 -0
  151. django_cfg/core/config.py +20 -892
  152. django_cfg/core/constants.py +69 -0
  153. django_cfg/core/environment/__init__.py +9 -0
  154. django_cfg/core/exceptions.py +45 -298
  155. django_cfg/core/generation/__init__.py +51 -0
  156. django_cfg/core/generation/core_generators/__init__.py +0 -0
  157. django_cfg/core/generation/core_generators/settings.py +90 -0
  158. django_cfg/core/generation/core_generators/static.py +82 -0
  159. django_cfg/core/generation/core_generators/templates.py +141 -0
  160. django_cfg/core/generation/data_generators/__init__.py +15 -0
  161. django_cfg/core/generation/data_generators/cache.py +132 -0
  162. django_cfg/core/generation/data_generators/database.py +117 -0
  163. django_cfg/core/generation/generation.py +92 -0
  164. django_cfg/core/generation/integration_generators/__init__.py +21 -0
  165. django_cfg/core/generation/integration_generators/api.py +237 -0
  166. django_cfg/core/generation/integration_generators/sessions.py +65 -0
  167. django_cfg/core/generation/integration_generators/tailwind.py +54 -0
  168. django_cfg/core/generation/integration_generators/tasks.py +92 -0
  169. django_cfg/core/generation/integration_generators/third_party.py +144 -0
  170. django_cfg/core/generation/orchestrator.py +285 -0
  171. django_cfg/core/generation/protocols.py +30 -0
  172. django_cfg/core/generation/security_generators/__init__.py +0 -0
  173. django_cfg/core/generation/utility_generators/__init__.py +24 -0
  174. django_cfg/core/generation/utility_generators/email.py +58 -0
  175. django_cfg/core/generation/utility_generators/i18n.py +66 -0
  176. django_cfg/core/generation/utility_generators/limits.py +58 -0
  177. django_cfg/core/generation/utility_generators/logging.py +66 -0
  178. django_cfg/core/generation/utility_generators/security.py +101 -0
  179. django_cfg/core/generation/utils/__init__.py +0 -0
  180. django_cfg/core/generation/utils/helpers.py +32 -0
  181. django_cfg/core/integration/__init__.py +18 -25
  182. django_cfg/core/integration/display/startup.py +146 -133
  183. django_cfg/core/integration/url_integration.py +13 -2
  184. django_cfg/core/services/__init__.py +5 -0
  185. django_cfg/core/services/config_service.py +121 -0
  186. django_cfg/core/state/__init__.py +9 -0
  187. django_cfg/core/state/registry.py +84 -0
  188. django_cfg/core/types/__init__.py +15 -0
  189. django_cfg/core/types/aliases.py +15 -0
  190. django_cfg/core/types/enums.py +49 -0
  191. django_cfg/dashboard/DEBUG_README.md +105 -0
  192. django_cfg/dashboard/REFACTORING_SUMMARY.md +237 -0
  193. django_cfg/dashboard/__init__.py +24 -0
  194. django_cfg/dashboard/components.py +308 -0
  195. django_cfg/dashboard/debug.py +176 -0
  196. django_cfg/dashboard/management/__init__.py +0 -0
  197. django_cfg/dashboard/management/commands/__init__.py +0 -0
  198. django_cfg/dashboard/management/commands/debug_dashboard.py +109 -0
  199. django_cfg/dashboard/sections/__init__.py +1 -0
  200. django_cfg/dashboard/sections/base.py +128 -0
  201. django_cfg/dashboard/sections/commands.py +32 -0
  202. django_cfg/dashboard/sections/overview.py +394 -0
  203. django_cfg/dashboard/sections/stats.py +48 -0
  204. django_cfg/dashboard/sections/system.py +73 -0
  205. django_cfg/management/commands/check_settings.py +6 -2
  206. django_cfg/management/commands/clear_constance.py +6 -1
  207. django_cfg/management/commands/create_token.py +5 -4
  208. django_cfg/management/commands/generate.py +5 -0
  209. django_cfg/management/commands/list_urls.py +7 -2
  210. django_cfg/management/commands/migrate_all.py +6 -2
  211. django_cfg/management/commands/migrator.py +6 -1
  212. django_cfg/management/commands/rundramatiq.py +6 -1
  213. django_cfg/management/commands/rundramatiq_simulator.py +11 -4
  214. django_cfg/management/commands/runserver_ngrok.py +9 -7
  215. django_cfg/management/commands/script.py +25 -21
  216. django_cfg/management/commands/show_config.py +6 -1
  217. django_cfg/management/commands/show_urls.py +8 -3
  218. django_cfg/management/commands/superuser.py +5 -4
  219. django_cfg/management/commands/task_clear.py +8 -3
  220. django_cfg/management/commands/task_status.py +8 -3
  221. django_cfg/management/commands/test_email.py +6 -1
  222. django_cfg/management/commands/test_telegram.py +6 -1
  223. django_cfg/management/commands/test_twilio.py +6 -1
  224. django_cfg/management/commands/tree.py +7 -4
  225. django_cfg/models/__init__.py +88 -3
  226. django_cfg/models/api/__init__.py +27 -0
  227. django_cfg/models/{api.py → api/config.py} +1 -1
  228. django_cfg/models/api/drf/__init__.py +21 -0
  229. django_cfg/models/api/drf/config.py +101 -0
  230. django_cfg/models/api/drf/redoc.py +31 -0
  231. django_cfg/models/api/drf/spectacular.py +129 -0
  232. django_cfg/models/api/drf/swagger.py +59 -0
  233. django_cfg/models/{api_keys.py → api/keys.py} +16 -6
  234. django_cfg/models/{limits.py → api/limits.py} +0 -1
  235. django_cfg/models/base/__init__.py +14 -0
  236. django_cfg/models/django/__init__.py +16 -0
  237. django_cfg/models/{constance.py → django/constance.py} +1 -1
  238. django_cfg/models/{environment.py → django/environment.py} +1 -1
  239. django_cfg/models/infrastructure/__init__.py +17 -0
  240. django_cfg/models/{cache.py → infrastructure/cache.py} +3 -2
  241. django_cfg/models/infrastructure/database/__init__.py +22 -0
  242. django_cfg/models/infrastructure/database/config.py +265 -0
  243. django_cfg/models/infrastructure/database/converters.py +91 -0
  244. django_cfg/models/infrastructure/database/parsers.py +96 -0
  245. django_cfg/models/infrastructure/database/routing.py +85 -0
  246. django_cfg/models/infrastructure/database/validators.py +170 -0
  247. django_cfg/models/{logging.py → infrastructure/logging.py} +1 -1
  248. django_cfg/models/{security.py → infrastructure/security.py} +2 -2
  249. django_cfg/models/ngrok/__init__.py +11 -0
  250. django_cfg/models/ngrok/auth.py +37 -0
  251. django_cfg/models/ngrok/config.py +77 -0
  252. django_cfg/models/ngrok/tunnel.py +35 -0
  253. django_cfg/models/payments/__init__.py +20 -0
  254. django_cfg/models/payments/api_keys.py +57 -0
  255. django_cfg/models/{payments.py → payments/config.py} +56 -154
  256. django_cfg/models/payments/providers/__init__.py +15 -0
  257. django_cfg/models/payments/providers/base.py +25 -0
  258. django_cfg/models/payments/providers/nowpayments.py +48 -0
  259. django_cfg/models/services/__init__.py +18 -0
  260. django_cfg/models/services/base.py +65 -0
  261. django_cfg/models/{email.py → services/email.py} +1 -1
  262. django_cfg/models/services/telegram.py +172 -0
  263. django_cfg/models/tasks/__init__.py +51 -0
  264. django_cfg/models/tasks/backends.py +250 -0
  265. django_cfg/models/tasks/config.py +314 -0
  266. django_cfg/models/tasks/utils.py +174 -0
  267. django_cfg/modules/base.py +18 -3
  268. django_cfg/modules/django_admin/decorators/actions.py +1 -1
  269. django_cfg/modules/django_admin/decorators/display.py +1 -1
  270. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +1 -1
  271. django_cfg/modules/django_cfg_rpc_client/README.md +346 -0
  272. django_cfg/modules/django_cfg_rpc_client/__init__.py +51 -0
  273. django_cfg/modules/django_cfg_rpc_client/client.py +540 -0
  274. django_cfg/modules/django_cfg_rpc_client/config.py +207 -0
  275. django_cfg/modules/django_cfg_rpc_client/dashboard/README.md +517 -0
  276. django_cfg/modules/django_cfg_rpc_client/dashboard/UNFOLD_INTEGRATION.md +439 -0
  277. django_cfg/modules/django_cfg_rpc_client/dashboard/__init__.py +11 -0
  278. django_cfg/modules/django_cfg_rpc_client/dashboard/apps.py +22 -0
  279. django_cfg/modules/django_cfg_rpc_client/dashboard/monitor.py +435 -0
  280. django_cfg/modules/django_cfg_rpc_client/dashboard/static/django_cfg_rpc_dashboard/js/dashboard.js +373 -0
  281. django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/base.html +76 -0
  282. django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/dashboard.html +200 -0
  283. django_cfg/modules/django_cfg_rpc_client/dashboard/urls.py +22 -0
  284. django_cfg/modules/django_cfg_rpc_client/dashboard/urls_admin.py +9 -0
  285. django_cfg/modules/django_cfg_rpc_client/dashboard/views.py +251 -0
  286. django_cfg/modules/django_cfg_rpc_client/exceptions.py +201 -0
  287. django_cfg/modules/django_drf_theme/CHANGELOG.md +210 -0
  288. django_cfg/modules/django_drf_theme/EXAMPLE.md +465 -0
  289. django_cfg/modules/django_drf_theme/IMPLEMENTATION.md +232 -0
  290. django_cfg/modules/django_drf_theme/README.md +207 -0
  291. django_cfg/modules/django_drf_theme/TAILWIND_CDN_GUIDE.md +274 -0
  292. django_cfg/modules/django_drf_theme/__init__.py +23 -0
  293. django_cfg/modules/django_drf_theme/apps.py +15 -0
  294. django_cfg/modules/django_drf_theme/renderers.py +58 -0
  295. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/api.html +375 -0
  296. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/base.html +938 -0
  297. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/filter_form.html +132 -0
  298. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/raw_data_form.html +123 -0
  299. django_cfg/modules/django_drf_theme/templatetags/__init__.py +1 -0
  300. django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +57 -0
  301. django_cfg/modules/django_email/__init__.py +14 -0
  302. django_cfg/modules/{django_email.py → django_email/service.py} +78 -113
  303. django_cfg/modules/django_email/utils.py +40 -0
  304. django_cfg/modules/django_health/__init__.py +9 -0
  305. django_cfg/modules/{django_health.py → django_health/service.py} +23 -21
  306. django_cfg/modules/django_llm/llm/client.py +155 -550
  307. django_cfg/modules/django_llm/llm/embeddings/__init__.py +13 -0
  308. django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +106 -0
  309. django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +79 -0
  310. django_cfg/modules/django_llm/llm/models_api/__init__.py +9 -0
  311. django_cfg/modules/django_llm/llm/models_api/models_query.py +163 -0
  312. django_cfg/modules/django_llm/llm/providers/__init__.py +15 -0
  313. django_cfg/modules/django_llm/llm/providers/config_builder.py +103 -0
  314. django_cfg/modules/django_llm/llm/providers/provider_manager.py +148 -0
  315. django_cfg/modules/django_llm/llm/providers/provider_selector.py +60 -0
  316. django_cfg/modules/django_llm/llm/requests/__init__.py +15 -0
  317. django_cfg/modules/django_llm/llm/requests/cache_manager.py +170 -0
  318. django_cfg/modules/django_llm/llm/requests/chat_handler.py +199 -0
  319. django_cfg/modules/django_llm/llm/requests/embedding_handler.py +113 -0
  320. django_cfg/modules/django_llm/llm/responses/__init__.py +9 -0
  321. django_cfg/modules/django_llm/llm/responses/response_builder.py +131 -0
  322. django_cfg/modules/django_llm/llm/stats/__init__.py +9 -0
  323. django_cfg/modules/django_llm/llm/stats/stats_manager.py +107 -0
  324. django_cfg/modules/django_llm/translator/detectors/__init__.py +13 -0
  325. django_cfg/modules/django_llm/translator/detectors/language_detector.py +90 -0
  326. django_cfg/modules/django_llm/translator/detectors/script_detector.py +153 -0
  327. django_cfg/modules/django_llm/translator/stats/__init__.py +11 -0
  328. django_cfg/modules/django_llm/translator/stats/stats_tracker.py +85 -0
  329. django_cfg/modules/django_llm/translator/translator.py +150 -603
  330. django_cfg/modules/django_llm/translator/translators/__init__.py +15 -0
  331. django_cfg/modules/django_llm/translator/translators/json_translator.py +316 -0
  332. django_cfg/modules/django_llm/translator/translators/text_translator.py +139 -0
  333. django_cfg/modules/django_llm/translator/utils/__init__.py +13 -0
  334. django_cfg/modules/django_llm/translator/utils/prompt_builder.py +110 -0
  335. django_cfg/modules/django_llm/translator/utils/text_utils.py +114 -0
  336. django_cfg/modules/django_logging/FIXES_SUMMARY.md +276 -0
  337. django_cfg/modules/django_logging/LOGGING_GUIDE.md +504 -0
  338. django_cfg/modules/django_logging/__init__.py +14 -0
  339. django_cfg/modules/{django_logger.py → django_logging/django_logger.py} +13 -13
  340. django_cfg/modules/{logger.py → django_logging/logger.py} +14 -4
  341. django_cfg/modules/django_ngrok/__init__.py +39 -0
  342. django_cfg/modules/{django_ngrok.py → django_ngrok/service.py} +14 -42
  343. django_cfg/modules/django_rpc_old/POETRY.md +344 -0
  344. django_cfg/modules/django_rpc_old/README.md +397 -0
  345. django_cfg/modules/django_rpc_old/TESTING.md +358 -0
  346. django_cfg/modules/django_rpc_old/__init__.py +39 -0
  347. django_cfg/modules/django_rpc_old/client.py +531 -0
  348. django_cfg/modules/django_rpc_old/config.py +279 -0
  349. django_cfg/modules/django_rpc_old/exceptions.py +172 -0
  350. django_cfg/modules/django_tailwind/README.md +478 -0
  351. django_cfg/modules/django_tailwind/__init__.py +7 -0
  352. django_cfg/modules/django_tailwind/apps.py +10 -0
  353. django_cfg/modules/django_tailwind/templates/django_tailwind/app.html +5 -0
  354. django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +117 -0
  355. django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +124 -0
  356. django_cfg/modules/django_tailwind/templates/django_tailwind/components/theme_toggle.html +54 -0
  357. django_cfg/modules/django_tailwind/templates/django_tailwind/components/user_menu.html +116 -0
  358. django_cfg/modules/django_tailwind/templates/django_tailwind/simple.html +46 -0
  359. django_cfg/modules/django_tailwind/templatetags/__init__.py +1 -0
  360. django_cfg/modules/django_tailwind/templatetags/tailwind_info.py +185 -0
  361. django_cfg/modules/django_tasks/__init__.py +29 -0
  362. django_cfg/modules/django_tasks/factory.py +127 -0
  363. django_cfg/modules/{django_tasks.py → django_tasks/service.py} +45 -274
  364. django_cfg/modules/django_tasks/settings.py +107 -0
  365. django_cfg/modules/django_telegram/__init__.py +29 -0
  366. django_cfg/modules/{django_telegram.py → django_telegram/service.py} +45 -113
  367. django_cfg/modules/django_telegram/utils.py +62 -0
  368. django_cfg/modules/django_twilio/__init__.py +54 -107
  369. django_cfg/modules/django_twilio/_imports.py +30 -0
  370. django_cfg/modules/django_twilio/base.py +192 -0
  371. django_cfg/modules/django_twilio/email_otp.py +227 -0
  372. django_cfg/modules/django_twilio/sendgrid_service.py +1 -1
  373. django_cfg/modules/django_twilio/simple_service.py +1 -2
  374. django_cfg/modules/django_twilio/sms.py +94 -0
  375. django_cfg/modules/django_twilio/twilio_service.py +2 -3
  376. django_cfg/modules/django_twilio/unified.py +310 -0
  377. django_cfg/modules/django_twilio/utils.py +190 -0
  378. django_cfg/modules/django_twilio/whatsapp.py +137 -0
  379. django_cfg/modules/django_unfold/callbacks/base.py +198 -7
  380. django_cfg/modules/django_unfold/callbacks/main.py +102 -10
  381. django_cfg/modules/django_unfold/dashboard.py +65 -43
  382. django_cfg/modules/django_unfold/models/config.py +13 -12
  383. django_cfg/modules/django_unfold/models/navigation.py +8 -3
  384. django_cfg/modules/django_unfold/models/tabs.py +2 -2
  385. django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +102 -0
  386. django_cfg/registry/core.py +24 -26
  387. django_cfg/registry/modules.py +5 -2
  388. django_cfg/registry/services.py +20 -3
  389. django_cfg/registry/third_party.py +8 -8
  390. django_cfg/static/admin/css/dashboard.css +260 -0
  391. django_cfg/static/admin/js/commands.js +171 -0
  392. django_cfg/static/admin/js/dashboard.js +126 -0
  393. django_cfg/templates/admin/components/management_commands.js +375 -0
  394. django_cfg/templates/admin/components/progress_bar.html +18 -23
  395. django_cfg/templates/admin/index.html +48 -20
  396. django_cfg/templates/admin/index_new.html +106 -0
  397. django_cfg/templates/admin/layouts/base_dashboard.html +60 -0
  398. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +1 -20
  399. django_cfg/templates/admin/sections/commands_section.html +626 -0
  400. django_cfg/templates/admin/sections/overview_section.html +112 -0
  401. django_cfg/templates/admin/sections/stats_section.html +35 -0
  402. django_cfg/templates/admin/sections/system_section.html +99 -0
  403. django_cfg/templates/admin/snippets/components/CHARTS_GUIDE.md +322 -0
  404. django_cfg/templates/admin/snippets/components/activity_tracker.html +85 -47
  405. django_cfg/templates/admin/snippets/components/charts_section.html +154 -64
  406. django_cfg/templates/admin/snippets/components/django_commands.html +3 -3
  407. django_cfg/templates/admin/snippets/components/recent_activity_improved.html +25 -0
  408. django_cfg/templates/admin/snippets/components/recent_users_table.html +1 -1
  409. django_cfg/templates/admin/snippets/components/system_metrics.html +179 -93
  410. django_cfg/templates/admin/snippets/zones/zones_table.html +2 -2
  411. django_cfg/templatetags/django_cfg.py +7 -1
  412. django_cfg/utils/smart_defaults.py +4 -4
  413. django_cfg-1.4.0.dist-info/METADATA +920 -0
  414. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/RECORD +425 -196
  415. django_cfg/apps/accounts/utils/auth_email_service.py +0 -84
  416. django_cfg/apps/payments/services/providers/nowpayments/parsers.py +0 -879
  417. django_cfg/core/generation.py +0 -621
  418. django_cfg/management/commands/validate_config.py +0 -189
  419. django_cfg/models/database.py +0 -480
  420. django_cfg/models/drf.py +0 -272
  421. django_cfg/models/ngrok.py +0 -122
  422. django_cfg/models/services.py +0 -440
  423. django_cfg/models/tasks.py +0 -550
  424. django_cfg/modules/django_twilio/service.py +0 -942
  425. django_cfg/template_archive/django_sample.zip +0 -0
  426. django_cfg/templates/rest_framework/api.html +0 -12
  427. django_cfg/utils/toolkit.py +0 -703
  428. django_cfg-1.3.11.dist-info/METADATA +0 -1029
  429. /django_cfg/apps/accounts/management/commands/{test_otp.py → otp_test.py} +0 -0
  430. /django_cfg/core/{environment.py → environment/detector.py} +0 -0
  431. /django_cfg/models/{cors.py → api/cors.py} +0 -0
  432. /django_cfg/models/{jwt.py → api/jwt.py} +0 -0
  433. /django_cfg/models/{base.py → base/config.py} +0 -0
  434. /django_cfg/models/{cfg.py → base/module.py} +0 -0
  435. /django_cfg/models/{revolution.py → django/revolution.py} +0 -0
  436. /django_cfg/modules/{dramatiq_setup.py → django_tasks/dramatiq_setup.py} +0 -0
  437. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/WHEEL +0 -0
  438. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/entry_points.txt +0 -0
  439. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Django CFG Commands JavaScript
3
+ *
4
+ * Handles command execution and modal interactions
5
+ */
6
+
7
+ class CommandExecutor {
8
+ constructor() {
9
+ this.modal = document.getElementById('commandModal');
10
+ this.commandNameEl = document.getElementById('commandName');
11
+ this.commandOutput = document.getElementById('commandOutput');
12
+ this.commandStatus = document.getElementById('commandStatus');
13
+ }
14
+
15
+ execute(commandName) {
16
+ if (!this.modal || !this.commandNameEl || !this.commandOutput || !this.commandStatus) {
17
+ console.error('Command modal elements not found');
18
+ return;
19
+ }
20
+
21
+ this.commandNameEl.textContent = commandName;
22
+ this.commandOutput.textContent = '';
23
+ this.commandStatus.innerHTML = '<div class="w-3 h-3 bg-yellow-500 rounded-full mr-2 animate-pulse"></div><span class="text-sm font-medium text-gray-700 dark:text-gray-300">Executing...</span>';
24
+ this.modal.classList.remove('hidden');
25
+
26
+ fetch('/cfg/commands/execute/', {
27
+ method: 'POST',
28
+ headers: {
29
+ 'Content-Type': 'application/json',
30
+ 'X-CSRFToken': getCookie('csrftoken')
31
+ },
32
+ body: JSON.stringify({
33
+ command: commandName,
34
+ args: [],
35
+ options: {}
36
+ })
37
+ })
38
+ .then(response => {
39
+ if (!response.ok) {
40
+ throw new Error(`HTTP error! status: ${response.status}`);
41
+ }
42
+
43
+ const reader = response.body.getReader();
44
+ const decoder = new TextDecoder();
45
+
46
+ const readStream = () => {
47
+ return reader.read().then(({done, value}) => {
48
+ if (done) return;
49
+
50
+ const chunk = decoder.decode(value);
51
+ const lines = chunk.split('\n');
52
+
53
+ lines.forEach(line => {
54
+ if (line.startsWith('data: ')) {
55
+ try {
56
+ const data = JSON.parse(line.slice(6));
57
+ this.handleCommandData(data);
58
+ } catch (e) {
59
+ console.error('Error parsing command data:', e);
60
+ }
61
+ }
62
+ });
63
+
64
+ return readStream();
65
+ });
66
+ };
67
+
68
+ return readStream();
69
+ })
70
+ .catch(error => {
71
+ console.error('Error executing command:', error);
72
+ this.commandOutput.textContent += `\n❌ Error: ${error.message}`;
73
+ this.commandStatus.innerHTML = '<div class="w-3 h-3 bg-red-500 rounded-full mr-2"></div><span class="text-sm font-medium text-red-600 dark:text-red-400">Error</span>';
74
+ });
75
+ }
76
+
77
+ handleCommandData(data) {
78
+ switch (data.type) {
79
+ case 'start':
80
+ this.commandOutput.innerHTML = '';
81
+ this.addLogLine(`🚀 Starting command: ${data.command}`, 'info');
82
+ this.addLogLine(`📝 Arguments: ${data.args.join(' ')}`, 'info');
83
+ this.addLogLine('', 'spacer');
84
+ this.commandStatus.innerHTML = '<div class="w-3 h-3 bg-yellow-500 rounded-full mr-2 animate-pulse"></div><span class="text-sm font-medium text-gray-700 dark:text-gray-300">Executing...</span>';
85
+ break;
86
+ case 'output':
87
+ this.addLogLine(data.line, 'output');
88
+ this.scrollToBottom();
89
+ break;
90
+ case 'complete':
91
+ const success = data.return_code === 0;
92
+ this.commandStatus.innerHTML = success
93
+ ? '<div class="w-3 h-3 bg-green-500 rounded-full mr-2"></div><span class="text-sm font-medium text-green-600 dark:text-green-400">Completed</span>'
94
+ : '<div class="w-3 h-3 bg-red-500 rounded-full mr-2"></div><span class="text-sm font-medium text-red-600 dark:text-red-400">Failed</span>';
95
+
96
+ this.addLogLine('', 'spacer');
97
+ let completionMessage = `${success ? '✅' : '❌'} Command completed with exit code: ${data.return_code}`;
98
+ if (data.execution_time) {
99
+ completionMessage += ` (${data.execution_time}s)`;
100
+ }
101
+ this.addLogLine(completionMessage, success ? 'success' : 'error');
102
+ this.scrollToBottom();
103
+ break;
104
+ case 'error':
105
+ this.addLogLine(`❌ Error: ${data.error}`, 'error');
106
+ this.commandStatus.innerHTML = '<div class="w-3 h-3 bg-red-500 rounded-full mr-2"></div><span class="text-sm font-medium text-red-600 dark:text-red-400">Error</span>';
107
+ this.scrollToBottom();
108
+ break;
109
+ }
110
+ }
111
+
112
+ addLogLine(text, type = 'output') {
113
+ const line = document.createElement('div');
114
+ line.className = 'log-line';
115
+
116
+ switch (type) {
117
+ case 'info':
118
+ line.className += ' text-blue-600 dark:text-blue-400 font-medium';
119
+ break;
120
+ case 'success':
121
+ line.className += ' text-green-600 dark:text-green-400 font-medium';
122
+ break;
123
+ case 'error':
124
+ line.className += ' text-red-600 dark:text-red-400 font-medium';
125
+ break;
126
+ case 'spacer':
127
+ line.className += ' h-2';
128
+ break;
129
+ default:
130
+ line.className += ' text-gray-700 dark:text-gray-300';
131
+ }
132
+
133
+ if (type === 'spacer') {
134
+ line.innerHTML = '&nbsp;';
135
+ } else {
136
+ line.textContent = text;
137
+ }
138
+
139
+ this.commandOutput.appendChild(line);
140
+ }
141
+
142
+ scrollToBottom() {
143
+ if (!this.commandOutput) return;
144
+
145
+ setTimeout(() => {
146
+ this.commandOutput.scrollTop = this.commandOutput.scrollHeight;
147
+ }, 50);
148
+ }
149
+
150
+ close() {
151
+ if (this.modal) {
152
+ this.modal.classList.add('hidden');
153
+ }
154
+ }
155
+ }
156
+
157
+ // Global functions
158
+ function executeCommand(commandName) {
159
+ const executor = new CommandExecutor();
160
+ executor.execute(commandName);
161
+ }
162
+
163
+ function closeCommandModal() {
164
+ const executor = new CommandExecutor();
165
+ executor.close();
166
+ }
167
+
168
+ // Export
169
+ window.CommandExecutor = CommandExecutor;
170
+ window.executeCommand = executeCommand;
171
+ window.closeCommandModal = closeCommandModal;
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Django CFG Dashboard JavaScript
3
+ *
4
+ * Handles dashboard tabs, navigation, and interactions
5
+ */
6
+
7
+ // Tab Management
8
+ class DashboardTabs {
9
+ constructor() {
10
+ this.tabs = document.querySelectorAll('#dashboard-tabs button');
11
+ this.contents = document.querySelectorAll('.tab-content');
12
+ this.tabNames = ['overview', 'zones', 'users', 'system', 'stats', 'app-stats', 'commands'];
13
+ this.init();
14
+ }
15
+
16
+ init() {
17
+ if (!this.tabs.length || !this.contents.length) return;
18
+
19
+ // Add click handlers
20
+ this.tabs.forEach((tab, idx) => {
21
+ tab.onclick = (e) => {
22
+ e.preventDefault();
23
+ this.switchTab(idx, true);
24
+ };
25
+ });
26
+
27
+ // Handle browser back/forward
28
+ window.addEventListener('hashchange', () => {
29
+ const tabIndex = this.getTabFromHash();
30
+ this.switchTab(tabIndex, false);
31
+ });
32
+
33
+ // Activate initial tab
34
+ const initialTab = this.getTabFromHash();
35
+ this.switchTab(initialTab, false);
36
+ }
37
+
38
+ switchTab(idx, updateHash = true) {
39
+ this.tabs.forEach((t, i) => {
40
+ if (i === idx) {
41
+ t.classList.add('active');
42
+ } else {
43
+ t.classList.remove('active');
44
+ }
45
+ });
46
+
47
+ this.contents.forEach((content, i) => {
48
+ content.style.display = i === idx ? 'block' : 'none';
49
+ content.classList.toggle('active', i === idx);
50
+ });
51
+
52
+ if (updateHash && this.tabNames[idx]) {
53
+ history.replaceState(null, null, '#' + this.tabNames[idx]);
54
+ }
55
+ }
56
+
57
+ getTabFromHash() {
58
+ const hash = window.location.hash.substring(1);
59
+ const tabIndex = this.tabNames.indexOf(hash);
60
+ return tabIndex >= 0 ? tabIndex : 0;
61
+ }
62
+ }
63
+
64
+ // Category Toggle
65
+ function toggleCategory(category) {
66
+ const content = document.getElementById(`content-${category}`);
67
+ const icon = document.getElementById(`icon-${category}`);
68
+
69
+ if (!content || !icon) return;
70
+
71
+ if (content.style.display === 'none' || content.style.display === '') {
72
+ content.style.display = 'block';
73
+ icon.style.transform = 'rotate(0deg)';
74
+ icon.textContent = 'expand_more';
75
+ } else {
76
+ content.style.display = 'none';
77
+ icon.style.transform = 'rotate(-90deg)';
78
+ icon.textContent = 'expand_less';
79
+ }
80
+ }
81
+
82
+ // Clipboard Functions
83
+ function copyToClipboard(text) {
84
+ navigator.clipboard.writeText(text).then(() => {
85
+ const button = event.target.closest('button');
86
+ const originalText = button.innerHTML;
87
+ button.innerHTML = '<span class="material-icons text-xs mr-1">check</span>Copied';
88
+ button.classList.remove('bg-gray-100', 'dark:bg-gray-700', 'hover:bg-gray-200', 'dark:hover:bg-gray-600');
89
+ button.classList.add('bg-green-600', 'hover:bg-green-700', 'dark:bg-green-500', 'dark:hover:bg-green-600', 'text-white');
90
+
91
+ setTimeout(() => {
92
+ button.innerHTML = originalText;
93
+ button.classList.remove('bg-green-600', 'hover:bg-green-700', 'dark:bg-green-500', 'dark:hover:bg-green-600', 'text-white');
94
+ button.classList.add('bg-gray-100', 'dark:bg-gray-700', 'hover:bg-gray-200', 'dark:hover:bg-gray-600');
95
+ }, 2000);
96
+ }).catch((err) => {
97
+ console.error('Could not copy text: ', err);
98
+ });
99
+ }
100
+
101
+ // Utility Functions
102
+ function getCookie(name) {
103
+ let cookieValue = null;
104
+ if (document.cookie && document.cookie !== '') {
105
+ const cookies = document.cookie.split(';');
106
+ for (let i = 0; i < cookies.length; i++) {
107
+ const cookie = cookies[i].trim();
108
+ if (cookie.substring(0, name.length + 1) === (name + '=')) {
109
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
110
+ break;
111
+ }
112
+ }
113
+ }
114
+ return cookieValue;
115
+ }
116
+
117
+ // Initialize on DOM load
118
+ document.addEventListener('DOMContentLoaded', () => {
119
+ new DashboardTabs();
120
+ });
121
+
122
+ // Export for global access
123
+ window.DashboardTabs = DashboardTabs;
124
+ window.toggleCategory = toggleCategory;
125
+ window.copyToClipboard = copyToClipboard;
126
+ window.getCookie = getCookie;
@@ -0,0 +1,375 @@
1
+ /**
2
+ * Management Commands JavaScript
3
+ * Handles toggle, search, modal, and command execution functionality
4
+ */
5
+
6
+ // Global functions for category expansion
7
+ window.toggleCategory = function(category) {
8
+ const content = document.getElementById(`content-${category}`);
9
+ const icon = document.getElementById(`icon-${category}`);
10
+
11
+ if (!content || !icon) return;
12
+
13
+ if (content.style.display === 'none' || content.style.display === '') {
14
+ content.style.display = 'block';
15
+ icon.style.transform = 'rotate(0deg)';
16
+ icon.textContent = 'expand_more';
17
+ } else {
18
+ content.style.display = 'none';
19
+ icon.style.transform = 'rotate(-90deg)';
20
+ icon.textContent = 'expand_less';
21
+ }
22
+ };
23
+
24
+ // Command execution functions
25
+ window.copyToClipboard = function(text) {
26
+ navigator.clipboard.writeText(text).then(function() {
27
+ const button = event.target.closest('button');
28
+ const originalText = button.innerHTML;
29
+ button.innerHTML = '<span class="material-icons text-xs mr-1">check</span>Copied';
30
+ button.classList.remove('bg-base-100', 'dark:bg-base-700', 'hover:bg-base-200', 'dark:hover:bg-base-600');
31
+ button.classList.add('bg-green-600', 'hover:bg-green-700', 'dark:bg-green-500', 'dark:hover:bg-green-600', 'text-white');
32
+
33
+ setTimeout(function() {
34
+ button.innerHTML = originalText;
35
+ button.classList.remove('bg-green-600', 'hover:bg-green-700', 'dark:bg-green-500', 'dark:hover:bg-green-600', 'text-white');
36
+ button.classList.add('bg-base-100', 'dark:bg-base-700', 'hover:bg-base-200', 'dark:hover:bg-base-600');
37
+ }, 2000);
38
+ }).catch(function(err) {
39
+ console.error('Could not copy text: ', err);
40
+ });
41
+ };
42
+
43
+ window.executeCommand = function(commandName) {
44
+ const modal = document.getElementById('commandModal');
45
+ const commandNameEl = document.getElementById('commandName');
46
+ const commandOutput = document.getElementById('commandOutput');
47
+ const commandStatus = document.getElementById('commandStatus');
48
+
49
+ if (!modal || !commandNameEl || !commandOutput || !commandStatus) {
50
+ console.error('Command modal elements not found');
51
+ return;
52
+ }
53
+
54
+ commandNameEl.textContent = commandName;
55
+ commandOutput.textContent = '';
56
+ commandStatus.innerHTML = '<div class="w-3 h-3 bg-yellow-500 rounded-full mr-2 animate-pulse"></div><span class="text-sm font-medium text-font-default-light dark:text-font-default-dark">Executing...</span>';
57
+ modal.classList.remove('hidden');
58
+
59
+ fetch('/cfg/commands/execute/', {
60
+ method: 'POST',
61
+ headers: {
62
+ 'Content-Type': 'application/json',
63
+ 'X-CSRFToken': getCookie('csrftoken')
64
+ },
65
+ body: JSON.stringify({
66
+ command: commandName,
67
+ args: [],
68
+ options: {}
69
+ })
70
+ })
71
+ .then(response => {
72
+ if (!response.ok) {
73
+ throw new Error(`HTTP error! status: ${response.status}`);
74
+ }
75
+
76
+ const reader = response.body.getReader();
77
+ const decoder = new TextDecoder();
78
+
79
+ function readStream() {
80
+ return reader.read().then(({done, value}) => {
81
+ if (done) return;
82
+
83
+ const chunk = decoder.decode(value);
84
+ const lines = chunk.split('\n');
85
+
86
+ lines.forEach(line => {
87
+ if (line.startsWith('data: ')) {
88
+ try {
89
+ const data = JSON.parse(line.slice(6));
90
+ handleCommandData(data);
91
+ } catch (e) {
92
+ console.error('Error parsing command data:', e);
93
+ }
94
+ }
95
+ });
96
+
97
+ return readStream();
98
+ });
99
+ }
100
+
101
+ return readStream();
102
+ })
103
+ .catch(error => {
104
+ console.error('Error executing command:', error);
105
+ commandOutput.textContent += `\n❌ Error: ${error.message}`;
106
+ commandStatus.innerHTML = '<div class="w-3 h-3 bg-red-500 rounded-full mr-2"></div><span class="text-sm font-medium text-red-600 dark:text-red-400">Error</span>';
107
+ });
108
+ };
109
+
110
+ window.closeCommandModal = function() {
111
+ const modal = document.getElementById('commandModal');
112
+ if (modal) {
113
+ modal.classList.add('hidden');
114
+ }
115
+ };
116
+
117
+ // Helper functions
118
+ function handleCommandData(data) {
119
+ const output = document.getElementById('commandOutput');
120
+ const status = document.getElementById('commandStatus');
121
+
122
+ if (!output || !status) return;
123
+
124
+ switch (data.type) {
125
+ case 'start':
126
+ output.innerHTML = '';
127
+ addLogLine(output, `🚀 Starting command: ${data.command}`, 'info');
128
+ addLogLine(output, `📝 Arguments: ${data.args.join(' ')}`, 'info');
129
+ addLogLine(output, '', 'spacer');
130
+ status.innerHTML = '<div class="w-3 h-3 bg-yellow-500 rounded-full mr-2 animate-pulse"></div><span class="text-sm font-medium text-font-default-light dark:text-font-default-dark">Executing...</span>';
131
+ break;
132
+ case 'output':
133
+ addLogLine(output, data.line, 'output');
134
+ scrollToBottom(output);
135
+ break;
136
+ case 'complete':
137
+ const success = data.return_code === 0;
138
+ status.innerHTML = success
139
+ ? '<div class="w-3 h-3 bg-green-500 rounded-full mr-2"></div><span class="text-sm font-medium text-green-600 dark:text-green-400">Completed</span>'
140
+ : '<div class="w-3 h-3 bg-red-500 rounded-full mr-2"></div><span class="text-sm font-medium text-red-600 dark:text-red-400">Failed</span>';
141
+
142
+ addLogLine(output, '', 'spacer');
143
+ let completionMessage = `${success ? '✅' : '❌'} Command completed with exit code: ${data.return_code}`;
144
+ if (data.execution_time) {
145
+ completionMessage += ` (${data.execution_time}s)`;
146
+ }
147
+ addLogLine(output, completionMessage, success ? 'success' : 'error');
148
+ scrollToBottom(output);
149
+ break;
150
+ case 'error':
151
+ addLogLine(output, `❌ ${data.message}`, 'error');
152
+ status.innerHTML = '<div class="w-3 h-3 bg-red-500 rounded-full mr-2"></div><span class="text-sm font-medium text-red-600 dark:text-red-400">Error</span>';
153
+ scrollToBottom(output);
154
+ break;
155
+ }
156
+ }
157
+
158
+ function addLogLine(container, text, type = 'output') {
159
+ const line = document.createElement('div');
160
+ line.className = 'log-line';
161
+
162
+ switch (type) {
163
+ case 'info':
164
+ line.className += ' text-blue-600 dark:text-blue-400';
165
+ break;
166
+ case 'success':
167
+ line.className += ' text-green-600 dark:text-green-400 font-medium';
168
+ break;
169
+ case 'error':
170
+ line.className += ' text-red-600 dark:text-red-400 font-medium';
171
+ break;
172
+ case 'spacer':
173
+ line.style.height = '1em';
174
+ break;
175
+ default:
176
+ line.className += ' text-font-default-light dark:text-font-default-dark';
177
+ }
178
+
179
+ line.textContent = text;
180
+ container.appendChild(line);
181
+ }
182
+
183
+ function scrollToBottom(element) {
184
+ element.scrollTop = element.scrollHeight;
185
+ }
186
+
187
+ function getCookie(name) {
188
+ let cookieValue = null;
189
+ if (document.cookie && document.cookie !== '') {
190
+ const cookies = document.cookie.split(';');
191
+ for (let i = 0; i < cookies.length; i++) {
192
+ const cookie = cookies[i].trim();
193
+ if (cookie.substring(0, name.length + 1) === (name + '=')) {
194
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
195
+ break;
196
+ }
197
+ }
198
+ }
199
+ return cookieValue;
200
+ }
201
+
202
+ // Search functionality
203
+ function searchCommands(query) {
204
+ const searchQuery = query.toLowerCase().trim();
205
+ const categories = document.querySelectorAll('[id^="content-"]');
206
+ const clearButton = document.getElementById('clearSearch');
207
+ const commandsCount = document.getElementById('commandsCount');
208
+ let visibleCommands = 0;
209
+
210
+ // Show/hide clear button
211
+ if (searchQuery) {
212
+ clearButton.classList.remove('hidden');
213
+ } else {
214
+ clearButton.classList.add('hidden');
215
+ }
216
+
217
+ categories.forEach(category => {
218
+ const categoryName = category.id.replace('content-', '');
219
+ const commands = category.querySelectorAll('.command-item');
220
+ let categoryHasVisibleCommands = false;
221
+
222
+ commands.forEach(command => {
223
+ const commandName = command.querySelector('.command-name').textContent.toLowerCase();
224
+ const commandDesc = command.querySelector('.command-description')?.textContent.toLowerCase() || '';
225
+
226
+ if (!searchQuery || commandName.includes(searchQuery) || commandDesc.includes(searchQuery)) {
227
+ command.style.display = 'block';
228
+ categoryHasVisibleCommands = true;
229
+ visibleCommands++;
230
+ } else {
231
+ command.style.display = 'none';
232
+ }
233
+ });
234
+
235
+ // Show/hide category based on whether it has visible commands
236
+ const categoryHeader = document.querySelector(`button[onclick="toggleCategory('${categoryName}')"]`);
237
+ const categoryContainer = categoryHeader.parentElement;
238
+
239
+ if (categoryHasVisibleCommands) {
240
+ categoryContainer.style.display = 'block';
241
+
242
+ // Auto-expand categories when searching
243
+ if (searchQuery) {
244
+ category.style.display = 'block';
245
+ const icon = categoryHeader.querySelector('.material-icons');
246
+ if (icon) {
247
+ icon.textContent = 'expand_less';
248
+ icon.style.transform = 'rotate(0deg)';
249
+ }
250
+ }
251
+ } else {
252
+ categoryContainer.style.display = 'none';
253
+ }
254
+ });
255
+
256
+ // Update commands count
257
+ if (commandsCount) {
258
+ commandsCount.textContent = visibleCommands;
259
+ }
260
+
261
+ // Show "no results" message if no commands found
262
+ showNoResultsMessage(visibleCommands === 0 && searchQuery);
263
+ }
264
+
265
+ function clearSearch() {
266
+ const searchInput = document.getElementById('commandSearch');
267
+ const clearButton = document.getElementById('clearSearch');
268
+ const commandsCount = document.getElementById('commandsCount');
269
+
270
+ searchInput.value = '';
271
+ clearButton.classList.add('hidden');
272
+
273
+ // Show all commands and categories
274
+ const categories = document.querySelectorAll('[id^="content-"]');
275
+ const allCommands = document.querySelectorAll('.command-item');
276
+
277
+ categories.forEach(category => {
278
+ const categoryName = category.id.replace('content-', '');
279
+ const categoryHeader = document.querySelector(`button[onclick="toggleCategory('${categoryName}')"]`);
280
+ categoryHeader.parentElement.style.display = 'block';
281
+ // Reset to collapsed state
282
+ category.style.display = 'none';
283
+ const icon = categoryHeader.querySelector('.material-icons');
284
+ if (icon) {
285
+ icon.textContent = 'expand_less';
286
+ icon.style.transform = 'rotate(-90deg)';
287
+ }
288
+ });
289
+
290
+ allCommands.forEach(command => {
291
+ command.style.display = 'block';
292
+ });
293
+
294
+ // Reset commands count to original total
295
+ if (commandsCount && commandsCount.dataset.originalCount) {
296
+ commandsCount.textContent = commandsCount.dataset.originalCount;
297
+ }
298
+
299
+ // Hide no results message
300
+ showNoResultsMessage(false);
301
+ }
302
+
303
+ function showNoResultsMessage(show) {
304
+ let noResultsDiv = document.getElementById('noSearchResults');
305
+
306
+ if (show && !noResultsDiv) {
307
+ // Create no results message
308
+ noResultsDiv = document.createElement('div');
309
+ noResultsDiv.id = 'noSearchResults';
310
+ noResultsDiv.className = 'text-center py-12';
311
+ noResultsDiv.innerHTML = `
312
+ <div class="flex flex-col items-center">
313
+ <span class="material-icons text-6xl text-base-400 dark:text-base-500 mb-4">search_off</span>
314
+ <h3 class="text-lg font-medium text-font-important-light dark:text-font-important-dark mb-2">
315
+ No Commands Found
316
+ </h3>
317
+ <p class="text-font-subtle-light dark:text-font-subtle-dark max-w-md mx-auto">
318
+ No commands match your search criteria. Try different keywords or clear the search.
319
+ </p>
320
+ </div>
321
+ `;
322
+
323
+ // Insert after the commands container
324
+ const commandsContainer = document.querySelector('.space-y-4');
325
+ if (commandsContainer && commandsContainer.parentNode) {
326
+ commandsContainer.parentNode.insertBefore(noResultsDiv, commandsContainer.nextSibling);
327
+ }
328
+ } else if (!show && noResultsDiv) {
329
+ noResultsDiv.remove();
330
+ }
331
+ }
332
+
333
+ // Initialize on page load
334
+ document.addEventListener('DOMContentLoaded', function() {
335
+ const searchInput = document.getElementById('commandSearch');
336
+ const commandsCount = document.getElementById('commandsCount');
337
+
338
+ // Store original count for reset
339
+ if (commandsCount) {
340
+ commandsCount.dataset.originalCount = commandsCount.textContent;
341
+ }
342
+
343
+ // Focus search with Ctrl+F or Cmd+F
344
+ document.addEventListener('keydown', function(e) {
345
+ if ((e.ctrlKey || e.metaKey) && e.key === 'f' && searchInput) {
346
+ e.preventDefault();
347
+ searchInput.focus();
348
+ }
349
+
350
+ // Clear search with Escape
351
+ if (e.key === 'Escape' && document.activeElement === searchInput) {
352
+ clearSearch();
353
+ searchInput.blur();
354
+ }
355
+
356
+ // Close modal with Escape
357
+ if (e.key === 'Escape') {
358
+ closeCommandModal();
359
+ }
360
+ });
361
+
362
+ // Close modal on background click
363
+ const modal = document.getElementById('commandModal');
364
+ if (modal) {
365
+ modal.addEventListener('click', function(e) {
366
+ if (e.target === modal) {
367
+ closeCommandModal();
368
+ }
369
+ });
370
+ }
371
+ });
372
+
373
+ // Export functions for global use
374
+ window.searchCommands = searchCommands;
375
+ window.clearSearch = clearSearch;