blockmine 1.24.0 → 1.27.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 (476) hide show
  1. package/CHANGELOG.md +76 -1
  2. package/README.en.md +427 -0
  3. package/README.md +40 -0
  4. package/backend/package.json +2 -2
  5. package/backend/prisma/migrations/20260328173000_add_plugin_source_ref/migration.sql +2 -0
  6. package/backend/prisma/migrations/migration_lock.toml +2 -2
  7. package/backend/prisma/schema.prisma +2 -0
  8. package/backend/src/ai/plugin-assistant-system-prompt.md +664 -5
  9. package/backend/src/api/routes/apiKeys.js +8 -0
  10. package/backend/src/api/routes/bots.js +271 -9
  11. package/backend/src/api/routes/eventGraphs.js +151 -1
  12. package/backend/src/api/routes/health.js +38 -0
  13. package/backend/src/api/routes/nodeRegistry.js +63 -0
  14. package/backend/src/api/routes/plugins.js +254 -29
  15. package/backend/src/api/routes/servers.js +14 -2
  16. package/backend/src/container.js +11 -8
  17. package/backend/src/core/BotCommandLoader.js +161 -0
  18. package/backend/src/core/BotConnection.js +125 -0
  19. package/backend/src/core/BotEventHandlers.js +234 -0
  20. package/backend/src/core/BotIPCHandler.js +445 -0
  21. package/backend/src/core/BotManager.js +15 -7
  22. package/backend/src/core/BotProcess.js +169 -140
  23. package/backend/src/core/EventGraphManager.js +7 -3
  24. package/backend/src/core/GraphDebugHandler.js +229 -0
  25. package/backend/src/core/GraphDebugIPC.js +117 -0
  26. package/backend/src/core/GraphExecutionEngine.js +545 -978
  27. package/backend/src/core/GraphTraversal.js +80 -0
  28. package/backend/src/core/GraphValidation.js +73 -0
  29. package/backend/src/core/NodeDefinition.js +138 -0
  30. package/backend/src/core/NodeRegistry.js +153 -141
  31. package/backend/src/core/PluginLoader.js +83 -3
  32. package/backend/src/core/PluginManager.js +346 -35
  33. package/backend/src/core/RewindSignal.js +9 -0
  34. package/backend/src/core/config/ConfigValidator.js +72 -0
  35. package/backend/src/core/config/FeatureFlags.js +52 -0
  36. package/backend/src/core/config/__tests__/ConfigValidator.test.js +232 -0
  37. package/backend/src/core/domain/entities/Bot.js +39 -0
  38. package/backend/src/core/domain/entities/Command.js +41 -0
  39. package/backend/src/core/domain/entities/EventGraph.js +39 -0
  40. package/backend/src/core/domain/entities/Plugin.js +45 -0
  41. package/backend/src/core/domain/entities/User.js +40 -0
  42. package/backend/src/core/domain/services/DependencyResolver.js +168 -0
  43. package/backend/src/core/domain/services/GraphValidator.js +117 -0
  44. package/backend/src/core/domain/services/PermissionChecker.js +34 -0
  45. package/backend/src/core/domain/services/__tests__/DependencyResolver.test.js +126 -0
  46. package/backend/src/core/domain/valueObjects/BotConfig.js +27 -0
  47. package/backend/src/core/domain/valueObjects/DependencyGraph.js +86 -0
  48. package/backend/src/core/domain/valueObjects/PluginManifest.js +36 -0
  49. package/backend/src/core/errors/BaseError.js +29 -0
  50. package/backend/src/core/errors/ErrorHandler.js +81 -0
  51. package/backend/src/core/errors/__tests__/ErrorHandler.test.js +188 -0
  52. package/backend/src/core/errors/index.js +68 -0
  53. package/backend/src/core/infrastructure/BatchingUtility.js +66 -0
  54. package/backend/src/core/infrastructure/CircuitBreaker.js +103 -0
  55. package/backend/src/core/infrastructure/ConnectionPool.js +81 -0
  56. package/backend/src/core/infrastructure/RateLimiter.js +64 -0
  57. package/backend/src/core/infrastructure/__tests__/BatchingUtility.test.js +86 -0
  58. package/backend/src/core/infrastructure/__tests__/CircuitBreaker.test.js +156 -0
  59. package/backend/src/core/infrastructure/__tests__/ConnectionPool.test.js +146 -0
  60. package/backend/src/core/infrastructure/__tests__/RateLimiter.test.js +171 -0
  61. package/backend/src/core/ipc/botApiFactory.js +72 -0
  62. package/backend/src/core/ipc/ipcMessageTypes.js +115 -0
  63. package/backend/src/core/logging/AuditLogger.js +61 -0
  64. package/backend/src/core/logging/StructuredLogger.js +80 -0
  65. package/backend/src/core/logging/__tests__/StructuredLogger.test.js +213 -0
  66. package/backend/src/core/logging/index.js +7 -0
  67. package/backend/src/core/metrics/MetricsCollector.js +104 -0
  68. package/backend/src/core/metrics/__tests__/MetricsCollector.test.js +131 -0
  69. package/backend/src/core/node-registries/actionsNodes.js +191 -0
  70. package/backend/src/core/node-registries/arraysNodes.js +152 -0
  71. package/backend/src/core/node-registries/botNodes.js +48 -0
  72. package/backend/src/core/node-registries/containerNodes.js +141 -0
  73. package/backend/src/core/node-registries/dataNodes.js +284 -0
  74. package/backend/src/core/node-registries/debugNodes.js +23 -0
  75. package/backend/src/core/node-registries/eventsNodes.js +223 -0
  76. package/backend/src/core/node-registries/flowNodes.js +151 -0
  77. package/backend/src/core/node-registries/furnaceNodes.js +123 -0
  78. package/backend/src/core/node-registries/index.js +108 -0
  79. package/backend/src/core/node-registries/inventory.js +102 -106
  80. package/backend/src/core/node-registries/logicNodes.js +54 -0
  81. package/backend/src/core/node-registries/mathNodes.js +38 -0
  82. package/backend/src/core/node-registries/navigationNodes.js +109 -0
  83. package/backend/src/core/node-registries/objectsNodes.js +90 -0
  84. package/backend/src/core/node-registries/stringsNodes.js +165 -0
  85. package/backend/src/core/node-registries/timeNodes.js +105 -0
  86. package/backend/src/core/node-registries/typeNodes.js +22 -0
  87. package/backend/src/core/node-registries/usersNodes.js +126 -0
  88. package/backend/src/core/nodes/arrays/shuffle.js +14 -0
  89. package/backend/src/core/nodes/bot/get_name.js +8 -0
  90. package/backend/src/core/nodes/bot/stop_bot.js +5 -0
  91. package/backend/src/core/nodes/container/open.js +101 -111
  92. package/backend/src/core/nodes/data/store_read.js +26 -0
  93. package/backend/src/core/nodes/data/store_write.js +23 -0
  94. package/backend/src/core/nodes/event/call_event.js +31 -0
  95. package/backend/src/core/nodes/event/custom_event.js +8 -0
  96. package/backend/src/core/nodes/flow/timer.js +35 -0
  97. package/backend/src/core/nodes/inventory/drop.js +73 -65
  98. package/backend/src/core/nodes/inventory/equip.js +54 -45
  99. package/backend/src/core/nodes/inventory/select_slot.js +48 -46
  100. package/backend/src/core/nodes/navigation/follow.js +54 -51
  101. package/backend/src/core/nodes/navigation/go_to.js +41 -53
  102. package/backend/src/core/nodes/navigation/go_to_entity.js +65 -69
  103. package/backend/src/core/nodes/navigation/go_to_player.js +65 -70
  104. package/backend/src/core/nodes/navigation/stop.js +17 -26
  105. package/backend/src/core/nodes/users/add_to_group.js +24 -0
  106. package/backend/src/core/nodes/users/check_permission.js +26 -0
  107. package/backend/src/core/nodes/users/remove_from_group.js +24 -0
  108. package/backend/src/core/services/BotIPCMessageRouter.js +337 -0
  109. package/backend/src/core/services/BotLifecycleService.js +43 -450
  110. package/backend/src/core/services/CacheManager.js +83 -23
  111. package/backend/src/core/services/CrashRestartManager.js +42 -0
  112. package/backend/src/core/services/DebugSessionManager.js +114 -12
  113. package/backend/src/core/services/EventGraphService.js +69 -0
  114. package/backend/src/core/services/MinecraftBotManager.js +9 -1
  115. package/backend/src/core/services/PluginManagementService.js +84 -0
  116. package/backend/src/core/services/TestModeContext.js +65 -0
  117. package/backend/src/core/services/__tests__/CacheManager.test.js +168 -0
  118. package/backend/src/core/services.js +1 -11
  119. package/backend/src/core/validation/InputValidator.js +167 -0
  120. package/backend/src/core/validation/__tests__/InputValidator.test.js +296 -0
  121. package/backend/src/real-time/botApi/index.js +1 -1
  122. package/backend/src/real-time/socketHandler.js +26 -0
  123. package/backend/src/server.js +21 -6
  124. package/frontend/dist/assets/browser-ponyfill-D8y0Ty7C.js +2 -0
  125. package/frontend/dist/assets/index-CFJLS0dk.css +32 -0
  126. package/frontend/dist/assets/index-D91UGNMG.js +11260 -0
  127. package/frontend/dist/flags/en.svg +32 -0
  128. package/frontend/dist/flags/ru.svg +5 -0
  129. package/frontend/dist/index.html +2 -2
  130. package/frontend/dist/locales/en/admin.json +100 -0
  131. package/frontend/dist/locales/en/api-keys.json +58 -0
  132. package/frontend/dist/locales/en/bots.json +113 -0
  133. package/frontend/dist/locales/en/common.json +53 -0
  134. package/frontend/dist/locales/en/configuration.json +22 -0
  135. package/frontend/dist/locales/en/console.json +10 -0
  136. package/frontend/dist/locales/en/dashboard.json +85 -0
  137. package/frontend/dist/locales/en/dialogs.json +70 -0
  138. package/frontend/dist/locales/en/event-graphs.json +50 -0
  139. package/frontend/dist/locales/en/graph-store.json +70 -0
  140. package/frontend/dist/locales/en/login.json +36 -0
  141. package/frontend/dist/locales/en/management.json +192 -0
  142. package/frontend/dist/locales/en/minecraft-viewer.json +27 -0
  143. package/frontend/dist/locales/en/nodes.json +1132 -0
  144. package/frontend/dist/locales/en/permissions.json +50 -0
  145. package/frontend/dist/locales/en/plugin-detail.json +69 -0
  146. package/frontend/dist/locales/en/plugins.json +329 -0
  147. package/frontend/dist/locales/en/proxies.json +81 -0
  148. package/frontend/dist/locales/en/servers.json +39 -0
  149. package/frontend/dist/locales/en/setup.json +19 -0
  150. package/frontend/dist/locales/en/sidebar.json +195 -0
  151. package/frontend/dist/locales/en/tasks.json +62 -0
  152. package/frontend/dist/locales/en/visual-editor.json +418 -0
  153. package/frontend/dist/locales/en/websocket.json +86 -0
  154. package/frontend/dist/locales/ru/admin.json +100 -0
  155. package/frontend/dist/locales/ru/api-keys.json +58 -0
  156. package/frontend/dist/locales/ru/bots.json +113 -0
  157. package/frontend/dist/locales/ru/common.json +49 -0
  158. package/frontend/dist/locales/ru/configuration.json +22 -0
  159. package/frontend/dist/locales/ru/console.json +10 -0
  160. package/frontend/dist/locales/ru/dashboard.json +85 -0
  161. package/frontend/dist/locales/ru/dialogs.json +70 -0
  162. package/frontend/dist/locales/ru/event-graphs.json +50 -0
  163. package/frontend/dist/locales/ru/graph-store.json +70 -0
  164. package/frontend/dist/locales/ru/login.json +36 -0
  165. package/frontend/dist/locales/ru/management.json +192 -0
  166. package/frontend/dist/locales/ru/minecraft-viewer.json +30 -0
  167. package/frontend/dist/locales/ru/nodes.json +1131 -0
  168. package/frontend/dist/locales/ru/permissions.json +50 -0
  169. package/frontend/dist/locales/ru/plugin-detail.json +49 -0
  170. package/frontend/dist/locales/ru/plugins.json +209 -0
  171. package/frontend/dist/locales/ru/proxies.json +81 -0
  172. package/frontend/dist/locales/ru/servers.json +39 -0
  173. package/frontend/dist/locales/ru/setup.json +19 -0
  174. package/frontend/dist/locales/ru/sidebar.json +195 -0
  175. package/frontend/dist/locales/ru/tasks.json +62 -0
  176. package/frontend/dist/locales/ru/visual-editor.json +420 -0
  177. package/frontend/dist/locales/ru/websocket.json +86 -0
  178. package/frontend/dist/monacoeditorwork/css.worker.bundle.js +7 -7
  179. package/frontend/dist/monacoeditorwork/html.worker.bundle.js +7 -7
  180. package/frontend/dist/monacoeditorwork/json.worker.bundle.js +7 -7
  181. package/frontend/dist/monacoeditorwork/ts.worker.bundle.js +3 -3
  182. package/frontend/package.json +6 -0
  183. package/nul +12 -0
  184. package/package.json +3 -3
  185. package/screen/3dviewer.png +0 -0
  186. package/screen/console.png +0 -0
  187. package/screen/dashboard.png +0 -0
  188. package/screen/graph_collabe.png +0 -0
  189. package/screen/graph_live_debug.png +0 -0
  190. package/screen/language_selector.png +0 -0
  191. package/screen/management_command.png +0 -0
  192. package/screen/node_debug_trace.png +0 -0
  193. package/screen/plugin_/320/276/320/261/320/267/320/276/321/200.png +0 -0
  194. package/screen/websocket.png +0 -0
  195. package/screen//320/275/320/260/321/201/321/202/321/200/320/276/320/271/320/272/320/270_/320/276/321/202/320/264/320/265/320/273/321/214/320/275/321/213/321/205_/320/272/320/276/320/274/320/260/320/275/320/264_/320/272/320/260/320/266/320/264/321/203_/320/272/320/276/320/274/320/260/320/275/320/273/320/264/321/203_/320/274/320/276/320/266/320/275/320/276_/320/275/320/260/321/201/321/202/321/200/320/260/320/270/320/262/320/260/321/202/321/214.png +0 -0
  196. package/screen//320/277/320/273/320/260/320/275/320/270/321/200/320/276/320/262/321/211/320/270/320/272_/320/274/320/276/320/266/320/275/320/276_/320/267/320/260/320/264/320/260/320/262/320/260/321/202/321/214_/320/264/320/265/320/271/321/201/321/202/320/262/320/270/321/217_/320/277/320/276_/320/262/321/200/320/265/320/274/320/265/320/275/320/270.png +0 -0
  197. package/.claude/agents/README.md +0 -469
  198. package/.claude/agents/auth-route-debugger.md +0 -118
  199. package/.claude/agents/auth-route-tester.md +0 -93
  200. package/.claude/agents/auto-error-resolver.md +0 -97
  201. package/.claude/agents/build-optimizer.md +0 -236
  202. package/.claude/agents/code-architect.md +0 -34
  203. package/.claude/agents/code-architecture-reviewer.md +0 -83
  204. package/.claude/agents/code-explorer.md +0 -51
  205. package/.claude/agents/code-refactor-master.md +0 -94
  206. package/.claude/agents/code-reviewer.md +0 -46
  207. package/.claude/agents/cost-optimizer.md +0 -134
  208. package/.claude/agents/deployment-orchestrator.md +0 -113
  209. package/.claude/agents/documentation-architect.md +0 -82
  210. package/.claude/agents/frontend-error-fixer.md +0 -77
  211. package/.claude/agents/iac-code-generator.md +0 -71
  212. package/.claude/agents/incident-responder.md +0 -346
  213. package/.claude/agents/infrastructure-architect.md +0 -31
  214. package/.claude/agents/kubernetes-specialist.md +0 -56
  215. package/.claude/agents/migration-planner.md +0 -181
  216. package/.claude/agents/network-architect.md +0 -196
  217. package/.claude/agents/plan-reviewer.md +0 -52
  218. package/.claude/agents/refactor-planner.md +0 -63
  219. package/.claude/agents/security-scanner.md +0 -102
  220. package/.claude/agents/web-research-specialist.md +0 -78
  221. package/.claude/commands/cost-analysis.md +0 -315
  222. package/.claude/commands/dev-docs-update.md +0 -55
  223. package/.claude/commands/dev-docs.md +0 -51
  224. package/.claude/commands/feature-dev.md +0 -125
  225. package/.claude/commands/incident-debug.md +0 -247
  226. package/.claude/commands/infra-plan.md +0 -81
  227. package/.claude/commands/migration-plan.md +0 -478
  228. package/.claude/commands/route-research-for-testing.md +0 -37
  229. package/.claude/commands/security-review.md +0 -66
  230. package/.claude/hooks/CONFIG.md +0 -448
  231. package/.claude/hooks/README.md +0 -163
  232. package/.claude/hooks/SKILL_ACTIVATION_COMPLETE.md +0 -226
  233. package/.claude/hooks/WINDOWS_HOOKS_README.md +0 -151
  234. package/.claude/hooks/add-skill-activation-banners.ts +0 -132
  235. package/.claude/hooks/comprehensive-skill-test.ts +0 -1315
  236. package/.claude/hooks/error-handling-reminder.sh +0 -12
  237. package/.claude/hooks/error-handling-reminder.ts +0 -222
  238. package/.claude/hooks/k8s-manifest-validator.sh +0 -56
  239. package/.claude/hooks/package-lock.json +0 -556
  240. package/.claude/hooks/package.json +0 -16
  241. package/.claude/hooks/post-tool-use-tracker.ps1 +0 -174
  242. package/.claude/hooks/post-tool-use-tracker.sh +0 -183
  243. package/.claude/hooks/security-policy-check.sh +0 -247
  244. package/.claude/hooks/skill-activation-prompt.ps1 +0 -10
  245. package/.claude/hooks/skill-activation-prompt.sh +0 -10
  246. package/.claude/hooks/skill-activation-prompt.ts +0 -141
  247. package/.claude/hooks/stop-build-check-enhanced.sh +0 -130
  248. package/.claude/hooks/terraform-validator.sh +0 -53
  249. package/.claude/hooks/test-input.json +0 -7
  250. package/.claude/hooks/test-skill-activation.ts +0 -427
  251. package/.claude/hooks/trigger-build-resolver.sh +0 -79
  252. package/.claude/hooks/tsc-check.sh +0 -173
  253. package/.claude/hooks/tsconfig.json +0 -19
  254. package/.claude/settings.json +0 -59
  255. package/.claude/settings.local.json +0 -67
  256. package/.claude/skills/README.md +0 -507
  257. package/.claude/skills/api-engineering/SKILL.md +0 -63
  258. package/.claude/skills/api-engineering/resources/api-versioning.md +0 -88
  259. package/.claude/skills/api-engineering/resources/graphql-patterns.md +0 -106
  260. package/.claude/skills/api-engineering/resources/rate-limiting.md +0 -118
  261. package/.claude/skills/api-engineering/resources/rest-api-design.md +0 -105
  262. package/.claude/skills/backend-dev-guidelines/SKILL.md +0 -306
  263. package/.claude/skills/backend-dev-guidelines/resources/architecture-overview.md +0 -451
  264. package/.claude/skills/backend-dev-guidelines/resources/async-and-errors.md +0 -307
  265. package/.claude/skills/backend-dev-guidelines/resources/complete-examples.md +0 -638
  266. package/.claude/skills/backend-dev-guidelines/resources/configuration.md +0 -275
  267. package/.claude/skills/backend-dev-guidelines/resources/database-patterns.md +0 -224
  268. package/.claude/skills/backend-dev-guidelines/resources/middleware-guide.md +0 -213
  269. package/.claude/skills/backend-dev-guidelines/resources/routing-and-controllers.md +0 -756
  270. package/.claude/skills/backend-dev-guidelines/resources/sentry-and-monitoring.md +0 -336
  271. package/.claude/skills/backend-dev-guidelines/resources/services-and-repositories.md +0 -789
  272. package/.claude/skills/backend-dev-guidelines/resources/testing-guide.md +0 -235
  273. package/.claude/skills/backend-dev-guidelines/resources/validation-patterns.md +0 -754
  274. package/.claude/skills/budget-and-cost-management/SKILL.md +0 -850
  275. package/.claude/skills/build-engineering/SKILL.md +0 -431
  276. package/.claude/skills/build-engineering/resources/artifact-repositories.md +0 -72
  277. package/.claude/skills/build-engineering/resources/build-caching.md +0 -96
  278. package/.claude/skills/build-engineering/resources/build-pipelines.md +0 -105
  279. package/.claude/skills/build-engineering/resources/build-security.md +0 -95
  280. package/.claude/skills/build-engineering/resources/build-systems.md +0 -389
  281. package/.claude/skills/build-engineering/resources/compilation-optimization.md +0 -201
  282. package/.claude/skills/build-engineering/resources/dependency-management.md +0 -73
  283. package/.claude/skills/build-engineering/resources/monorepo-builds.md +0 -110
  284. package/.claude/skills/build-engineering/resources/performance-optimization.md +0 -113
  285. package/.claude/skills/build-engineering/resources/reproducible-builds.md +0 -82
  286. package/.claude/skills/cloud-engineering/SKILL.md +0 -675
  287. package/.claude/skills/cloud-engineering/resources/aws-patterns.md +0 -742
  288. package/.claude/skills/cloud-engineering/resources/azure-patterns.md +0 -714
  289. package/.claude/skills/cloud-engineering/resources/cleared-cloud-environments.md +0 -987
  290. package/.claude/skills/cloud-engineering/resources/cloud-cost-optimization.md +0 -757
  291. package/.claude/skills/cloud-engineering/resources/cloud-networking.md +0 -1058
  292. package/.claude/skills/cloud-engineering/resources/cloud-security-tools.md +0 -1530
  293. package/.claude/skills/cloud-engineering/resources/cloud-security.md +0 -990
  294. package/.claude/skills/cloud-engineering/resources/gcp-patterns.md +0 -758
  295. package/.claude/skills/cloud-engineering/resources/migration-strategies.md +0 -820
  296. package/.claude/skills/cloud-engineering/resources/multi-cloud-strategies.md +0 -670
  297. package/.claude/skills/cloud-engineering/resources/oci-patterns.md +0 -1198
  298. package/.claude/skills/cloud-engineering/resources/serverless-patterns.md +0 -795
  299. package/.claude/skills/cloud-engineering/resources/well-architected-frameworks.md +0 -966
  300. package/.claude/skills/cybersecurity/SKILL.md +0 -409
  301. package/.claude/skills/cybersecurity/resources/security-architecture.md +0 -266
  302. package/.claude/skills/database-engineering/SKILL.md +0 -61
  303. package/.claude/skills/database-engineering/resources/backup-and-recovery.md +0 -72
  304. package/.claude/skills/database-engineering/resources/database-replication.md +0 -63
  305. package/.claude/skills/database-engineering/resources/postgresql-fundamentals.md +0 -70
  306. package/.claude/skills/database-engineering/resources/query-optimization.md +0 -68
  307. package/.claude/skills/devsecops/SKILL.md +0 -374
  308. package/.claude/skills/devsecops/resources/ci-cd-security.md +0 -204
  309. package/.claude/skills/devsecops/resources/compliance-automation.md +0 -530
  310. package/.claude/skills/devsecops/resources/compliance-frameworks.md +0 -2322
  311. package/.claude/skills/devsecops/resources/container-security.md +0 -915
  312. package/.claude/skills/devsecops/resources/cspm-integration.md +0 -1440
  313. package/.claude/skills/devsecops/resources/policy-enforcement.md +0 -619
  314. package/.claude/skills/devsecops/resources/secrets-management.md +0 -755
  315. package/.claude/skills/devsecops/resources/security-monitoring.md +0 -146
  316. package/.claude/skills/devsecops/resources/security-scanning.md +0 -887
  317. package/.claude/skills/devsecops/resources/security-testing.md +0 -203
  318. package/.claude/skills/devsecops/resources/supply-chain-security.md +0 -518
  319. package/.claude/skills/devsecops/resources/vulnerability-management.md +0 -481
  320. package/.claude/skills/devsecops/resources/zero-trust-architecture.md +0 -177
  321. package/.claude/skills/documentation-as-code/SKILL.md +0 -323
  322. package/.claude/skills/documentation-as-code/resources/api-documentation.md +0 -90
  323. package/.claude/skills/documentation-as-code/resources/changelog-management.md +0 -79
  324. package/.claude/skills/documentation-as-code/resources/diagram-generation.md +0 -44
  325. package/.claude/skills/documentation-as-code/resources/docs-as-code-workflow.md +0 -99
  326. package/.claude/skills/documentation-as-code/resources/documentation-automation.md +0 -68
  327. package/.claude/skills/documentation-as-code/resources/documentation-sites.md +0 -79
  328. package/.claude/skills/documentation-as-code/resources/markdown-best-practices.md +0 -162
  329. package/.claude/skills/documentation-as-code/resources/openapi-specification.md +0 -77
  330. package/.claude/skills/documentation-as-code/resources/readme-engineering.md +0 -60
  331. package/.claude/skills/documentation-as-code/resources/technical-writing-guide.md +0 -202
  332. package/.claude/skills/engineering-management/SKILL.md +0 -356
  333. package/.claude/skills/engineering-management/resources/career-ladders.md +0 -609
  334. package/.claude/skills/engineering-management/resources/hiring-and-assessment.md +0 -555
  335. package/.claude/skills/engineering-management/resources/one-on-one-guides.md +0 -609
  336. package/.claude/skills/engineering-management/resources/resource-planning.md +0 -557
  337. package/.claude/skills/engineering-management/resources/team-organization-patterns.md +0 -491
  338. package/.claude/skills/engineering-management/resources/technical-interviews.md +0 -474
  339. package/.claude/skills/engineering-operations-management/SKILL.md +0 -817
  340. package/.claude/skills/error-tracking/SKILL.md +0 -379
  341. package/.claude/skills/frontend-design/SKILL.md +0 -42
  342. package/.claude/skills/frontend-dev-guidelines/SKILL.md +0 -403
  343. package/.claude/skills/frontend-dev-guidelines/resources/common-patterns.md +0 -331
  344. package/.claude/skills/frontend-dev-guidelines/resources/complete-examples.md +0 -872
  345. package/.claude/skills/frontend-dev-guidelines/resources/component-patterns.md +0 -502
  346. package/.claude/skills/frontend-dev-guidelines/resources/data-fetching.md +0 -767
  347. package/.claude/skills/frontend-dev-guidelines/resources/file-organization.md +0 -502
  348. package/.claude/skills/frontend-dev-guidelines/resources/loading-and-error-states.md +0 -501
  349. package/.claude/skills/frontend-dev-guidelines/resources/performance.md +0 -406
  350. package/.claude/skills/frontend-dev-guidelines/resources/routing-guide.md +0 -364
  351. package/.claude/skills/frontend-dev-guidelines/resources/styling-guide.md +0 -428
  352. package/.claude/skills/frontend-dev-guidelines/resources/typescript-standards.md +0 -418
  353. package/.claude/skills/general-it-engineering/SKILL.md +0 -393
  354. package/.claude/skills/general-it-engineering/resources/asset-management.md +0 -712
  355. package/.claude/skills/general-it-engineering/resources/automation-orchestration.md +0 -817
  356. package/.claude/skills/general-it-engineering/resources/business-continuity.md +0 -786
  357. package/.claude/skills/general-it-engineering/resources/change-management.md +0 -715
  358. package/.claude/skills/general-it-engineering/resources/enterprise-monitoring.md +0 -729
  359. package/.claude/skills/general-it-engineering/resources/help-desk-operations.md +0 -738
  360. package/.claude/skills/general-it-engineering/resources/incident-service-management.md +0 -834
  361. package/.claude/skills/general-it-engineering/resources/it-governance.md +0 -753
  362. package/.claude/skills/general-it-engineering/resources/itil-framework.md +0 -503
  363. package/.claude/skills/general-it-engineering/resources/service-management.md +0 -669
  364. package/.claude/skills/infrastructure-architecture/SKILL.md +0 -328
  365. package/.claude/skills/infrastructure-architecture/resources/architecture-decision-records.md +0 -505
  366. package/.claude/skills/infrastructure-architecture/resources/architecture-patterns.md +0 -528
  367. package/.claude/skills/infrastructure-architecture/resources/capacity-planning.md +0 -453
  368. package/.claude/skills/infrastructure-architecture/resources/cleared-environment-architecture.md +0 -773
  369. package/.claude/skills/infrastructure-architecture/resources/cost-architecture.md +0 -499
  370. package/.claude/skills/infrastructure-architecture/resources/data-architecture.md +0 -501
  371. package/.claude/skills/infrastructure-architecture/resources/disaster-recovery.md +0 -535
  372. package/.claude/skills/infrastructure-architecture/resources/migration-architecture.md +0 -512
  373. package/.claude/skills/infrastructure-architecture/resources/multi-region-design.md +0 -608
  374. package/.claude/skills/infrastructure-architecture/resources/reference-architectures.md +0 -562
  375. package/.claude/skills/infrastructure-architecture/resources/security-architecture.md +0 -538
  376. package/.claude/skills/infrastructure-architecture/resources/system-design-principles.md +0 -489
  377. package/.claude/skills/infrastructure-architecture/resources/workload-classification.md +0 -1000
  378. package/.claude/skills/infrastructure-strategy/SKILL.md +0 -924
  379. package/.claude/skills/network-engineering/SKILL.md +0 -385
  380. package/.claude/skills/network-engineering/resources/dns-management.md +0 -738
  381. package/.claude/skills/network-engineering/resources/load-balancing.md +0 -820
  382. package/.claude/skills/network-engineering/resources/network-architecture.md +0 -546
  383. package/.claude/skills/network-engineering/resources/network-security.md +0 -921
  384. package/.claude/skills/network-engineering/resources/network-troubleshooting.md +0 -749
  385. package/.claude/skills/network-engineering/resources/routing-switching.md +0 -373
  386. package/.claude/skills/network-engineering/resources/sdn-networking.md +0 -695
  387. package/.claude/skills/network-engineering/resources/service-mesh-networking.md +0 -777
  388. package/.claude/skills/network-engineering/resources/tcp-ip-protocols.md +0 -444
  389. package/.claude/skills/network-engineering/resources/vpn-connectivity.md +0 -672
  390. package/.claude/skills/node-development/SKILL.md +0 -317
  391. package/.claude/skills/observability-engineering/SKILL.md +0 -101
  392. package/.claude/skills/observability-engineering/resources/apm-tools.md +0 -97
  393. package/.claude/skills/observability-engineering/resources/correlation-strategies.md +0 -87
  394. package/.claude/skills/observability-engineering/resources/distributed-tracing.md +0 -98
  395. package/.claude/skills/observability-engineering/resources/logs-aggregation.md +0 -118
  396. package/.claude/skills/observability-engineering/resources/observability-cost-optimization.md +0 -141
  397. package/.claude/skills/observability-engineering/resources/opentelemetry.md +0 -110
  398. package/.claude/skills/platform-engineering/SKILL.md +0 -555
  399. package/.claude/skills/platform-engineering/resources/architecture-overview.md +0 -600
  400. package/.claude/skills/platform-engineering/resources/container-orchestration.md +0 -916
  401. package/.claude/skills/platform-engineering/resources/cost-optimization.md +0 -634
  402. package/.claude/skills/platform-engineering/resources/developer-platforms.md +0 -670
  403. package/.claude/skills/platform-engineering/resources/gitops-automation.md +0 -650
  404. package/.claude/skills/platform-engineering/resources/infrastructure-as-code.md +0 -778
  405. package/.claude/skills/platform-engineering/resources/infrastructure-standards.md +0 -708
  406. package/.claude/skills/platform-engineering/resources/multi-tenancy.md +0 -602
  407. package/.claude/skills/platform-engineering/resources/platform-security.md +0 -711
  408. package/.claude/skills/platform-engineering/resources/resource-management.md +0 -592
  409. package/.claude/skills/platform-engineering/resources/service-mesh.md +0 -628
  410. package/.claude/skills/release-engineering/SKILL.md +0 -393
  411. package/.claude/skills/release-engineering/resources/artifact-management.md +0 -108
  412. package/.claude/skills/release-engineering/resources/build-optimization.md +0 -84
  413. package/.claude/skills/release-engineering/resources/ci-cd-pipelines.md +0 -411
  414. package/.claude/skills/release-engineering/resources/deployment-strategies.md +0 -197
  415. package/.claude/skills/release-engineering/resources/pipeline-security.md +0 -62
  416. package/.claude/skills/release-engineering/resources/progressive-delivery.md +0 -83
  417. package/.claude/skills/release-engineering/resources/release-automation.md +0 -68
  418. package/.claude/skills/release-engineering/resources/release-orchestration.md +0 -77
  419. package/.claude/skills/release-engineering/resources/rollback-strategies.md +0 -66
  420. package/.claude/skills/release-engineering/resources/versioning-strategies.md +0 -59
  421. package/.claude/skills/route-tester/SKILL.md +0 -392
  422. package/.claude/skills/skill-developer/ADVANCED.md +0 -197
  423. package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +0 -306
  424. package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +0 -152
  425. package/.claude/skills/skill-developer/SKILL.md +0 -430
  426. package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +0 -315
  427. package/.claude/skills/skill-developer/TRIGGER_TYPES.md +0 -305
  428. package/.claude/skills/skill-developer/TROUBLESHOOTING.md +0 -514
  429. package/.claude/skills/skill-rules.json +0 -2989
  430. package/.claude/skills/sre/SKILL.md +0 -464
  431. package/.claude/skills/sre/resources/alerting-best-practices.md +0 -282
  432. package/.claude/skills/sre/resources/capacity-planning.md +0 -226
  433. package/.claude/skills/sre/resources/chaos-engineering.md +0 -193
  434. package/.claude/skills/sre/resources/disaster-recovery.md +0 -232
  435. package/.claude/skills/sre/resources/incident-management.md +0 -436
  436. package/.claude/skills/sre/resources/observability-stack.md +0 -240
  437. package/.claude/skills/sre/resources/on-call-runbooks.md +0 -167
  438. package/.claude/skills/sre/resources/performance-optimization.md +0 -108
  439. package/.claude/skills/sre/resources/reliability-patterns.md +0 -183
  440. package/.claude/skills/sre/resources/slo-sli-sla.md +0 -464
  441. package/.claude/skills/sre/resources/toil-reduction.md +0 -145
  442. package/.claude/skills/systems-engineering/SKILL.md +0 -648
  443. package/.claude/skills/systems-engineering/resources/automation-patterns.md +0 -771
  444. package/.claude/skills/systems-engineering/resources/configuration-management.md +0 -998
  445. package/.claude/skills/systems-engineering/resources/linux-administration.md +0 -672
  446. package/.claude/skills/systems-engineering/resources/networking-fundamentals.md +0 -982
  447. package/.claude/skills/systems-engineering/resources/performance-tuning.md +0 -871
  448. package/.claude/skills/systems-engineering/resources/powershell-scripting.md +0 -482
  449. package/.claude/skills/systems-engineering/resources/security-hardening.md +0 -739
  450. package/.claude/skills/systems-engineering/resources/shell-scripting.md +0 -915
  451. package/.claude/skills/systems-engineering/resources/storage-management.md +0 -628
  452. package/.claude/skills/systems-engineering/resources/system-monitoring.md +0 -787
  453. package/.claude/skills/systems-engineering/resources/troubleshooting-guide.md +0 -753
  454. package/.claude/skills/systems-engineering/resources/windows-administration.md +0 -738
  455. package/.claude/skills/technical-leadership/SKILL.md +0 -728
  456. package/backend/docs/SECRETS_DOCUMENTATION.md +0 -327
  457. package/backend/package-lock.json +0 -6801
  458. package/backend/src/core/node-registries/actions.js +0 -202
  459. package/backend/src/core/node-registries/arrays.js +0 -155
  460. package/backend/src/core/node-registries/bot.js +0 -23
  461. package/backend/src/core/node-registries/container.js +0 -162
  462. package/backend/src/core/node-registries/data.js +0 -290
  463. package/backend/src/core/node-registries/debug.js +0 -26
  464. package/backend/src/core/node-registries/events.js +0 -201
  465. package/backend/src/core/node-registries/flow.js +0 -139
  466. package/backend/src/core/node-registries/furnace.js +0 -143
  467. package/backend/src/core/node-registries/logic.js +0 -62
  468. package/backend/src/core/node-registries/math.js +0 -42
  469. package/backend/src/core/node-registries/navigation.js +0 -111
  470. package/backend/src/core/node-registries/objects.js +0 -98
  471. package/backend/src/core/node-registries/strings.js +0 -187
  472. package/backend/src/core/node-registries/time.js +0 -113
  473. package/backend/src/core/node-registries/type.js +0 -25
  474. package/backend/src/core/node-registries/users.js +0 -79
  475. package/frontend/dist/assets/index-BC-NbKXi.css +0 -32
  476. package/frontend/dist/assets/index-DqJXZMHY.js +0 -11266
@@ -10,6 +10,61 @@ const { execSync: execSyncRaw } = require('child_process');
10
10
 
11
11
  const projectRoot = path.resolve(__dirname, '..');
12
12
 
13
+ // Проверяет и устанавливает зависимости для всех плагинов
14
+ async function ensurePluginDependencies(installedPlugins = [], sendLog = console.log) {
15
+ if (!installedPlugins || installedPlugins.length === 0) return;
16
+
17
+ sendLog(`[PluginLoader] Проверка зависимостей ${installedPlugins.length} плагинов...`);
18
+
19
+ for (const plugin of installedPlugins) {
20
+ if (!plugin || !plugin.path) continue;
21
+
22
+ try {
23
+ const packageJsonPath = path.join(plugin.path, 'package.json');
24
+
25
+ // Проверяем есть ли package.json
26
+ if (!fssync.existsSync(packageJsonPath)) {
27
+ continue;
28
+ }
29
+
30
+ const packageJson = JSON.parse(fssync.readFileSync(packageJsonPath, 'utf-8'));
31
+ const dependencies = packageJson.dependencies || {};
32
+
33
+ if (Object.keys(dependencies).length === 0) {
34
+ continue;
35
+ }
36
+
37
+ // Проверяем есть ли node_modules
38
+ const nodeModulesPath = path.join(plugin.path, 'node_modules');
39
+ const needsInstall = !fssync.existsSync(nodeModulesPath);
40
+
41
+ if (needsInstall) {
42
+ sendLog(`[PluginLoader] Установка зависимостей для ${plugin.name}...`);
43
+
44
+ try {
45
+ execSync('npm install --omit=dev --no-audit --no-fund', {
46
+ cwd: plugin.path,
47
+ stdio: 'inherit'
48
+ });
49
+ sendLog(`[PluginLoader] ✓ Зависимости установлены для ${plugin.name}`);
50
+ } catch (e1) {
51
+ sendLog(`[PluginLoader] Повторная попытка с --legacy-peer-deps для ${plugin.name}...`);
52
+ execSync('npm install --omit=dev --legacy-peer-deps --no-audit --no-fund', {
53
+ cwd: plugin.path,
54
+ stdio: 'inherit'
55
+ });
56
+ sendLog(`[PluginLoader] ✓ Зависимости установлены для ${plugin.name}`);
57
+ }
58
+ }
59
+
60
+ } catch (error) {
61
+ sendLog(`[PluginLoader] [WARN] Не удалось проверить зависимости для ${plugin.name}: ${error.message}`);
62
+ }
63
+ }
64
+
65
+ sendLog(`[PluginLoader] Проверка зависимостей завершена`);
66
+ }
67
+
13
68
  // Создаёт обёрнутый console для перехвата логов плагина
14
69
  function createPluginConsole(botId, pluginName, originalConsole) {
15
70
  const emitLog = (level, args) => {
@@ -160,6 +215,16 @@ async function initializePlugins(bot, installedPlugins = [], prisma) {
160
215
  } else {
161
216
  sendLog(`[PluginLoader] [ERROR] ${plugin.name} не экспортирует функцию или объект с методом onLoad.`);
162
217
  }
218
+
219
+ if (pluginModule && pluginModule.exports && typeof pluginModule.exports === 'object') {
220
+ if (bot.pluginRegistry) {
221
+ bot.pluginRegistry.set(plugin.name, pluginModule.exports);
222
+ }
223
+ } else if (pluginModule && pluginModule.default && pluginModule.default.exports) {
224
+ if (bot.pluginRegistry) {
225
+ bot.pluginRegistry.set(plugin.name, pluginModule.default.exports);
226
+ }
227
+ }
163
228
  };
164
229
 
165
230
  sendLog(`[PluginLoader] Загрузка: ${plugin.name} (v${plugin.version}) из ${normalizedPath}`);
@@ -184,12 +249,27 @@ async function initializePlugins(bot, installedPlugins = [], prisma) {
184
249
  } catch (error) {
185
250
  let handled = false;
186
251
  let lastError = error;
187
- if (error.message.includes('Cannot find module')) {
252
+ // Проверяем не только сообщение ошибки, но и весь стек
253
+ const errorString = error.message + '\n' + (error.stack || '');
254
+ const isModuleError = errorString.includes('Cannot find module');
255
+ if (isModuleError) {
188
256
  const moduleMatch = error.message.match(/Cannot find module '([^']+)'/);
189
257
  const missingModule = moduleMatch ? moduleMatch[1] : null;
190
258
  if (missingModule) {
259
+ const isFilePath = missingModule.startsWith('/') ||
260
+ missingModule.startsWith('./') ||
261
+ missingModule.startsWith('../') ||
262
+ missingModule.startsWith('\\') ||
263
+ /^[A-Za-z]:[\\/]/.test(missingModule) || // Windows absolute path
264
+ /\.(js|json|node|ts|mjs|cjs)$/i.test(missingModule);
265
+
266
+ if (isFilePath) {
267
+ sendLog(`[PluginLoader] [ERROR] Файл не найден: ${missingModule}`);
268
+ sendLog(`[PluginLoader] [ERROR] Плагин ${plugin.name} содержит ошибку — отсутствует файл. Проверьте код плагина.`);
269
+ throw error;
270
+ }
271
+
191
272
  try {
192
- // Диагностика текущего состояния резолва
193
273
  pluginRequire.resolve(missingModule);
194
274
  sendLog(`[PluginLoader] [DEBUG] ${missingModule} уже резолвится до установки? Это неожиданно.`);
195
275
  } catch {
@@ -300,4 +380,4 @@ async function initializePlugins(bot, installedPlugins = [], prisma) {
300
380
  }
301
381
  }
302
382
 
303
- module.exports = { initializePlugins };
383
+ module.exports = { initializePlugins, ensurePluginDependencies };
@@ -13,7 +13,192 @@ const DATA_DIR = path.join(os.homedir(), '.blockmine');
13
13
  const PLUGINS_BASE_DIR = path.join(DATA_DIR, 'storage', 'plugins');
14
14
 
15
15
  const TELEMETRY_ENABLED = true;
16
- const STATS_SERVER_URL = 'http://185.65.200.184:3000';
16
+ const STATS_SERVER_URL = process.env.STATS_SERVER_URL || 'http://185.65.200.184:3000';
17
+
18
+ function normalizeGithubRepoUrl(repoUrl) {
19
+ if (!repoUrl || typeof repoUrl !== 'string') return null;
20
+
21
+ let trimmed = repoUrl.trim();
22
+ if (!trimmed) return null;
23
+
24
+ try {
25
+ trimmed = trimmed.replace(/^git\+/i, '');
26
+ if (/^github\.com\//i.test(trimmed)) {
27
+ trimmed = `https://${trimmed}`;
28
+ }
29
+
30
+ const sshMatch = trimmed.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/i);
31
+ if (sshMatch) {
32
+ const owner = sshMatch[1].toLowerCase();
33
+ const repo = sshMatch[2].toLowerCase();
34
+ return `https://github.com/${owner}/${repo}`;
35
+ }
36
+
37
+ const parsed = new URL(trimmed);
38
+ const hostname = parsed.hostname.toLowerCase();
39
+ if (hostname !== 'github.com' && hostname !== 'www.github.com') return null;
40
+
41
+ const pathParts = parsed.pathname.split('/').filter(Boolean);
42
+ if (pathParts.length < 2) return null;
43
+
44
+ const owner = pathParts[0].toLowerCase();
45
+ const repo = pathParts[1].replace(/\.git$/i, '').toLowerCase();
46
+ return `https://github.com/${owner}/${repo}`;
47
+ } catch {
48
+ return null;
49
+ }
50
+ }
51
+
52
+ function parseGithubOwnerRepo(repoUrl) {
53
+ const normalized = normalizeGithubRepoUrl(repoUrl);
54
+ if (!normalized) return null;
55
+ try {
56
+ const parsed = new URL(normalized);
57
+ const parts = parsed.pathname.split('/').filter(Boolean);
58
+ if (parts.length < 2) return null;
59
+ return { owner: parts[0], repo: parts[1] };
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+
65
+ function getGithubRepoName(repoUrl) {
66
+ const ownerRepo = parseGithubOwnerRepo(repoUrl);
67
+ return ownerRepo?.repo || null;
68
+ }
69
+
70
+ function getGithubHeaders(extra = {}) {
71
+ const headers = {
72
+ Accept: 'application/vnd.github+json',
73
+ 'User-Agent': 'BlockMine',
74
+ ...extra
75
+ };
76
+
77
+ if (process.env.GITHUB_TOKEN) {
78
+ headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
79
+ }
80
+
81
+ return headers;
82
+ }
83
+
84
+ async function fetchJsonWithTimeout(url, timeoutMs = 7000) {
85
+ const controller = new AbortController();
86
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
87
+ try {
88
+ const response = await fetch(url, { headers: getGithubHeaders(), signal: controller.signal });
89
+ if (!response.ok) {
90
+ return null;
91
+ }
92
+ return response.json();
93
+ } catch {
94
+ return null;
95
+ } finally {
96
+ clearTimeout(timeoutId);
97
+ }
98
+ }
99
+
100
+ async function fetchGithubResponseWithTimeout(url, options = {}, timeoutMs = 10000) {
101
+ const controller = new AbortController();
102
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
103
+
104
+ try {
105
+ const response = await fetch(url, {
106
+ ...options,
107
+ headers: getGithubHeaders(options.headers || {}),
108
+ signal: controller.signal
109
+ });
110
+
111
+ if (!response.ok) {
112
+ const error = new Error(`GitHub request failed with status ${response.status}.`);
113
+ error.status = response.status;
114
+ throw error;
115
+ }
116
+
117
+ return response;
118
+ } catch (error) {
119
+ if (error.name === 'AbortError') {
120
+ const timeoutError = new Error('GitHub request timed out.');
121
+ timeoutError.name = 'AbortError';
122
+ throw timeoutError;
123
+ }
124
+
125
+ throw error;
126
+ } finally {
127
+ clearTimeout(timeoutId);
128
+ }
129
+ }
130
+
131
+ async function fetchGithubRepoInfo(repoUrl) {
132
+ const ownerRepo = parseGithubOwnerRepo(repoUrl);
133
+ if (!ownerRepo) return null;
134
+
135
+ return fetchJsonWithTimeout(`https://api.github.com/repos/${ownerRepo.owner}/${ownerRepo.repo}`);
136
+ }
137
+
138
+ async function downloadGithubArchive(repoUrl, ref) {
139
+ const ownerRepo = parseGithubOwnerRepo(repoUrl);
140
+ if (!ownerRepo) {
141
+ throw new Error('Invalid GitHub repository URL.');
142
+ }
143
+
144
+ const response = await fetchGithubResponseWithTimeout(
145
+ `https://api.github.com/repos/${ownerRepo.owner}/${ownerRepo.repo}/zipball/${encodeURIComponent(ref)}`,
146
+ { headers: { Accept: 'application/vnd.github+json' } },
147
+ 15000
148
+ );
149
+
150
+ return response;
151
+ }
152
+
153
+ async function fetchGithubPackageVersion(repoUrl, ref = null) {
154
+ const ownerRepo = parseGithubOwnerRepo(repoUrl);
155
+ if (!ownerRepo) return null;
156
+
157
+ const resolvedRef = ref || (await fetchGithubRepoInfo(repoUrl))?.default_branch;
158
+ if (!resolvedRef) return null;
159
+
160
+ const packageJsonData = await fetchJsonWithTimeout(
161
+ `https://api.github.com/repos/${ownerRepo.owner}/${ownerRepo.repo}/contents/package.json?ref=${encodeURIComponent(resolvedRef)}`
162
+ );
163
+
164
+ if (!packageJsonData?.content) {
165
+ return null;
166
+ }
167
+
168
+ try {
169
+ const packageJsonRaw = Buffer.from(packageJsonData.content, packageJsonData.encoding || 'base64').toString('utf8');
170
+ const packageJson = JSON.parse(packageJsonRaw);
171
+ return typeof packageJson?.version === 'string' ? packageJson.version : null;
172
+ } catch {
173
+ return null;
174
+ }
175
+ }
176
+
177
+ async function fetchLatestGithubVersionTag(repoUrl) {
178
+ const ownerRepo = parseGithubOwnerRepo(repoUrl);
179
+ if (!ownerRepo) return null;
180
+
181
+ const releaseData = await fetchJsonWithTimeout(`https://api.github.com/repos/${ownerRepo.owner}/${ownerRepo.repo}/releases/latest`);
182
+ const releaseTag = typeof releaseData?.tag_name === 'string' ? releaseData.tag_name : null;
183
+ if (releaseTag) return releaseTag;
184
+
185
+ const tagsData = await fetchJsonWithTimeout(`https://api.github.com/repos/${ownerRepo.owner}/${ownerRepo.repo}/tags?per_page=20`);
186
+ if (!Array.isArray(tagsData) || tagsData.length === 0) return null;
187
+
188
+ const semverTags = tagsData
189
+ .map(item => item?.name)
190
+ .filter(Boolean)
191
+ .map(tag => ({ tag, normalized: semver.coerce(tag)?.version || null }))
192
+ .filter(item => item.normalized);
193
+
194
+ if (semverTags.length > 0) {
195
+ semverTags.sort((a, b) => semver.rcompare(a.normalized, b.normalized));
196
+ return semverTags[0].tag;
197
+ }
198
+
199
+ const firstTag = tagsData[0]?.name;
200
+ return typeof firstTag === 'string' ? firstTag : null;
201
+ }
17
202
 
18
203
  function reportPluginDownload(pluginName) {
19
204
  if (!TELEMETRY_ENABLED) return;
@@ -48,6 +233,52 @@ class PluginManager {
48
233
  await fse.mkdir(PLUGINS_BASE_DIR, { recursive: true }).catch(console.error);
49
234
  }
50
235
 
236
+ /**
237
+ * Проверяет зависимости плагина из package.json
238
+ * @param {number} botId - ID бота
239
+ * @param {object} packageJson - package.json плагина
240
+ * @returns {Promise<{isValid: boolean, missing: string[], warnings: string[]}>}
241
+ */
242
+ async checkPluginDependencies(botId, packageJson) {
243
+ const result = {
244
+ isValid: true,
245
+ missing: [],
246
+ warnings: []
247
+ };
248
+
249
+ // Проверяем зависимости из botpanel.dependencies
250
+ const pluginDeps = packageJson.botpanel?.dependencies || {};
251
+ if (Object.keys(pluginDeps).length === 0) {
252
+ return result; // Нет зависимостей
253
+ }
254
+
255
+ const installedPlugins = await prisma.installedPlugin.findMany({
256
+ where: { botId },
257
+ select: { name: true, version: true }
258
+ });
259
+
260
+ const installedMap = new Map(installedPlugins.map(p => [p.name, p.version]));
261
+
262
+ for (const [depName, depVersion] of Object.entries(pluginDeps)) {
263
+ if (!installedMap.has(depName)) {
264
+ result.missing.push(`${depName} (требуется ${depVersion})`);
265
+ result.isValid = false;
266
+ } else {
267
+ const installedVersion = installedMap.get(depName);
268
+ if (depVersion.startsWith('^') || depVersion.startsWith('~')) {
269
+ const requiredBase = depVersion.slice(1);
270
+ if (!installedVersion.startsWith(requiredBase.split('.')[0])) {
271
+ result.warnings.push(
272
+ `${depName}: установлена v${installedVersion}, требуется ${depVersion}`
273
+ );
274
+ }
275
+ }
276
+ }
277
+ }
278
+
279
+ return result;
280
+ }
281
+
51
282
  async _installDependencies(pluginPath) {
52
283
  const packageJsonPath = path.join(pluginPath, 'package.json');
53
284
  try {
@@ -108,9 +339,22 @@ class PluginManager {
108
339
  }
109
340
 
110
341
  async installFromLocalPath(botId, directoryPath) {
342
+ // Проверяем зависимости плагина перед установкой
343
+ const packageJsonPath = path.join(directoryPath, 'package.json');
344
+ const packageJson = JSON.parse(await fse.readFile(packageJsonPath, 'utf-8'));
345
+
346
+ const depCheck = await this.checkPluginDependencies(botId, packageJson);
347
+ if (!depCheck.isValid) {
348
+ const missingList = depCheck.missing.join(', ');
349
+ console.warn(`[PluginManager] ⚠️ Плагин ${packageJson.name} требует: ${missingList}`);
350
+ console.warn(`[PluginManager] Плагин будет установлен, но может работать некорректно без зависимостей.`);
351
+ }
352
+ if (depCheck.warnings.length > 0) {
353
+ depCheck.warnings.forEach(w => console.warn(`[PluginManager] ⚠️ ${w}`));
354
+ }
355
+
111
356
  const newPlugin = await this.registerPlugin(botId, directoryPath, 'LOCAL', directoryPath);
112
357
  try {
113
- const packageJson = JSON.parse(await fse.readFile(path.join(directoryPath, 'package.json'), 'utf-8'));
114
358
  reportPluginDownload(packageJson.name);
115
359
  } catch(e) {
116
360
  console.error('Не удалось прочитать package.json для отправки статистики локального плагина');
@@ -118,17 +362,19 @@ class PluginManager {
118
362
 
119
363
  await this._installDependencies(directoryPath);
120
364
  await this.loadPluginGraphs(botId, newPlugin.id, directoryPath);
121
-
365
+
122
366
  if (this.botManager) {
123
367
  await this.botManager.reloadPlugins(botId);
124
368
  }
125
-
369
+
126
370
  return newPlugin;
127
371
  }
128
372
 
129
373
  async installFromGithub(botId, repoUrl, prismaClient = prisma, isUpdate = false, tag = null) {
130
374
  const botPluginsDir = path.join(PLUGINS_BASE_DIR, `bot_${botId}`);
131
375
  await fse.mkdir(botPluginsDir, { recursive: true });
376
+ let sourceRefType = tag ? 'tag' : 'branch';
377
+ let sourceRef = tag || 'main';
132
378
 
133
379
  if (!isUpdate) {
134
380
  const existing = await prismaClient.installedPlugin.findFirst({ where: { botId, sourceUri: repoUrl } });
@@ -138,32 +384,30 @@ class PluginManager {
138
384
  try {
139
385
  const url = new URL(repoUrl);
140
386
  const repoPath = url.pathname.replace(/^\/|\.git$/g, '');
387
+ const repoInfo = tag ? null : await fetchGithubRepoInfo(repoUrl);
388
+ if (repoInfo?.default_branch) {
389
+ sourceRef = repoInfo.default_branch;
390
+ }
141
391
 
142
392
  let response;
143
393
 
144
- // Если указан тег - скачиваем конкретный релиз
145
394
  if (tag) {
146
- const archiveUrlTag = `https://github.com/${repoPath}/archive/refs/tags/${encodeURIComponent(tag)}.zip`;
147
395
  console.log(`[PluginManager] Скачиваем релиз ${tag} из ${repoUrl}...`);
148
396
  try {
149
- response = await fetch(archiveUrlTag);
397
+ response = await downloadGithubArchive(repoUrl, tag);
150
398
  } catch (err) {
151
399
  throw new Error(`Ошибка сети при скачивании релиза ${tag}: ${err.message || err}`);
152
400
  }
153
- if (!response.ok) {
154
- throw new Error(`Не удалось скачать релиз ${tag}. Статус: ${response.status}. Возможно, тег не существует.`);
155
- }
156
401
  } else {
157
- // Если тег не указан - скачиваем последний коммит из main/master (старое поведение)
158
- const archiveUrlMain = `https://github.com/${repoPath}/archive/refs/heads/main.zip`;
159
- const archiveUrlMaster = `https://github.com/${repoPath}/archive/refs/heads/master.zip`;
160
-
161
- response = await fetch(archiveUrlMain);
162
- if (!response.ok) {
163
- console.log(`[PluginManager] Ветка 'main' не найдена для ${repoUrl}, пробую 'master'...`);
164
- response = await fetch(archiveUrlMaster);
165
- if (!response.ok) {
166
- throw new Error(`Не удалось скачать архив плагина. Статус: ${response.status}`);
402
+ try {
403
+ response = await downloadGithubArchive(repoUrl, sourceRef);
404
+ } catch (err) {
405
+ if (!repoInfo && sourceRef !== 'master') {
406
+ console.log(`[PluginManager] Ветка '${sourceRef}' не найдена для ${repoUrl}, пробую 'master'...`);
407
+ sourceRef = 'master';
408
+ response = await downloadGithubArchive(repoUrl, sourceRef);
409
+ } else {
410
+ throw new Error(`Не удалось скачать архив плагина: ${err.message || err}`);
167
411
  }
168
412
  }
169
413
  }
@@ -193,9 +437,23 @@ class PluginManager {
193
437
 
194
438
  await this._installDependencies(localPath);
195
439
 
196
- const newPlugin = await this.registerPlugin(botId, localPath, 'GITHUB', repoUrl, prismaClient);
197
-
440
+
198
441
  const packageJson = JSON.parse(await fse.readFile(path.join(localPath, 'package.json'), 'utf-8'));
442
+ const depCheck = await this.checkPluginDependencies(botId, packageJson);
443
+ if (!depCheck.isValid) {
444
+ const missingList = depCheck.missing.join(', ');
445
+ console.warn(`[PluginManager] ⚠️ Плагин ${packageJson.name} требует: ${missingList}`);
446
+ console.warn(`[PluginManager] Плагин будет установлен, но может работать некорректно без зависимостей.`);
447
+ }
448
+ if (depCheck.warnings.length > 0) {
449
+ depCheck.warnings.forEach(w => console.warn(`[PluginManager] ⚠️ ${w}`));
450
+ }
451
+
452
+ const newPlugin = await this.registerPlugin(botId, localPath, 'GITHUB', repoUrl, prismaClient, {
453
+ sourceRefType,
454
+ sourceRef
455
+ });
456
+
199
457
  reportPluginDownload(packageJson.name);
200
458
 
201
459
  await this.loadPluginGraphs(botId, newPlugin.id, localPath);
@@ -215,7 +473,7 @@ class PluginManager {
215
473
  }
216
474
  }
217
475
 
218
- async registerPlugin(botId, directoryPath, sourceType, sourceUri, prismaClient = prisma) {
476
+ async registerPlugin(botId, directoryPath, sourceType, sourceUri, prismaClient = prisma, extraData = {}) {
219
477
  const packageJsonPath = path.join(directoryPath, 'package.json');
220
478
  let packageJson;
221
479
  try {
@@ -237,6 +495,7 @@ class PluginManager {
237
495
  sourceType,
238
496
  sourceUri: sourceUri || directoryPath,
239
497
  manifest: JSON.stringify(packageJson.botpanel || {}),
498
+ ...extraData,
240
499
  };
241
500
 
242
501
  return prismaClient.installedPlugin.upsert({
@@ -327,24 +586,76 @@ class PluginManager {
327
586
  where: { botId, sourceType: 'GITHUB' }
328
587
  });
329
588
  const updatesAvailable = [];
330
- const catalogMap = new Map(catalog.map(item => [item.repoUrl, item]));
589
+ const catalogMapByRepo = new Map();
590
+ const catalogMapByName = new Map();
591
+ const catalogMapByRepoName = new Map();
592
+ const latestTagCache = new Map();
593
+
594
+ for (const item of catalog) {
595
+ const normalizedRepoUrl = normalizeGithubRepoUrl(item.repoUrl);
596
+ if (normalizedRepoUrl) {
597
+ catalogMapByRepo.set(normalizedRepoUrl, item);
598
+ const repoName = getGithubRepoName(normalizedRepoUrl);
599
+ if (repoName && !catalogMapByRepoName.has(repoName)) {
600
+ catalogMapByRepoName.set(repoName, item);
601
+ }
602
+ }
603
+ if (item?.name) {
604
+ catalogMapByName.set(String(item.name).toLowerCase(), item);
605
+ }
606
+ }
331
607
 
332
608
  for (const plugin of githubPlugins) {
333
609
  try {
334
- const catalogInfo = catalogMap.get(plugin.sourceUri);
335
- if (!catalogInfo || !catalogInfo.latestTag) continue;
610
+ const normalizedSourceUri = normalizeGithubRepoUrl(plugin.sourceUri);
611
+ const repoName = getGithubRepoName(normalizedSourceUri || plugin.sourceUri);
612
+ const catalogInfo =
613
+ (normalizedSourceUri ? catalogMapByRepo.get(normalizedSourceUri) : null) ||
614
+ catalogMapByName.get(String(plugin.name).toLowerCase()) ||
615
+ (repoName ? catalogMapByRepoName.get(repoName) : null);
616
+
617
+ const targetRepoUrl = catalogInfo?.repoUrl || normalizedSourceUri || normalizeGithubRepoUrl(plugin.sourceUri) || plugin.sourceUri;
618
+ let latestTagRaw =
619
+ catalogInfo?.latestTag ||
620
+ catalogInfo?.recommendedVersion ||
621
+ catalogInfo?.version ||
622
+ catalogInfo?.latestVersion ||
623
+ catalogInfo?.tag;
624
+
625
+ if (!latestTagRaw) {
626
+ const cacheKey = targetRepoUrl || plugin.name;
627
+ if (latestTagCache.has(cacheKey)) {
628
+ latestTagRaw = latestTagCache.get(cacheKey);
629
+ } else {
630
+ const fetchedTag = targetRepoUrl ? await fetchLatestGithubVersionTag(targetRepoUrl) : null;
631
+ latestTagCache.set(cacheKey, fetchedTag);
632
+ latestTagRaw = fetchedTag;
633
+ }
634
+ }
635
+
636
+ let latestVersionRaw = latestTagRaw;
637
+ if (!latestVersionRaw && targetRepoUrl) {
638
+ latestVersionRaw = await fetchGithubPackageVersion(
639
+ targetRepoUrl,
640
+ plugin.sourceRefType === 'branch' ? plugin.sourceRef : null
641
+ );
642
+ }
643
+
644
+ if (!latestVersionRaw) continue;
336
645
 
337
- const localVersion = semver.coerce(plugin.version)?.version || plugin.version;
338
- const recommendedVersion = semver.coerce(catalogInfo.latestTag)?.version || catalogInfo.latestTag;
646
+ const localSemver = semver.coerce(plugin.version);
647
+ const remoteSemver = semver.coerce(latestVersionRaw);
648
+ if (!localSemver || !remoteSemver) continue;
339
649
 
340
- if (semver.gt(recommendedVersion, localVersion)) {
650
+ if (semver.gt(remoteSemver.version, localSemver.version)) {
341
651
  updatesAvailable.push({
342
652
  id: plugin.id,
343
653
  name: plugin.name,
344
654
  sourceUri: plugin.sourceUri,
345
- currentVersion: localVersion,
346
- recommendedVersion: recommendedVersion,
347
- latestTag: catalogInfo.latestTag, // 🏷️ Добавляем тег для использования при обновлении
655
+ currentVersion: localSemver.version,
656
+ recommendedVersion: remoteSemver.version,
657
+ latestTag: catalogInfo?.latestTag || latestTagRaw || null,
658
+ targetRepoUrl,
348
659
  });
349
660
  }
350
661
  } catch (error) {
@@ -354,7 +665,7 @@ class PluginManager {
354
665
  return updatesAvailable;
355
666
  }
356
667
 
357
- async updatePlugin(pluginId, targetTag = null) {
668
+ async updatePlugin(pluginId, targetTag = null, targetRepoUrl = null) {
358
669
  const plugin = await prisma.installedPlugin.findUnique({ where: { id: pluginId } });
359
670
  if (!plugin || plugin.sourceType !== 'GITHUB') {
360
671
  throw new Error('Плагин не найден или не является GitHub-плагином.');
@@ -362,7 +673,7 @@ class PluginManager {
362
673
 
363
674
  console.log(`[PluginManager] Начало обновления плагина ${plugin.name}${targetTag ? ` до версии ${targetTag}` : ''}...`);
364
675
 
365
- const repoUrl = plugin.sourceUri;
676
+ const repoUrl = targetRepoUrl || plugin.sourceUri;
366
677
  const botId = plugin.botId;
367
678
  const oldVersion = plugin.version;
368
679
 
@@ -584,4 +895,4 @@ class PluginManager {
584
895
  }
585
896
  }
586
897
 
587
- module.exports = PluginManager;
898
+ module.exports = PluginManager;
@@ -0,0 +1,9 @@
1
+ class RewindSignal extends Error {
2
+ constructor(target) {
3
+ super('Rewind signal');
4
+ this.name = 'RewindSignal';
5
+ this.target = target;
6
+ }
7
+ }
8
+
9
+ module.exports = RewindSignal;