blockmine 1.22.0 → 1.23.1

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 (108) hide show
  1. package/.claude/agents/code-architect.md +34 -0
  2. package/.claude/agents/code-explorer.md +51 -0
  3. package/.claude/agents/code-reviewer.md +46 -0
  4. package/.claude/commands/feature-dev.md +125 -0
  5. package/.claude/settings.json +5 -1
  6. package/.claude/settings.local.json +12 -1
  7. package/.claude/skills/frontend-design/SKILL.md +42 -0
  8. package/CHANGELOG.md +32 -1
  9. package/README.md +302 -152
  10. package/backend/package-lock.json +681 -9
  11. package/backend/package.json +8 -0
  12. package/backend/prisma/migrations/20251116111851_add_execution_trace/migration.sql +22 -0
  13. package/backend/prisma/migrations/20251120154914_add_panel_api_keys/migration.sql +21 -0
  14. package/backend/prisma/migrations/20251121110241_add_proxy_table/migration.sql +45 -0
  15. package/backend/prisma/schema.prisma +70 -1
  16. package/backend/src/__tests__/services/BotLifecycleService.test.js +9 -4
  17. package/backend/src/ai/plugin-assistant-system-prompt.md +788 -0
  18. package/backend/src/api/middleware/auth.js +27 -0
  19. package/backend/src/api/middleware/botAccess.js +7 -3
  20. package/backend/src/api/middleware/panelApiAuth.js +135 -0
  21. package/backend/src/api/routes/aiAssistant.js +995 -0
  22. package/backend/src/api/routes/auth.js +90 -54
  23. package/backend/src/api/routes/botCommands.js +107 -0
  24. package/backend/src/api/routes/botGroups.js +165 -0
  25. package/backend/src/api/routes/botHistory.js +108 -0
  26. package/backend/src/api/routes/botPermissions.js +99 -0
  27. package/backend/src/api/routes/botStatus.js +36 -0
  28. package/backend/src/api/routes/botUsers.js +162 -0
  29. package/backend/src/api/routes/bots.js +108 -59
  30. package/backend/src/api/routes/eventGraphs.js +4 -1
  31. package/backend/src/api/routes/logs.js +13 -3
  32. package/backend/src/api/routes/panel.js +3 -3
  33. package/backend/src/api/routes/panelApiKeys.js +179 -0
  34. package/backend/src/api/routes/pluginIde.js +1715 -135
  35. package/backend/src/api/routes/plugins.js +170 -13
  36. package/backend/src/api/routes/proxies.js +130 -0
  37. package/backend/src/api/routes/search.js +4 -0
  38. package/backend/src/api/routes/servers.js +20 -3
  39. package/backend/src/api/routes/settings.js +5 -0
  40. package/backend/src/api/routes/system.js +3 -3
  41. package/backend/src/api/routes/traces.js +131 -0
  42. package/backend/src/config/debug.config.js +36 -0
  43. package/backend/src/core/BotHistoryStore.js +180 -0
  44. package/backend/src/core/BotManager.js +14 -4
  45. package/backend/src/core/BotProcess.js +1517 -1092
  46. package/backend/src/core/EventGraphManager.js +194 -280
  47. package/backend/src/core/GraphExecutionEngine.js +1004 -321
  48. package/backend/src/core/MessageQueue.js +12 -6
  49. package/backend/src/core/PluginLoader.js +99 -5
  50. package/backend/src/core/PluginManager.js +74 -13
  51. package/backend/src/core/TaskScheduler.js +1 -1
  52. package/backend/src/core/commands/whois.js +1 -1
  53. package/backend/src/core/node-registries/actions.js +72 -2
  54. package/backend/src/core/node-registries/arrays.js +18 -0
  55. package/backend/src/core/node-registries/data.js +1 -1
  56. package/backend/src/core/node-registries/events.js +14 -0
  57. package/backend/src/core/node-registries/logic.js +17 -0
  58. package/backend/src/core/node-registries/strings.js +34 -0
  59. package/backend/src/core/node-registries/type.js +25 -0
  60. package/backend/src/core/nodes/actions/bot_look_at.js +1 -1
  61. package/backend/src/core/nodes/actions/create_command.js +189 -0
  62. package/backend/src/core/nodes/actions/delete_command.js +92 -0
  63. package/backend/src/core/nodes/actions/http_request.js +23 -4
  64. package/backend/src/core/nodes/actions/send_message.js +2 -12
  65. package/backend/src/core/nodes/actions/update_command.js +133 -0
  66. package/backend/src/core/nodes/arrays/join.js +28 -0
  67. package/backend/src/core/nodes/data/cast.js +2 -1
  68. package/backend/src/core/nodes/data/string_literal.js +2 -13
  69. package/backend/src/core/nodes/logic/not.js +22 -0
  70. package/backend/src/core/nodes/strings/starts_with.js +1 -1
  71. package/backend/src/core/nodes/strings/to_lower.js +22 -0
  72. package/backend/src/core/nodes/strings/to_upper.js +22 -0
  73. package/backend/src/core/nodes/type/to_string.js +32 -0
  74. package/backend/src/core/services/BotLifecycleService.js +835 -596
  75. package/backend/src/core/services/CommandExecutionService.js +430 -351
  76. package/backend/src/core/services/DebugSessionManager.js +347 -0
  77. package/backend/src/core/services/GraphCollaborationManager.js +501 -0
  78. package/backend/src/core/services/MinecraftBotManager.js +259 -0
  79. package/backend/src/core/services/MinecraftViewerService.js +216 -0
  80. package/backend/src/core/services/TraceCollectorService.js +545 -0
  81. package/backend/src/core/system/RuntimeCommandRegistry.js +116 -0
  82. package/backend/src/core/system/Transport.js +0 -4
  83. package/backend/src/core/validation/nodeSchemas.js +6 -6
  84. package/backend/src/real-time/botApi/handlers/graphHandlers.js +2 -2
  85. package/backend/src/real-time/botApi/handlers/graphWebSocketHandlers.js +1 -1
  86. package/backend/src/real-time/botApi/utils.js +11 -0
  87. package/backend/src/real-time/panelNamespace.js +387 -0
  88. package/backend/src/real-time/presence.js +7 -2
  89. package/backend/src/real-time/socketHandler.js +395 -4
  90. package/backend/src/server.js +18 -0
  91. package/frontend/dist/assets/index-DqzDkFsP.js +11210 -0
  92. package/frontend/dist/assets/index-t6K1u4OV.css +32 -0
  93. package/frontend/dist/index.html +2 -2
  94. package/frontend/package-lock.json +9437 -0
  95. package/frontend/package.json +8 -0
  96. package/package.json +2 -2
  97. package/screen/console.png +0 -0
  98. package/screen/dashboard.png +0 -0
  99. package/screen/graph_collabe.png +0 -0
  100. package/screen/graph_live_debug.png +0 -0
  101. package/screen/management_command.png +0 -0
  102. package/screen/node_debug_trace.png +0 -0
  103. package/screen/plugin_/320/276/320/261/320/267/320/276/321/200.png +0 -0
  104. package/screen/websocket.png +0 -0
  105. 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
  106. 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
  107. package/frontend/dist/assets/index-CfTo92bP.css +0 -1
  108. package/frontend/dist/assets/index-CiFD5X9Z.js +0 -8344
@@ -0,0 +1,347 @@
1
+ const { randomUUID } = require('crypto');
2
+
3
+ /**
4
+ * Состояние отладки для конкретного графа
5
+ * Shared state между всеми подключенными пользователями
6
+ */
7
+ class GraphDebugState {
8
+ constructor(botId, graphId, io) {
9
+ this.botId = botId;
10
+ this.graphId = graphId;
11
+ this.io = io;
12
+
13
+ this.breakpoints = new Map(); // Map<nodeId, Breakpoint>
14
+
15
+ this.activeExecution = null;
16
+
17
+ this.connectedUsers = new Map(); // Map<socketId, {userId, username}>
18
+
19
+ this.pausePromise = null;
20
+ this.resumeCallback = null;
21
+
22
+ // Измененные значения во время паузы (what-if)
23
+ this.pendingOverrides = {}; // Object<key, value>
24
+
25
+ // Режим пошагового выполнения (step over)
26
+ this.stepMode = false; // Если true, остановится на следующей ноде
27
+ this.stepFromNodeId = null; // ID ноды, с которой начали step over (чтобы её пропустить)
28
+ }
29
+
30
+ /**
31
+ * Получить имя комнаты для этого графа
32
+ */
33
+ getRoomName() {
34
+ return `graph:${this.graphId}:debug`;
35
+ }
36
+
37
+ /**
38
+ * Broadcast событие всем подключенным пользователям
39
+ */
40
+ broadcast(event, data) {
41
+ const room = this.getRoomName();
42
+ console.log(`[GraphDebugState] Broadcasting ${event} to room ${room}`);
43
+ console.log(`[GraphDebugState] Connected users in this debug state:`, this.connectedUsers.size);
44
+
45
+ const socketsInRoom = this.io.sockets.adapter.rooms.get(room);
46
+ console.log(`[GraphDebugState] Sockets in room ${room}:`, socketsInRoom ? socketsInRoom.size : 0);
47
+
48
+ this.io.to(room).emit(event, data);
49
+ }
50
+
51
+ /**
52
+ * Приостановить выполнение графа
53
+ * Возвращает Promise, который разрешится когда пользователь нажмет Continue
54
+ */
55
+ async pause(state) {
56
+ // Генерируем sessionId для этой паузы
57
+ const sessionId = randomUUID();
58
+
59
+ this.activeExecution = {
60
+ sessionId,
61
+ ...state,
62
+ pausedAt: Date.now()
63
+ };
64
+
65
+
66
+ this.broadcast('debug:paused', {
67
+ sessionId,
68
+ ...state
69
+ });
70
+
71
+
72
+ // Создаем Promise, который будет ждать resume
73
+ this.pausePromise = new Promise((resolve) => {
74
+ this.resumeCallback = resolve;
75
+ });
76
+
77
+ // Ждем пока кто-то не вызовет resume
78
+ const overrides = await this.pausePromise;
79
+
80
+ return overrides;
81
+ }
82
+
83
+ /**
84
+ * Возобновить выполнение
85
+ * @param {object} overrides - Изменения значений
86
+ * @param {boolean} stepMode - Если true, остановится на следующей ноде
87
+ */
88
+ resume(overrides = null, stepMode = false) {
89
+ if (this.resumeCallback) {
90
+ // Объединяем pendingOverrides с переданными overrides
91
+ const finalOverrides = {
92
+ ...this.pendingOverrides,
93
+ ...(overrides || {})
94
+ };
95
+
96
+ console.log('[GraphDebugState] Resuming with overrides:', finalOverrides, 'stepMode:', stepMode);
97
+
98
+ // Устанавливаем флаг stepMode и запоминаем текущую ноду
99
+ this.stepMode = stepMode;
100
+ if (stepMode && this.activeExecution) {
101
+ this.stepFromNodeId = this.activeExecution.nodeId;
102
+ console.log('[GraphDebugState] Step mode: will skip current node', this.stepFromNodeId);
103
+ }
104
+
105
+ this.resumeCallback(Object.keys(finalOverrides).length > 0 ? finalOverrides : null);
106
+ this.resumeCallback = null;
107
+ this.pausePromise = null;
108
+ }
109
+
110
+ // Если не step mode, очищаем состояние полностью
111
+ if (!stepMode) {
112
+ this.activeExecution = null;
113
+ this.stepFromNodeId = null;
114
+ }
115
+
116
+ this.pendingOverrides = {}; // Очищаем после применения
117
+
118
+ this.broadcast('debug:resumed', { stepMode });
119
+ }
120
+
121
+ /**
122
+ * Остановить выполнение (форсированно)
123
+ */
124
+ stop() {
125
+ if (this.resumeCallback) {
126
+ this.resumeCallback({ __stopped: true });
127
+ this.resumeCallback = null;
128
+ this.pausePromise = null;
129
+ }
130
+
131
+ this.activeExecution = null;
132
+ this.pendingOverrides = {}; // Очищаем при остановке
133
+ this.stepMode = false; // Сбрасываем step mode
134
+ this.stepFromNodeId = null; // Очищаем запомненную ноду
135
+
136
+ this.broadcast('debug:stopped', {});
137
+ }
138
+
139
+ /**
140
+ * Добавить брейкпоинт
141
+ */
142
+ addBreakpoint(nodeId, condition, createdBy) {
143
+ const breakpoint = {
144
+ id: randomUUID(),
145
+ nodeId,
146
+ condition: condition || null,
147
+ enabled: true,
148
+ hitCount: 0,
149
+ createdBy,
150
+ createdAt: Date.now()
151
+ };
152
+
153
+ this.breakpoints.set(nodeId, breakpoint);
154
+
155
+ this.broadcast('debug:breakpoint-added', { breakpoint });
156
+
157
+ return breakpoint;
158
+ }
159
+
160
+ /**
161
+ * Удалить брейкпоинт
162
+ */
163
+ removeBreakpoint(nodeId) {
164
+ this.breakpoints.delete(nodeId);
165
+ this.broadcast('debug:breakpoint-removed', { nodeId });
166
+ }
167
+
168
+ /**
169
+ * Переключить enabled для брейкпоинта
170
+ */
171
+ toggleBreakpoint(nodeId, enabled) {
172
+ const bp = this.breakpoints.get(nodeId);
173
+ if (bp) {
174
+ bp.enabled = enabled;
175
+ this.broadcast('debug:breakpoint-toggled', { nodeId, enabled });
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Очистить все брейкпоинты
181
+ */
182
+ clearAllBreakpoints() {
183
+ const nodeIds = Array.from(this.breakpoints.keys());
184
+ this.breakpoints.clear();
185
+
186
+ // Уведомляем о каждом удаленном брейкпоинте
187
+ nodeIds.forEach(nodeId => {
188
+ this.broadcast('debug:breakpoint-removed', { nodeId });
189
+ });
190
+ }
191
+
192
+ /**
193
+ * Проверить, нужно ли остановиться в step mode
194
+ * @param {string} nodeId - ID текущей ноды
195
+ * @returns {boolean}
196
+ */
197
+ shouldStepPause(nodeId) {
198
+ if (this.stepMode) {
199
+ // Пропускаем ноду, с которой начали step
200
+ if (nodeId === this.stepFromNodeId) {
201
+ return false;
202
+ }
203
+
204
+ // Останавливаемся на следующей ноде
205
+ this.stepMode = false; // Сбрасываем после остановки
206
+ this.stepFromNodeId = null;
207
+ return true;
208
+ }
209
+ return false;
210
+ }
211
+
212
+ /**
213
+ * Установить измененное значение (what-if)
214
+ */
215
+ setValue(key, value) {
216
+ this.pendingOverrides[key] = value;
217
+ console.log(`[GraphDebugState] Set override: ${key} =`, value);
218
+ }
219
+
220
+ /**
221
+ * Получить текущее состояние (для отправки новым пользователям)
222
+ */
223
+ getState() {
224
+ return {
225
+ breakpoints: Array.from(this.breakpoints.values()),
226
+ activeExecution: this.activeExecution,
227
+ connectedUsers: Array.from(this.connectedUsers.values())
228
+ };
229
+ }
230
+
231
+ /**
232
+ * Добавить пользователя
233
+ */
234
+ addUser(socketId, userInfo) {
235
+ this.connectedUsers.set(socketId, userInfo);
236
+ }
237
+
238
+ /**
239
+ * Удалить пользователя
240
+ */
241
+ removeUser(socketId) {
242
+ this.connectedUsers.delete(socketId);
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Менеджер отладочных сессий
248
+ * Управляет состоянием отладки для всех графов (в памяти)
249
+ */
250
+ class DebugSessionManager {
251
+ constructor(io) {
252
+ this.io = io;
253
+
254
+ // Map<graphId, GraphDebugState>
255
+ this.graphDebugStates = new Map();
256
+
257
+ console.log('[DebugSessionManager] Initialized');
258
+ }
259
+
260
+ /**
261
+ * Получить или создать состояние отладки для графа
262
+ */
263
+ getOrCreate(botId, graphId) {
264
+ if (!this.graphDebugStates.has(graphId)) {
265
+ const state = new GraphDebugState(botId, graphId, this.io);
266
+ this.graphDebugStates.set(graphId, state);
267
+ console.log(`[DebugSessionManager] Created debug state for graph ${graphId}`);
268
+ }
269
+
270
+ return this.graphDebugStates.get(graphId);
271
+ }
272
+
273
+ /**
274
+ * Получить состояние отладки для графа (если существует)
275
+ */
276
+ get(graphId) {
277
+ return this.graphDebugStates.get(graphId);
278
+ }
279
+
280
+ /**
281
+ * Найти состояние по sessionId
282
+ */
283
+ getBySessionId(sessionId) {
284
+ for (const state of this.graphDebugStates.values()) {
285
+ if (state.activeExecution && state.activeExecution.sessionId === sessionId) {
286
+ return state;
287
+ }
288
+ }
289
+ return null;
290
+ }
291
+
292
+ /**
293
+ * Удалить состояние графа (при необходимости)
294
+ */
295
+ remove(graphId) {
296
+ this.graphDebugStates.delete(graphId);
297
+ console.log(`[DebugSessionManager] Removed debug state for graph ${graphId}`);
298
+ }
299
+
300
+ /**
301
+ * Очистить все состояния (при перезапуске бота)
302
+ */
303
+ clearAll() {
304
+ this.graphDebugStates.clear();
305
+ console.log('[DebugSessionManager] Cleared all debug states');
306
+ }
307
+
308
+ /**
309
+ * Очистить состояния для конкретного бота
310
+ */
311
+ clearForBot(botId) {
312
+ for (const [graphId, state] of this.graphDebugStates.entries()) {
313
+ if (state.botId === botId) {
314
+ this.graphDebugStates.delete(graphId);
315
+ }
316
+ }
317
+ console.log(`[DebugSessionManager] Cleared debug states for bot ${botId}`);
318
+ }
319
+ }
320
+
321
+ // Глобальный инстанс для предотвращения циклических зависимостей
322
+ let globalDebugManager = null;
323
+
324
+ /**
325
+ * Инициализировать глобальный инстанс DebugSessionManager
326
+ */
327
+ function initializeDebugManager(io) {
328
+ if (!globalDebugManager) {
329
+ globalDebugManager = new DebugSessionManager(io);
330
+ console.log('[DebugSessionManager] Global instance initialized');
331
+ }
332
+ return globalDebugManager;
333
+ }
334
+
335
+ /**
336
+ * Получить глобальный инстанс DebugSessionManager
337
+ */
338
+ function getGlobalDebugManager() {
339
+ if (!globalDebugManager) {
340
+ throw new Error('DebugSessionManager not initialized! Call initializeDebugManager(io) first.');
341
+ }
342
+ return globalDebugManager;
343
+ }
344
+
345
+ module.exports = DebugSessionManager;
346
+ module.exports.initializeDebugManager = initializeDebugManager;
347
+ module.exports.getGlobalDebugManager = getGlobalDebugManager;