blockmine 1.21.0 → 1.22.0

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 (433) hide show
  1. package/.claude/agents/README.md +469 -0
  2. package/.claude/agents/auth-route-debugger.md +118 -0
  3. package/.claude/agents/auth-route-tester.md +93 -0
  4. package/.claude/agents/auto-error-resolver.md +97 -0
  5. package/.claude/agents/build-optimizer.md +236 -0
  6. package/.claude/agents/code-architecture-reviewer.md +83 -0
  7. package/.claude/agents/code-refactor-master.md +94 -0
  8. package/.claude/agents/cost-optimizer.md +134 -0
  9. package/.claude/agents/deployment-orchestrator.md +113 -0
  10. package/.claude/agents/documentation-architect.md +82 -0
  11. package/.claude/agents/frontend-error-fixer.md +77 -0
  12. package/.claude/agents/iac-code-generator.md +71 -0
  13. package/.claude/agents/incident-responder.md +346 -0
  14. package/.claude/agents/infrastructure-architect.md +31 -0
  15. package/.claude/agents/kubernetes-specialist.md +56 -0
  16. package/.claude/agents/migration-planner.md +181 -0
  17. package/.claude/agents/network-architect.md +196 -0
  18. package/.claude/agents/plan-reviewer.md +52 -0
  19. package/.claude/agents/refactor-planner.md +63 -0
  20. package/.claude/agents/security-scanner.md +102 -0
  21. package/.claude/agents/web-research-specialist.md +78 -0
  22. package/.claude/commands/cost-analysis.md +315 -0
  23. package/.claude/commands/dev-docs-update.md +55 -0
  24. package/.claude/commands/dev-docs.md +51 -0
  25. package/.claude/commands/incident-debug.md +247 -0
  26. package/.claude/commands/infra-plan.md +81 -0
  27. package/.claude/commands/migration-plan.md +478 -0
  28. package/.claude/commands/route-research-for-testing.md +37 -0
  29. package/.claude/commands/security-review.md +66 -0
  30. package/.claude/hooks/CONFIG.md +448 -0
  31. package/.claude/hooks/README.md +163 -0
  32. package/.claude/hooks/SKILL_ACTIVATION_COMPLETE.md +226 -0
  33. package/.claude/hooks/WINDOWS_HOOKS_README.md +151 -0
  34. package/.claude/hooks/add-skill-activation-banners.ts +132 -0
  35. package/.claude/hooks/comprehensive-skill-test.ts +1315 -0
  36. package/.claude/hooks/error-handling-reminder.sh +12 -0
  37. package/.claude/hooks/error-handling-reminder.ts +222 -0
  38. package/.claude/hooks/k8s-manifest-validator.sh +56 -0
  39. package/.claude/hooks/package-lock.json +556 -0
  40. package/.claude/hooks/package.json +16 -0
  41. package/.claude/hooks/post-tool-use-tracker.ps1 +174 -0
  42. package/.claude/hooks/post-tool-use-tracker.sh +183 -0
  43. package/.claude/hooks/security-policy-check.sh +247 -0
  44. package/.claude/hooks/skill-activation-prompt.ps1 +10 -0
  45. package/.claude/hooks/skill-activation-prompt.sh +10 -0
  46. package/.claude/hooks/skill-activation-prompt.ts +141 -0
  47. package/.claude/hooks/stop-build-check-enhanced.sh +130 -0
  48. package/.claude/hooks/terraform-validator.sh +53 -0
  49. package/.claude/hooks/test-input.json +7 -0
  50. package/.claude/hooks/test-skill-activation.ts +427 -0
  51. package/.claude/hooks/trigger-build-resolver.sh +79 -0
  52. package/.claude/hooks/tsc-check.sh +173 -0
  53. package/.claude/hooks/tsconfig.json +19 -0
  54. package/.claude/settings.json +55 -0
  55. package/.claude/settings.local.json +27 -14
  56. package/.claude/skills/README.md +507 -0
  57. package/.claude/skills/api-engineering/SKILL.md +63 -0
  58. package/.claude/skills/api-engineering/resources/api-versioning.md +88 -0
  59. package/.claude/skills/api-engineering/resources/graphql-patterns.md +106 -0
  60. package/.claude/skills/api-engineering/resources/rate-limiting.md +118 -0
  61. package/.claude/skills/api-engineering/resources/rest-api-design.md +105 -0
  62. package/.claude/skills/backend-dev-guidelines/SKILL.md +306 -0
  63. package/.claude/skills/backend-dev-guidelines/resources/architecture-overview.md +451 -0
  64. package/.claude/skills/backend-dev-guidelines/resources/async-and-errors.md +307 -0
  65. package/.claude/skills/backend-dev-guidelines/resources/complete-examples.md +638 -0
  66. package/.claude/skills/backend-dev-guidelines/resources/configuration.md +275 -0
  67. package/.claude/skills/backend-dev-guidelines/resources/database-patterns.md +224 -0
  68. package/.claude/skills/backend-dev-guidelines/resources/middleware-guide.md +213 -0
  69. package/.claude/skills/backend-dev-guidelines/resources/routing-and-controllers.md +756 -0
  70. package/.claude/skills/backend-dev-guidelines/resources/sentry-and-monitoring.md +336 -0
  71. package/.claude/skills/backend-dev-guidelines/resources/services-and-repositories.md +789 -0
  72. package/.claude/skills/backend-dev-guidelines/resources/testing-guide.md +235 -0
  73. package/.claude/skills/backend-dev-guidelines/resources/validation-patterns.md +754 -0
  74. package/.claude/skills/budget-and-cost-management/SKILL.md +850 -0
  75. package/.claude/skills/build-engineering/SKILL.md +431 -0
  76. package/.claude/skills/build-engineering/resources/artifact-repositories.md +72 -0
  77. package/.claude/skills/build-engineering/resources/build-caching.md +96 -0
  78. package/.claude/skills/build-engineering/resources/build-pipelines.md +105 -0
  79. package/.claude/skills/build-engineering/resources/build-security.md +95 -0
  80. package/.claude/skills/build-engineering/resources/build-systems.md +389 -0
  81. package/.claude/skills/build-engineering/resources/compilation-optimization.md +201 -0
  82. package/.claude/skills/build-engineering/resources/dependency-management.md +73 -0
  83. package/.claude/skills/build-engineering/resources/monorepo-builds.md +110 -0
  84. package/.claude/skills/build-engineering/resources/performance-optimization.md +113 -0
  85. package/.claude/skills/build-engineering/resources/reproducible-builds.md +82 -0
  86. package/.claude/skills/cloud-engineering/SKILL.md +675 -0
  87. package/.claude/skills/cloud-engineering/resources/aws-patterns.md +742 -0
  88. package/.claude/skills/cloud-engineering/resources/azure-patterns.md +714 -0
  89. package/.claude/skills/cloud-engineering/resources/cleared-cloud-environments.md +987 -0
  90. package/.claude/skills/cloud-engineering/resources/cloud-cost-optimization.md +757 -0
  91. package/.claude/skills/cloud-engineering/resources/cloud-networking.md +1058 -0
  92. package/.claude/skills/cloud-engineering/resources/cloud-security-tools.md +1530 -0
  93. package/.claude/skills/cloud-engineering/resources/cloud-security.md +990 -0
  94. package/.claude/skills/cloud-engineering/resources/gcp-patterns.md +758 -0
  95. package/.claude/skills/cloud-engineering/resources/migration-strategies.md +820 -0
  96. package/.claude/skills/cloud-engineering/resources/multi-cloud-strategies.md +670 -0
  97. package/.claude/skills/cloud-engineering/resources/oci-patterns.md +1198 -0
  98. package/.claude/skills/cloud-engineering/resources/serverless-patterns.md +795 -0
  99. package/.claude/skills/cloud-engineering/resources/well-architected-frameworks.md +966 -0
  100. package/.claude/skills/cybersecurity/SKILL.md +409 -0
  101. package/.claude/skills/cybersecurity/resources/security-architecture.md +266 -0
  102. package/.claude/skills/database-engineering/SKILL.md +61 -0
  103. package/.claude/skills/database-engineering/resources/backup-and-recovery.md +72 -0
  104. package/.claude/skills/database-engineering/resources/database-replication.md +63 -0
  105. package/.claude/skills/database-engineering/resources/postgresql-fundamentals.md +70 -0
  106. package/.claude/skills/database-engineering/resources/query-optimization.md +68 -0
  107. package/.claude/skills/devsecops/SKILL.md +374 -0
  108. package/.claude/skills/devsecops/resources/ci-cd-security.md +204 -0
  109. package/.claude/skills/devsecops/resources/compliance-automation.md +530 -0
  110. package/.claude/skills/devsecops/resources/compliance-frameworks.md +2322 -0
  111. package/.claude/skills/devsecops/resources/container-security.md +915 -0
  112. package/.claude/skills/devsecops/resources/cspm-integration.md +1440 -0
  113. package/.claude/skills/devsecops/resources/policy-enforcement.md +619 -0
  114. package/.claude/skills/devsecops/resources/secrets-management.md +755 -0
  115. package/.claude/skills/devsecops/resources/security-monitoring.md +146 -0
  116. package/.claude/skills/devsecops/resources/security-scanning.md +887 -0
  117. package/.claude/skills/devsecops/resources/security-testing.md +203 -0
  118. package/.claude/skills/devsecops/resources/supply-chain-security.md +518 -0
  119. package/.claude/skills/devsecops/resources/vulnerability-management.md +481 -0
  120. package/.claude/skills/devsecops/resources/zero-trust-architecture.md +177 -0
  121. package/.claude/skills/documentation-as-code/SKILL.md +323 -0
  122. package/.claude/skills/documentation-as-code/resources/api-documentation.md +90 -0
  123. package/.claude/skills/documentation-as-code/resources/changelog-management.md +79 -0
  124. package/.claude/skills/documentation-as-code/resources/diagram-generation.md +44 -0
  125. package/.claude/skills/documentation-as-code/resources/docs-as-code-workflow.md +99 -0
  126. package/.claude/skills/documentation-as-code/resources/documentation-automation.md +68 -0
  127. package/.claude/skills/documentation-as-code/resources/documentation-sites.md +79 -0
  128. package/.claude/skills/documentation-as-code/resources/markdown-best-practices.md +162 -0
  129. package/.claude/skills/documentation-as-code/resources/openapi-specification.md +77 -0
  130. package/.claude/skills/documentation-as-code/resources/readme-engineering.md +60 -0
  131. package/.claude/skills/documentation-as-code/resources/technical-writing-guide.md +202 -0
  132. package/.claude/skills/engineering-management/SKILL.md +356 -0
  133. package/.claude/skills/engineering-management/resources/career-ladders.md +609 -0
  134. package/.claude/skills/engineering-management/resources/hiring-and-assessment.md +555 -0
  135. package/.claude/skills/engineering-management/resources/one-on-one-guides.md +609 -0
  136. package/.claude/skills/engineering-management/resources/resource-planning.md +557 -0
  137. package/.claude/skills/engineering-management/resources/team-organization-patterns.md +491 -0
  138. package/.claude/skills/engineering-management/resources/technical-interviews.md +474 -0
  139. package/.claude/skills/engineering-operations-management/SKILL.md +817 -0
  140. package/.claude/skills/error-tracking/SKILL.md +379 -0
  141. package/.claude/skills/frontend-dev-guidelines/SKILL.md +403 -0
  142. package/.claude/skills/frontend-dev-guidelines/resources/common-patterns.md +331 -0
  143. package/.claude/skills/frontend-dev-guidelines/resources/complete-examples.md +872 -0
  144. package/.claude/skills/frontend-dev-guidelines/resources/component-patterns.md +502 -0
  145. package/.claude/skills/frontend-dev-guidelines/resources/data-fetching.md +767 -0
  146. package/.claude/skills/frontend-dev-guidelines/resources/file-organization.md +502 -0
  147. package/.claude/skills/frontend-dev-guidelines/resources/loading-and-error-states.md +501 -0
  148. package/.claude/skills/frontend-dev-guidelines/resources/performance.md +406 -0
  149. package/.claude/skills/frontend-dev-guidelines/resources/routing-guide.md +364 -0
  150. package/.claude/skills/frontend-dev-guidelines/resources/styling-guide.md +428 -0
  151. package/.claude/skills/frontend-dev-guidelines/resources/typescript-standards.md +418 -0
  152. package/.claude/skills/general-it-engineering/SKILL.md +393 -0
  153. package/.claude/skills/general-it-engineering/resources/asset-management.md +712 -0
  154. package/.claude/skills/general-it-engineering/resources/automation-orchestration.md +817 -0
  155. package/.claude/skills/general-it-engineering/resources/business-continuity.md +786 -0
  156. package/.claude/skills/general-it-engineering/resources/change-management.md +715 -0
  157. package/.claude/skills/general-it-engineering/resources/enterprise-monitoring.md +729 -0
  158. package/.claude/skills/general-it-engineering/resources/help-desk-operations.md +738 -0
  159. package/.claude/skills/general-it-engineering/resources/incident-service-management.md +834 -0
  160. package/.claude/skills/general-it-engineering/resources/it-governance.md +753 -0
  161. package/.claude/skills/general-it-engineering/resources/itil-framework.md +503 -0
  162. package/.claude/skills/general-it-engineering/resources/service-management.md +669 -0
  163. package/.claude/skills/infrastructure-architecture/SKILL.md +328 -0
  164. package/.claude/skills/infrastructure-architecture/resources/architecture-decision-records.md +505 -0
  165. package/.claude/skills/infrastructure-architecture/resources/architecture-patterns.md +528 -0
  166. package/.claude/skills/infrastructure-architecture/resources/capacity-planning.md +453 -0
  167. package/.claude/skills/infrastructure-architecture/resources/cleared-environment-architecture.md +773 -0
  168. package/.claude/skills/infrastructure-architecture/resources/cost-architecture.md +499 -0
  169. package/.claude/skills/infrastructure-architecture/resources/data-architecture.md +501 -0
  170. package/.claude/skills/infrastructure-architecture/resources/disaster-recovery.md +535 -0
  171. package/.claude/skills/infrastructure-architecture/resources/migration-architecture.md +512 -0
  172. package/.claude/skills/infrastructure-architecture/resources/multi-region-design.md +608 -0
  173. package/.claude/skills/infrastructure-architecture/resources/reference-architectures.md +562 -0
  174. package/.claude/skills/infrastructure-architecture/resources/security-architecture.md +538 -0
  175. package/.claude/skills/infrastructure-architecture/resources/system-design-principles.md +489 -0
  176. package/.claude/skills/infrastructure-architecture/resources/workload-classification.md +1000 -0
  177. package/.claude/skills/infrastructure-strategy/SKILL.md +924 -0
  178. package/.claude/skills/network-engineering/SKILL.md +385 -0
  179. package/.claude/skills/network-engineering/resources/dns-management.md +738 -0
  180. package/.claude/skills/network-engineering/resources/load-balancing.md +820 -0
  181. package/.claude/skills/network-engineering/resources/network-architecture.md +546 -0
  182. package/.claude/skills/network-engineering/resources/network-security.md +921 -0
  183. package/.claude/skills/network-engineering/resources/network-troubleshooting.md +749 -0
  184. package/.claude/skills/network-engineering/resources/routing-switching.md +373 -0
  185. package/.claude/skills/network-engineering/resources/sdn-networking.md +695 -0
  186. package/.claude/skills/network-engineering/resources/service-mesh-networking.md +777 -0
  187. package/.claude/skills/network-engineering/resources/tcp-ip-protocols.md +444 -0
  188. package/.claude/skills/network-engineering/resources/vpn-connectivity.md +672 -0
  189. package/.claude/skills/observability-engineering/SKILL.md +101 -0
  190. package/.claude/skills/observability-engineering/resources/apm-tools.md +97 -0
  191. package/.claude/skills/observability-engineering/resources/correlation-strategies.md +87 -0
  192. package/.claude/skills/observability-engineering/resources/distributed-tracing.md +98 -0
  193. package/.claude/skills/observability-engineering/resources/logs-aggregation.md +118 -0
  194. package/.claude/skills/observability-engineering/resources/observability-cost-optimization.md +141 -0
  195. package/.claude/skills/observability-engineering/resources/opentelemetry.md +110 -0
  196. package/.claude/skills/platform-engineering/SKILL.md +555 -0
  197. package/.claude/skills/platform-engineering/resources/architecture-overview.md +600 -0
  198. package/.claude/skills/platform-engineering/resources/container-orchestration.md +916 -0
  199. package/.claude/skills/platform-engineering/resources/cost-optimization.md +634 -0
  200. package/.claude/skills/platform-engineering/resources/developer-platforms.md +670 -0
  201. package/.claude/skills/platform-engineering/resources/gitops-automation.md +650 -0
  202. package/.claude/skills/platform-engineering/resources/infrastructure-as-code.md +778 -0
  203. package/.claude/skills/platform-engineering/resources/infrastructure-standards.md +708 -0
  204. package/.claude/skills/platform-engineering/resources/multi-tenancy.md +602 -0
  205. package/.claude/skills/platform-engineering/resources/platform-security.md +711 -0
  206. package/.claude/skills/platform-engineering/resources/resource-management.md +592 -0
  207. package/.claude/skills/platform-engineering/resources/service-mesh.md +628 -0
  208. package/.claude/skills/release-engineering/SKILL.md +393 -0
  209. package/.claude/skills/release-engineering/resources/artifact-management.md +108 -0
  210. package/.claude/skills/release-engineering/resources/build-optimization.md +84 -0
  211. package/.claude/skills/release-engineering/resources/ci-cd-pipelines.md +411 -0
  212. package/.claude/skills/release-engineering/resources/deployment-strategies.md +197 -0
  213. package/.claude/skills/release-engineering/resources/pipeline-security.md +62 -0
  214. package/.claude/skills/release-engineering/resources/progressive-delivery.md +83 -0
  215. package/.claude/skills/release-engineering/resources/release-automation.md +68 -0
  216. package/.claude/skills/release-engineering/resources/release-orchestration.md +77 -0
  217. package/.claude/skills/release-engineering/resources/rollback-strategies.md +66 -0
  218. package/.claude/skills/release-engineering/resources/versioning-strategies.md +59 -0
  219. package/.claude/skills/route-tester/SKILL.md +392 -0
  220. package/.claude/skills/skill-developer/ADVANCED.md +197 -0
  221. package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +306 -0
  222. package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +152 -0
  223. package/.claude/skills/skill-developer/SKILL.md +430 -0
  224. package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +315 -0
  225. package/.claude/skills/skill-developer/TRIGGER_TYPES.md +305 -0
  226. package/.claude/skills/skill-developer/TROUBLESHOOTING.md +514 -0
  227. package/.claude/skills/skill-rules.json +2940 -0
  228. package/.claude/skills/sre/SKILL.md +464 -0
  229. package/.claude/skills/sre/resources/alerting-best-practices.md +282 -0
  230. package/.claude/skills/sre/resources/capacity-planning.md +226 -0
  231. package/.claude/skills/sre/resources/chaos-engineering.md +193 -0
  232. package/.claude/skills/sre/resources/disaster-recovery.md +232 -0
  233. package/.claude/skills/sre/resources/incident-management.md +436 -0
  234. package/.claude/skills/sre/resources/observability-stack.md +240 -0
  235. package/.claude/skills/sre/resources/on-call-runbooks.md +167 -0
  236. package/.claude/skills/sre/resources/performance-optimization.md +108 -0
  237. package/.claude/skills/sre/resources/reliability-patterns.md +183 -0
  238. package/.claude/skills/sre/resources/slo-sli-sla.md +464 -0
  239. package/.claude/skills/sre/resources/toil-reduction.md +145 -0
  240. package/.claude/skills/systems-engineering/SKILL.md +648 -0
  241. package/.claude/skills/systems-engineering/resources/automation-patterns.md +771 -0
  242. package/.claude/skills/systems-engineering/resources/configuration-management.md +998 -0
  243. package/.claude/skills/systems-engineering/resources/linux-administration.md +672 -0
  244. package/.claude/skills/systems-engineering/resources/networking-fundamentals.md +982 -0
  245. package/.claude/skills/systems-engineering/resources/performance-tuning.md +871 -0
  246. package/.claude/skills/systems-engineering/resources/powershell-scripting.md +482 -0
  247. package/.claude/skills/systems-engineering/resources/security-hardening.md +739 -0
  248. package/.claude/skills/systems-engineering/resources/shell-scripting.md +915 -0
  249. package/.claude/skills/systems-engineering/resources/storage-management.md +628 -0
  250. package/.claude/skills/systems-engineering/resources/system-monitoring.md +787 -0
  251. package/.claude/skills/systems-engineering/resources/troubleshooting-guide.md +753 -0
  252. package/.claude/skills/systems-engineering/resources/windows-administration.md +738 -0
  253. package/.claude/skills/technical-leadership/SKILL.md +728 -0
  254. package/CHANGELOG.md +90 -54
  255. package/README.md +94 -0
  256. package/backend/docs/SECRETS_DOCUMENTATION.md +327 -0
  257. package/backend/jest.config.js +59 -0
  258. package/backend/package-lock.json +6129 -0
  259. package/backend/package.json +16 -4
  260. package/backend/prisma/migrations/20251026104609_add_websocket_api/migration.sql +33 -0
  261. package/backend/prisma/schema.prisma +33 -0
  262. package/backend/src/__tests__/core/DependencyService.test.js +336 -0
  263. package/backend/src/__tests__/core/UserService.test.js +875 -0
  264. package/backend/src/__tests__/repositories/BaseRepository.test.js +146 -0
  265. package/backend/src/__tests__/repositories/BotRepository.test.js +118 -0
  266. package/backend/src/__tests__/repositories/CommandRepository.test.js +132 -0
  267. package/backend/src/__tests__/repositories/EventGraphRepository.test.js +93 -0
  268. package/backend/src/__tests__/repositories/GroupRepository.test.js +155 -0
  269. package/backend/src/__tests__/repositories/PermissionRepository.test.js +130 -0
  270. package/backend/src/__tests__/repositories/PluginRepository.test.js +107 -0
  271. package/backend/src/__tests__/repositories/ServerRepository.test.js +80 -0
  272. package/backend/src/__tests__/repositories/UserRepository.test.js +128 -0
  273. package/backend/src/__tests__/secretsFilter.test.js +425 -0
  274. package/backend/src/__tests__/services/BotLifecycleService.test.js +411 -0
  275. package/backend/src/__tests__/services/BotProcessManager.test.js +285 -0
  276. package/backend/src/__tests__/services/CacheManager.test.js +125 -0
  277. package/backend/src/__tests__/services/CommandExecutionService.test.js +460 -0
  278. package/backend/src/__tests__/services/ResourceMonitorService.test.js +207 -0
  279. package/backend/src/__tests__/services/TelemetryService.test.js +291 -0
  280. package/backend/src/__tests__/setup.js +25 -0
  281. package/backend/src/api/routes/apiKeys.js +181 -0
  282. package/backend/src/api/routes/bots.js +49 -7
  283. package/backend/src/api/routes/plugins.js +2 -1
  284. package/backend/src/api/routes/system.js +174 -0
  285. package/backend/src/container.js +82 -0
  286. package/backend/src/core/BotManager.js +142 -871
  287. package/backend/src/core/BotManager.old.js +1093 -0
  288. package/backend/src/core/BotProcess.js +1092 -858
  289. package/backend/src/core/EventGraphManager.js +280 -198
  290. package/backend/src/core/GraphExecutionEngine.js +321 -325
  291. package/backend/src/core/MessageQueue.js +27 -6
  292. package/backend/src/core/NodeRegistry.js +37 -1134
  293. package/backend/src/core/PluginManager.js +62 -12
  294. package/backend/src/core/PrismaService.js +32 -0
  295. package/backend/src/core/UserService.js +3 -3
  296. package/backend/src/core/__tests__/PrismaService.test.js +24 -0
  297. package/backend/src/core/commands/README.md +305 -0
  298. package/backend/src/core/commands/dev.js +13 -7
  299. package/backend/src/core/commands/ping.js +10 -4
  300. package/backend/src/core/commands/whois.js +63 -0
  301. package/backend/src/core/config/validation.js +27 -0
  302. package/backend/src/core/constants/graphTypes.js +21 -0
  303. package/backend/src/core/node-registries/actions.js +132 -0
  304. package/backend/src/core/node-registries/arrays.js +137 -0
  305. package/backend/src/core/node-registries/bot.js +23 -0
  306. package/backend/src/core/node-registries/data.js +290 -0
  307. package/backend/src/core/node-registries/debug.js +26 -0
  308. package/backend/src/core/node-registries/events.js +187 -0
  309. package/backend/src/core/node-registries/flow.js +139 -0
  310. package/backend/src/core/node-registries/logic.js +45 -0
  311. package/backend/src/core/node-registries/math.js +42 -0
  312. package/backend/src/core/node-registries/objects.js +98 -0
  313. package/backend/src/core/node-registries/strings.js +153 -0
  314. package/backend/src/core/node-registries/time.js +113 -0
  315. package/backend/src/core/node-registries/users.js +79 -0
  316. package/backend/src/core/nodes/{action_bot_look_at.js → actions/bot_look_at.js} +36 -36
  317. package/backend/src/core/nodes/{action_bot_set_variable.js → actions/bot_set_variable.js} +32 -32
  318. package/backend/src/core/nodes/{action_send_log.js → actions/send_log.js} +28 -23
  319. package/backend/src/core/nodes/{action_send_message.js → actions/send_message.js} +32 -32
  320. package/backend/src/core/nodes/actions/send_websocket_response.js +33 -0
  321. package/backend/src/core/nodes/arrays/get_next.js +35 -0
  322. package/backend/src/core/nodes/{data_cast.js → data/cast.js} +8 -0
  323. package/backend/src/core/nodes/data/datetime_literal.js +27 -0
  324. package/backend/src/core/nodes/data/entity_info.js +69 -0
  325. package/backend/src/core/nodes/data/get_nearby_entities.js +32 -0
  326. package/backend/src/core/nodes/data/get_nearby_players.js +64 -0
  327. package/backend/src/core/nodes/{data_get_user_field.js → data/get_user_field.js} +1 -1
  328. package/backend/src/core/nodes/data/type_check.js +53 -0
  329. package/backend/src/core/nodes/{debug_log.js → debug/log.js} +16 -16
  330. package/backend/src/core/nodes/{flow_branch.js → flow/branch.js} +15 -15
  331. package/backend/src/core/nodes/{flow_break.js → flow/break.js} +14 -14
  332. package/backend/src/core/nodes/flow/delay.js +43 -0
  333. package/backend/src/core/nodes/{flow_for_each.js → flow/for_each.js} +39 -39
  334. package/backend/src/core/nodes/{flow_sequence.js → flow/sequence.js} +16 -16
  335. package/backend/src/core/nodes/{flow_switch.js → flow/switch.js} +47 -47
  336. package/backend/src/core/nodes/{flow_while.js → flow/while.js} +1 -1
  337. package/backend/src/core/nodes/logic/__tests__/compare.test.js +83 -0
  338. package/backend/src/core/nodes/math/__tests__/operation.test.js +65 -0
  339. package/backend/src/core/nodes/strings/__tests__/concat.test.js +89 -0
  340. package/backend/src/core/nodes/time/__tests__/now.test.js +24 -0
  341. package/backend/src/core/nodes/time/add.js +33 -0
  342. package/backend/src/core/nodes/time/compare.js +35 -0
  343. package/backend/src/core/nodes/time/diff.js +29 -0
  344. package/backend/src/core/nodes/time/format.js +32 -0
  345. package/backend/src/core/nodes/time/now.js +18 -0
  346. package/backend/src/core/nodes/{user_check_blacklist.js → users/check_blacklist.js} +37 -37
  347. package/backend/src/core/nodes/{user_get_groups.js → users/get_groups.js} +36 -36
  348. package/backend/src/core/nodes/{user_get_permissions.js → users/get_permissions.js} +36 -36
  349. package/backend/src/core/nodes/{user_set_blacklist.js → users/set_blacklist.js} +37 -37
  350. package/backend/src/core/services/BotLifecycleService.js +596 -0
  351. package/backend/src/core/services/BotProcessManager.js +163 -0
  352. package/backend/src/core/services/CacheManager.js +111 -0
  353. package/backend/src/core/services/CommandExecutionService.js +351 -0
  354. package/backend/src/core/services/ResourceMonitorService.js +90 -0
  355. package/backend/src/core/services/TelemetryService.js +124 -0
  356. package/backend/src/core/services/ValidationService.js +132 -0
  357. package/backend/src/core/services/__tests__/ValidationService.test.js +148 -0
  358. package/backend/src/core/services.js +20 -5
  359. package/backend/src/core/system/CommandContext.js +84 -0
  360. package/backend/src/core/system/Transport.js +78 -0
  361. package/backend/src/core/utils/__tests__/jsonParser.test.js +44 -0
  362. package/backend/src/core/utils/jsonParser.js +18 -0
  363. package/backend/src/core/utils/secretsFilter.js +262 -0
  364. package/backend/src/core/utils/variableParser.js +89 -0
  365. package/backend/src/core/validation/__tests__/nodeSchemas.test.js +175 -0
  366. package/backend/src/core/validation/nodeSchemas.js +112 -0
  367. package/backend/src/lib/prisma.js +2 -4
  368. package/backend/src/real-time/botApi/handlers/commandHandlers.js +28 -0
  369. package/backend/src/real-time/botApi/handlers/graphHandlers.js +99 -0
  370. package/backend/src/real-time/botApi/handlers/graphWebSocketHandlers.js +147 -0
  371. package/backend/src/real-time/botApi/handlers/index.js +43 -0
  372. package/backend/src/real-time/botApi/handlers/messageHandlers.js +66 -0
  373. package/backend/src/real-time/botApi/handlers/statusHandlers.js +17 -0
  374. package/backend/src/real-time/botApi/handlers/userHandlers.js +141 -0
  375. package/backend/src/real-time/botApi/index.js +40 -0
  376. package/backend/src/real-time/botApi/middleware.js +79 -0
  377. package/backend/src/real-time/botApi/utils.js +54 -0
  378. package/backend/src/real-time/socketHandler.js +6 -2
  379. package/backend/src/repositories/BaseRepository.js +43 -0
  380. package/backend/src/repositories/BotRepository.js +42 -0
  381. package/backend/src/repositories/CommandRepository.js +53 -0
  382. package/backend/src/repositories/EventGraphRepository.js +40 -0
  383. package/backend/src/repositories/GroupRepository.js +69 -0
  384. package/backend/src/repositories/PermissionRepository.js +48 -0
  385. package/backend/src/repositories/PluginRepository.js +42 -0
  386. package/backend/src/repositories/ServerRepository.js +27 -0
  387. package/backend/src/repositories/UserRepository.js +48 -0
  388. package/backend/src/server.js +3 -0
  389. package/backend/src/test-refactor.js +85 -0
  390. package/frontend/dist/assets/index-CfTo92bP.css +1 -0
  391. package/frontend/dist/assets/index-CiFD5X9Z.js +8344 -0
  392. package/frontend/dist/index.html +2 -2
  393. package/frontend/package.json +0 -5
  394. package/package.json +2 -1
  395. package/frontend/dist/assets/index-B9GedHEa.js +0 -8352
  396. package/frontend/dist/assets/index-zLiy9MDx.css +0 -1
  397. package/nul +0 -0
  398. /package/backend/src/core/nodes/{action_http_request.js → actions/http_request.js} +0 -0
  399. /package/backend/src/core/nodes/{array_add_element.js → arrays/add_element.js} +0 -0
  400. /package/backend/src/core/nodes/{array_contains.js → arrays/contains.js} +0 -0
  401. /package/backend/src/core/nodes/{array_find_index.js → arrays/find_index.js} +0 -0
  402. /package/backend/src/core/nodes/{array_get_by_index.js → arrays/get_by_index.js} +0 -0
  403. /package/backend/src/core/nodes/{array_get_random_element.js → arrays/get_random_element.js} +0 -0
  404. /package/backend/src/core/nodes/{array_remove_by_index.js → arrays/remove_by_index.js} +0 -0
  405. /package/backend/src/core/nodes/{bot_get_position.js → bot/get_position.js} +0 -0
  406. /package/backend/src/core/nodes/{data_array_literal.js → data/array_literal.js} +0 -0
  407. /package/backend/src/core/nodes/{data_boolean_literal.js → data/boolean_literal.js} +0 -0
  408. /package/backend/src/core/nodes/{data_get_argument.js → data/get_argument.js} +0 -0
  409. /package/backend/src/core/nodes/{data_get_bot_look.js → data/get_bot_look.js} +0 -0
  410. /package/backend/src/core/nodes/{data_get_entity_field.js → data/get_entity_field.js} +0 -0
  411. /package/backend/src/core/nodes/{data_get_server_players.js → data/get_server_players.js} +0 -0
  412. /package/backend/src/core/nodes/{data_get_variable.js → data/get_variable.js} +0 -0
  413. /package/backend/src/core/nodes/{data_length.js → data/length.js} +0 -0
  414. /package/backend/src/core/nodes/{data_make_object.js → data/make_object.js} +0 -0
  415. /package/backend/src/core/nodes/{data_number_literal.js → data/number_literal.js} +0 -0
  416. /package/backend/src/core/nodes/{data_string_literal.js → data/string_literal.js} +0 -0
  417. /package/backend/src/core/nodes/{logic_compare.js → logic/compare.js} +0 -0
  418. /package/backend/src/core/nodes/{logic_operation.js → logic/operation.js} +0 -0
  419. /package/backend/src/core/nodes/{math_operation.js → math/operation.js} +0 -0
  420. /package/backend/src/core/nodes/{math_random_number.js → math/random_number.js} +0 -0
  421. /package/backend/src/core/nodes/{object_create.js → objects/create.js} +0 -0
  422. /package/backend/src/core/nodes/{object_delete.js → objects/delete.js} +0 -0
  423. /package/backend/src/core/nodes/{object_get.js → objects/get.js} +0 -0
  424. /package/backend/src/core/nodes/{object_has_key.js → objects/has_key.js} +0 -0
  425. /package/backend/src/core/nodes/{object_set.js → objects/set.js} +0 -0
  426. /package/backend/src/core/nodes/{string_concat.js → strings/concat.js} +0 -0
  427. /package/backend/src/core/nodes/{string_contains.js → strings/contains.js} +0 -0
  428. /package/backend/src/core/nodes/{string_ends_with.js → strings/ends_with.js} +0 -0
  429. /package/backend/src/core/nodes/{string_equals.js → strings/equals.js} +0 -0
  430. /package/backend/src/core/nodes/{string_length.js → strings/length.js} +0 -0
  431. /package/backend/src/core/nodes/{string_matches.js → strings/matches.js} +0 -0
  432. /package/backend/src/core/nodes/{string_split.js → strings/split.js} +0 -0
  433. /package/backend/src/core/nodes/{string_starts_with.js → strings/starts_with.js} +0 -0
@@ -38,7 +38,7 @@ function reportPluginDownload(pluginName) {
38
38
 
39
39
 
40
40
  class PluginManager {
41
- constructor(botManager) {
41
+ constructor({ botManager } = {}) {
42
42
  this.botManager = botManager;
43
43
  this.ensureBaseDirExists();
44
44
  }
@@ -125,7 +125,7 @@ class PluginManager {
125
125
  return newPlugin;
126
126
  }
127
127
 
128
- async installFromGithub(botId, repoUrl, prismaClient = prisma, isUpdate = false) {
128
+ async installFromGithub(botId, repoUrl, prismaClient = prisma, isUpdate = false, tag = null) {
129
129
  const botPluginsDir = path.join(PLUGINS_BASE_DIR, `bot_${botId}`);
130
130
  await fse.mkdir(botPluginsDir, { recursive: true });
131
131
 
@@ -137,17 +137,36 @@ class PluginManager {
137
137
  try {
138
138
  const url = new URL(repoUrl);
139
139
  const repoPath = url.pathname.replace(/^\/|\.git$/g, '');
140
- const archiveUrlMain = `https://github.com/${repoPath}/archive/refs/heads/main.zip`;
141
- const archiveUrlMaster = `https://github.com/${repoPath}/archive/refs/heads/master.zip`;
140
+
141
+ let response;
142
+
143
+ // Если указан тег - скачиваем конкретный релиз
144
+ if (tag) {
145
+ const archiveUrlTag = `https://github.com/${repoPath}/archive/refs/tags/${encodeURIComponent(tag)}.zip`;
146
+ console.log(`[PluginManager] Скачиваем релиз ${tag} из ${repoUrl}...`);
147
+ try {
148
+ response = await fetch(archiveUrlTag);
149
+ } catch (err) {
150
+ throw new Error(`Ошибка сети при скачивании релиза ${tag}: ${err.message || err}`);
151
+ }
152
+ if (!response.ok) {
153
+ throw new Error(`Не удалось скачать релиз ${tag}. Статус: ${response.status}. Возможно, тег не существует.`);
154
+ }
155
+ } else {
156
+ // Если тег не указан - скачиваем последний коммит из main/master (старое поведение)
157
+ const archiveUrlMain = `https://github.com/${repoPath}/archive/refs/heads/main.zip`;
158
+ const archiveUrlMaster = `https://github.com/${repoPath}/archive/refs/heads/master.zip`;
142
159
 
143
- let response = await fetch(archiveUrlMain);
144
- if (!response.ok) {
145
- console.log(`[PluginManager] Ветка 'main' не найдена для ${repoUrl}, пробую 'master'...`);
146
- response = await fetch(archiveUrlMaster);
160
+ response = await fetch(archiveUrlMain);
147
161
  if (!response.ok) {
148
- throw new Error(`Не удалось скачать архив плагина. Статус: ${response.status}`);
162
+ console.log(`[PluginManager] Ветка 'main' не найдена для ${repoUrl}, пробую 'master'...`);
163
+ response = await fetch(archiveUrlMaster);
164
+ if (!response.ok) {
165
+ throw new Error(`Не удалось скачать архив плагина. Статус: ${response.status}`);
166
+ }
149
167
  }
150
168
  }
169
+
151
170
  const buffer = await response.arrayBuffer();
152
171
 
153
172
  const zip = new AdmZip(Buffer.from(buffer));
@@ -324,6 +343,7 @@ class PluginManager {
324
343
  sourceUri: plugin.sourceUri,
325
344
  currentVersion: localVersion,
326
345
  recommendedVersion: recommendedVersion,
346
+ latestTag: catalogInfo.latestTag, // 🏷️ Добавляем тег для использования при обновлении
327
347
  });
328
348
  }
329
349
  } catch (error) {
@@ -333,21 +353,51 @@ class PluginManager {
333
353
  return updatesAvailable;
334
354
  }
335
355
 
336
- async updatePlugin(pluginId) {
356
+ async updatePlugin(pluginId, targetTag = null) {
337
357
  const plugin = await prisma.installedPlugin.findUnique({ where: { id: pluginId } });
338
358
  if (!plugin || plugin.sourceType !== 'GITHUB') {
339
359
  throw new Error('Плагин не найден или не является GitHub-плагином.');
340
360
  }
341
361
 
342
- console.log(`[PluginManager] Начало обновления плагина ${plugin.name}...`);
362
+ console.log(`[PluginManager] Начало обновления плагина ${plugin.name}${targetTag ? ` до версии ${targetTag}` : ''}...`);
343
363
 
344
364
  const repoUrl = plugin.sourceUri;
345
365
  const botId = plugin.botId;
346
366
 
367
+ // Сохраняем настройки и важные данные перед удалением
368
+ const backupData = {
369
+ name: plugin.name,
370
+ settings: plugin.settings,
371
+ isEnabled: plugin.isEnabled,
372
+ // PluginDataStore сохранятся автоматически (привязаны к pluginName + botId)
373
+ };
374
+ console.log(`[PluginManager] Настройки плагина ${plugin.name} сохранены для миграции.`);
375
+
376
+ // Удаляем старую версию
347
377
  await this.deletePlugin(pluginId);
348
378
  console.log(`[PluginManager] Старая версия ${plugin.name} удалена, устанавливаем новую...`);
349
379
 
350
- return await this.installFromGithub(botId, repoUrl, prisma, true);
380
+ // Устанавливаем новую версию с конкретным тегом (если указан)
381
+ const newPlugin = await this.installFromGithub(botId, repoUrl, prisma, true, targetTag);
382
+
383
+ // Восстанавливаем настройки
384
+ if (backupData.settings && newPlugin) {
385
+ try {
386
+ await prisma.installedPlugin.update({
387
+ where: { id: newPlugin.id },
388
+ data: {
389
+ settings: backupData.settings,
390
+ isEnabled: backupData.isEnabled,
391
+ },
392
+ });
393
+ console.log(`[PluginManager] Настройки успешно восстановлены для ${plugin.name}`);
394
+ } catch (settingsError) {
395
+ console.error(`[PluginManager] Не удалось восстановить настройки для ${plugin.name}:`, settingsError);
396
+ // Не бросаем ошибку, т.к. плагин уже установлен
397
+ }
398
+ }
399
+
400
+ return newPlugin;
351
401
  }
352
402
 
353
403
  async loadPluginGraphs(botId, pluginId, pluginPath) {
@@ -0,0 +1,32 @@
1
+ const { PrismaClient } = require('@prisma/client');
2
+
3
+ /**
4
+ * Singleton service для PrismaClient
5
+ * Предотвращает утечки памяти используя одно соединение с БД
6
+ * Благодаря кешированию require в Node.js это фактический singleton
7
+ */
8
+ class PrismaService {
9
+ constructor() {
10
+ this.prisma = new PrismaClient({
11
+ log: ['error', 'warn'],
12
+ });
13
+ }
14
+
15
+ /**
16
+ * Получить экземпляр Prisma client
17
+ * @returns {PrismaClient}
18
+ */
19
+ getClient() {
20
+ return this.prisma;
21
+ }
22
+
23
+ /**
24
+ * Отключиться от БД (вызывать при выключении приложения)
25
+ */
26
+ async disconnect() {
27
+ await this.prisma.$disconnect();
28
+ }
29
+ }
30
+
31
+ const prismaService = new PrismaService();
32
+ module.exports = prismaService;
@@ -10,15 +10,15 @@ class User {
10
10
  constructor(userInstance, botConfig = {}) {
11
11
  this.user = userInstance;
12
12
  this.botConfig = botConfig;
13
-
13
+
14
14
  const globalOwners = ["merka", "akrem"];
15
15
  const keksikServers = ["mc.mineblaze.net", "mc.masedworld.net", "mc.cheatmine.net", "mc.dexland.org"];
16
-
16
+
17
17
  const botOwners = (this.botConfig.owners || '').toLowerCase().split(',').map(s => s.trim()).filter(Boolean);
18
18
  const usernameLower = this.user.username.toLowerCase();
19
19
 
20
20
  this.isOwner = botOwners.includes(usernameLower) || (keksikServers.includes(this.botConfig.server?.host) && globalOwners.includes(usernameLower));
21
-
21
+
22
22
  this.permissionsSet = new Set();
23
23
  if (this.user.groups) {
24
24
  this.user.groups.forEach(userGroup => {
@@ -0,0 +1,24 @@
1
+ const prismaService = require('../PrismaService');
2
+
3
+ describe('PrismaService', () => {
4
+ it('should return singleton instance', () => {
5
+ const service1 = require('../PrismaService');
6
+ const service2 = require('../PrismaService');
7
+
8
+ expect(service1).toBe(service2);
9
+ });
10
+
11
+ it('should provide getClient method', () => {
12
+ const client = prismaService.getClient();
13
+
14
+ expect(client).toBeDefined();
15
+ expect(typeof client.$connect).toBe('function');
16
+ });
17
+
18
+ it('should reuse same client instance', () => {
19
+ const client1 = prismaService.getClient();
20
+ const client2 = prismaService.getClient();
21
+
22
+ expect(client1).toBe(client2);
23
+ });
24
+ });
@@ -0,0 +1,305 @@
1
+
2
+
3
+ > ⚠️ **АХТУНГ**: ДОКУМЕНТАЦИЯ СГЕНЕРИРОВАНА @CLAUDE.
4
+
5
+ # Создание команд для BlockMine
6
+
7
+ Система команд BlockMine поддерживает две сигнатуры для handler'ов: **старую** (обратно совместимую) и **новую** (с CommandContext).
8
+
9
+ ## 📋 Две сигнатуры команд
10
+
11
+ ### 1️⃣ Старая сигнатура (рекомендуется для простых команд)
12
+
13
+ ```javascript
14
+ async handler(bot, typeChat, user, args) {
15
+ // bot - экземпляр бота
16
+ // typeChat - тип чата ('chat', 'clan', 'private', 'websocket', etc)
17
+ // user - User объект с методами (hasPermission, addGroup, etc)
18
+ // args - объект с аргументами команды
19
+
20
+ const message = `Привет, ${user.username}!`;
21
+
22
+ // Для WebSocket API нужно вернуть результат
23
+ if (typeChat === 'websocket') {
24
+ return message;
25
+ }
26
+
27
+ // Для остальных отправляем в чат
28
+ bot.sendMessage(typeChat, message, user.username);
29
+ }
30
+ ```
31
+
32
+ ### 2️⃣ Новая сигнатура (рекомендуется для универсальных команд)
33
+
34
+ ```javascript
35
+ async handler(context) {
36
+ // context.bot - экземпляр бота
37
+ // context.user - User объект с методами
38
+ // context.args - объект с аргументами
39
+ // context.transport - Transport объект
40
+ // context.typeChat - тип чата (для совместимости)
41
+
42
+ const message = `Привет, ${context.user.username}!`;
43
+
44
+ // context.reply() автоматически работает для всех транспортов
45
+ return context.reply(message);
46
+ }
47
+ ```
48
+
49
+ ## ✨ Автоматическое определение сигнатуры
50
+
51
+ Система **автоматически** определяет какую сигнатуру использует команда:
52
+
53
+ - **4 параметра** (`handler(bot, typeChat, user, args)`) → старая сигнатура
54
+ - **1 параметр** (`handler(context)`) → новая сигнатура
55
+
56
+ Вы можете использовать любую из них!
57
+
58
+ ## 📖 Примеры команд
59
+
60
+ ### Пример 1: Простая команда (старая сигнатура)
61
+
62
+ ```javascript
63
+ const Command = require('../system/Command');
64
+
65
+ class HelloCommand extends Command {
66
+ constructor() {
67
+ super({
68
+ name: 'hello',
69
+ description: 'Поздороваться с пользователем',
70
+ aliases: ['hi', 'привет'],
71
+ cooldown: 5,
72
+ permissions: 'user.say',
73
+ owner: 'system',
74
+ allowedChatTypes: ['chat', 'clan', 'private', 'websocket'],
75
+ args: []
76
+ });
77
+ }
78
+
79
+ async handler(bot, typeChat, user) {
80
+ const message = `Привет, ${user.username}!`;
81
+
82
+ if (typeChat === 'websocket') {
83
+ return message;
84
+ }
85
+
86
+ bot.sendMessage(typeChat, message, user.username);
87
+ }
88
+ }
89
+
90
+ module.exports = HelloCommand;
91
+ ```
92
+
93
+ ### Пример 2: Команда с аргументами (старая сигнатура)
94
+
95
+ ```javascript
96
+ const Command = require('../system/Command');
97
+
98
+ class SayCommand extends Command {
99
+ constructor() {
100
+ super({
101
+ name: 'say',
102
+ description: 'Отправить сообщение от имени бота',
103
+ cooldown: 3,
104
+ permissions: 'admin.say',
105
+ owner: 'system',
106
+ allowedChatTypes: ['chat', 'clan', 'websocket'],
107
+ args: [
108
+ {
109
+ name: 'message',
110
+ type: 'greedy_string',
111
+ required: true,
112
+ description: 'Текст сообщения'
113
+ }
114
+ ]
115
+ });
116
+ }
117
+
118
+ async handler(bot, typeChat, user, { message }) {
119
+ if (typeChat === 'websocket') {
120
+ bot.sendMessage('chat', message);
121
+ return `Сообщение отправлено: "${message}"`;
122
+ }
123
+
124
+ bot.sendMessage('chat', message);
125
+ }
126
+ }
127
+
128
+ module.exports = SayCommand;
129
+ ```
130
+
131
+ ### Пример 3: Универсальная команда (новая сигнатура)
132
+
133
+ ```javascript
134
+ const Command = require('../system/Command');
135
+
136
+ class InfoCommand extends Command {
137
+ constructor() {
138
+ super({
139
+ name: 'info',
140
+ description: 'Информация о пользователе',
141
+ cooldown: 10,
142
+ permissions: 'user.info',
143
+ owner: 'system',
144
+ allowedChatTypes: ['chat', 'private', 'websocket'],
145
+ args: [
146
+ {
147
+ name: 'target',
148
+ type: 'string',
149
+ required: false,
150
+ description: 'Имя пользователя'
151
+ }
152
+ ]
153
+ });
154
+ }
155
+
156
+ async handler(context) {
157
+ const targetUsername = context.args.target || context.user.username;
158
+
159
+ // Получаем данные о пользователе
160
+ const targetUser = await context.bot.api.getUser(targetUsername);
161
+
162
+ const groups = targetUser.groups.map(g => g.group.name).join(', ');
163
+ const message = `👤 ${targetUser.username}\n📋 Группы: ${groups}`;
164
+
165
+ // Автоматически работает для всех транспортов
166
+ return context.reply(message);
167
+ }
168
+ }
169
+
170
+ module.exports = InfoCommand;
171
+ ```
172
+
173
+ ### Пример 4: Команда с методами User (новая сигнатура)
174
+
175
+ ```javascript
176
+ const Command = require('../system/Command');
177
+
178
+ class PromoteCommand extends Command {
179
+ constructor() {
180
+ super({
181
+ name: 'promote',
182
+ description: 'Повысить пользователя до VIP',
183
+ cooldown: 0,
184
+ permissions: 'admin.promote',
185
+ owner: 'system',
186
+ allowedChatTypes: ['chat', 'private', 'websocket'],
187
+ args: [
188
+ {
189
+ name: 'username',
190
+ type: 'string',
191
+ required: true,
192
+ description: 'Имя пользователя'
193
+ }
194
+ ]
195
+ });
196
+ }
197
+
198
+ async handler(context) {
199
+ const targetUsername = context.args.username;
200
+
201
+ // Получаем полноценный User объект с методами
202
+ const targetUser = await context.bot.api.getUser(targetUsername);
203
+
204
+ // Используем методы User
205
+ if (targetUser.hasPermission('vip.*')) {
206
+ return context.reply(`${targetUsername} уже VIP!`);
207
+ }
208
+
209
+ await targetUser.addGroup('vip');
210
+ return context.reply(`✅ ${targetUsername} повышен до VIP!`);
211
+ }
212
+ }
213
+
214
+ module.exports = PromoteCommand;
215
+ ```
216
+
217
+ ## 🔄 Transport и CommandContext API
218
+
219
+ ### CommandContext
220
+
221
+ ```javascript
222
+ class CommandContext {
223
+ bot // Экземпляр бота
224
+ user // User объект с методами
225
+ args // Объект с аргументами
226
+ transport // Transport объект
227
+ typeChat // Тип чата (для обратной совместимости)
228
+
229
+ // Методы
230
+ reply(message) // Отправить ответ пользователю
231
+ sendTo(chatType, message, recipient) // Отправить в конкретный чат
232
+ isWebSocket() // Проверка на WebSocket API
233
+ isMinecraft() // Проверка на Minecraft
234
+ getTransportName() // Получить название транспорта
235
+ }
236
+ ```
237
+
238
+ ### Transport
239
+
240
+ ```javascript
241
+ class Transport {
242
+ type // 'websocket' | 'chat' | 'clan' | 'private' | 'telegram'
243
+ bot // Экземпляр бота
244
+
245
+ // Методы
246
+ send(message, recipient) // Отправить сообщение
247
+ isMinecraftTransport() // Проверка на Minecraft
248
+ isUniversal() // Проверка на универсальный транспорт
249
+ isAllowedFor(allowedTypes) // Проверка разрешений
250
+ getDisplayName() // Получить читаемое название
251
+ }
252
+ ```
253
+
254
+ ## 🎯 Когда использовать какую сигнатуру?
255
+
256
+ ### Используйте **старую сигнатуру** если:
257
+ - ✅ Команда простая и не требует сложной логики
258
+ - ✅ Не нужны методы User (hasPermission, addGroup, etc)
259
+ - ✅ Вы портируете существующие команды
260
+ - ✅ Команда работает только в Minecraft
261
+
262
+ ### Используйте **новую сигнатуру** если:
263
+ - ✅ Команда должна работать везде (Minecraft, WebSocket)
264
+ - ✅ Нужны методы User (для управления группами, проверки прав и т.д.)
265
+ - ✅ Команда сложная и требует чистого кода
266
+ - ✅ Вы пишете новую команду с нуля
267
+
268
+ ## 🚀 Будущие транспорты
269
+
270
+ Архитектура готова к добавлению новых транспортов:
271
+
272
+ - **WebSocket API** ✅ (уже работает)
273
+ - **Minecraft** ✅ (уже работает)
274
+
275
+ Команды с новой сигнатурой (`handler(context)`) будут **автоматически** работать во всех транспортах!
276
+
277
+ ## 📝 Важные замечания
278
+
279
+ 1. **User восстановление**: User объект полностью восстанавливается в child process с помощью `UserService.getUser()`, поэтому все методы класса User доступны в командах.
280
+
281
+ 2. **Кэширование User**: UserService использует кэш, поэтому повторные вызовы `getUser()` не создают лишних запросов к БД.
282
+
283
+ 3. **WebSocket результаты**: Для WebSocket API команды должны либо **вернуть** результат через `return`, либо вызвать `context.reply()` (в новой сигнатуре).
284
+
285
+ 4. **Обратная совместимость**: Все существующие команды продолжают работать без изменений!
286
+
287
+ ## 🔍 Как система определяет сигнатуру
288
+
289
+ Магия в `BotProcess.js`:
290
+
291
+ ```javascript
292
+ // Проверяем количество параметров функции handler
293
+ const handlerParamCount = commandInstance.handler.length;
294
+
295
+ if (handlerParamCount === 1) {
296
+ // Новая сигнатура: handler(context)
297
+ const context = new CommandContext(bot, user, args, transport);
298
+ await commandInstance.handler(context);
299
+ } else {
300
+ // Старая сигнатура: handler(bot, typeChat, user, args)
301
+ await commandInstance.handler(bot, typeChat, user, args);
302
+ }
303
+ ```
304
+
305
+ Система **автоматически** выбирает правильный способ вызова!
@@ -14,29 +14,29 @@ class DevCommand extends Command {
14
14
  cooldown: 10,
15
15
  permissions: 'user.say',
16
16
  owner: 'system',
17
- allowedChatTypes: ['chat', 'local', 'clan', 'private'],
17
+ allowedChatTypes: ['chat', 'local', 'clan', 'private', 'websocket'],
18
18
  args: []
19
19
  });
20
20
  }
21
21
 
22
22
  // Переопределяем метод для кастомного сообщения при отсутствии прав
23
23
  onInsufficientPermissions(bot, typeChat, user) {
24
- bot.api.sendMessage(typeChat, `${user.username}, у вас нет прав для этой команды.`, user.username);
24
+ bot.sendMessage(typeChat, `${user.username}, у вас нет прав для этой команды.`, user.username);
25
25
  }
26
26
 
27
27
  // Переопределяем метод для неправильного типа чата
28
28
  onWrongChatType(bot, typeChat, user) {
29
- bot.api.sendMessage('private', `${user.username}, команду dev нельзя использовать в чате типа "${typeChat}"`, user.username);
29
+ bot.sendMessage('private', `${user.username}, команду dev нельзя использовать в чате типа "${typeChat}"`, user.username);
30
30
  }
31
31
 
32
32
  // Переопределяем метод для кулдауна
33
33
  onCooldown(bot, typeChat, user, timeLeft) {
34
- bot.api.sendMessage(typeChat, `${user.username}, подождите еще ${timeLeft} секунд перед повторным использованием команды.`, user.username);
34
+ bot.sendMessage(typeChat, `${user.username}, подождите еще ${timeLeft} секунд перед повторным использованием команды.`, user.username);
35
35
  }
36
36
 
37
37
  // Переопределяем метод для черного списка (по умолчанию ничего не отправляется)
38
38
  onBlacklisted(bot, typeChat, user) {
39
- bot.api.sendMessage(typeChat, `${user.username}, вы находитесь в черном списке.`, user.username);
39
+ bot.sendMessage(typeChat, `${user.username}, вы находитесь в черном списке.`, user.username);
40
40
  }
41
41
 
42
42
  async handler(bot, typeChat, user) {
@@ -52,14 +52,20 @@ class DevCommand extends Command {
52
52
  }
53
53
 
54
54
  const enabledPluginsCount = bot.config.plugins.length;
55
-
55
+
56
56
  const uniqueCommands = new Set();
57
57
  for (const command of bot.commands.values()) {
58
58
  uniqueCommands.add(command.name);
59
59
  }
60
60
  const totalCommandsCount = uniqueCommands.size;
61
61
 
62
- bot.api.sendMessage(typeChat, `Бот создан с помощью - BlockMine. Версия: v${appVersion}. Активных плагинов: ${enabledPluginsCount}. Всего команд: ${totalCommandsCount}`, user.username);
62
+ const message = `Бот создан с помощью - BlockMine. Версия: v${appVersion}. Активных плагинов: ${enabledPluginsCount}. Всего команд: ${totalCommandsCount}`;
63
+
64
+ if (typeChat === 'websocket') {
65
+ return message;
66
+ }
67
+
68
+ bot.sendMessage(typeChat, message, user.username);
63
69
  }
64
70
  }
65
71
 
@@ -9,7 +9,7 @@ class PingCommand extends Command {
9
9
  cooldown: 5,
10
10
  permissions: 'user.ping',
11
11
  owner: 'system',
12
- allowedChatTypes: ['local', 'clan', 'private'],
12
+ allowedChatTypes: ['local', 'clan', 'private', 'websocket'],
13
13
 
14
14
  args: [
15
15
  {
@@ -23,12 +23,18 @@ class PingCommand extends Command {
23
23
  }
24
24
 
25
25
  async handler(bot, typeChat, user, { target }) {
26
-
26
+ let message;
27
27
  if (target) {
28
- bot.api.sendMessage(typeChat, `Понг, ${user.username}! Пингую игрока ${target}.`, user.username);
28
+ message = `Понг, ${user.username}! Пингую игрока ${target}.`;
29
29
  } else {
30
- bot.api.sendMessage(typeChat, `Понг, ${user.username}!`, user.username);
30
+ message = `Понг, ${user.username}!`;
31
+ }
32
+
33
+ if (typeChat === 'websocket') {
34
+ return message;
31
35
  }
36
+
37
+ bot.sendMessage(typeChat, message, user.username);
32
38
  }
33
39
  }
34
40
 
@@ -0,0 +1,63 @@
1
+ const Command = require('../system/Command');
2
+
3
+ class WhoisCommand extends Command {
4
+ constructor() {
5
+ super({
6
+ name: 'whois',
7
+ description: 'Показывает информацию о пользователе',
8
+ aliases: ['userinfo', 'кто'],
9
+ cooldown: 5,
10
+ permissions: 'user.whois',
11
+ owner: 'system',
12
+ allowedChatTypes: ['chat', 'local', 'clan', 'private', 'websocket'],
13
+ args: [
14
+ {
15
+ name: 'username',
16
+ type: 'string',
17
+ required: false,
18
+ description: 'Имя пользователя (по умолчанию - вы)'
19
+ }
20
+ ]
21
+ });
22
+ }
23
+
24
+ async handler(context) {
25
+ const targetUsername = context.args.username || context.user.username;
26
+
27
+ try {
28
+ const targetUser = await context.getUser(targetUsername);
29
+
30
+ // Получаем список групп
31
+ const groups = targetUser.groups
32
+ .map(ug => ug.group.name)
33
+ .join(', ') || 'Нет групп';
34
+
35
+ // Статус
36
+ const status = targetUser.isBlacklisted ? '⛔ В черном списке' : '✅ Активен';
37
+
38
+ // Форматируем вывод в зависимости от транспорта
39
+ let message;
40
+
41
+ if (context.isWebSocket()) {
42
+ // Для WebSocket API возвращаем структурированные данные
43
+ message = {
44
+ username: targetUser.username,
45
+ isOwner: targetUser.isOwner,
46
+ isBlacklisted: targetUser.isBlacklisted,
47
+ groups: targetUser.groups.map(ug => ug.group.name),
48
+ status: status
49
+ };
50
+ } else {
51
+ message = `${targetUser.username} | Группы: ${groups} | ${status}`;
52
+ }
53
+
54
+ return context.reply(message);
55
+
56
+ } catch (error) {
57
+ const errorMsg = `❌ Ошибка: ${error.message}`;
58
+ return context.reply(errorMsg);
59
+ }
60
+ }
61
+ }
62
+
63
+ module.exports = WhoisCommand;