blockmine 1.22.0 → 1.23.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.
- package/.claude/settings.json +5 -1
- package/.claude/settings.local.json +10 -1
- package/CHANGELOG.md +27 -3
- package/CLAUDE.md +284 -0
- package/README.md +302 -152
- package/backend/package-lock.json +681 -9
- package/backend/package.json +8 -0
- package/backend/prisma/migrations/20251116111851_add_execution_trace/migration.sql +22 -0
- package/backend/prisma/migrations/20251120154914_add_panel_api_keys/migration.sql +21 -0
- package/backend/prisma/migrations/20251121110241_add_proxy_table/migration.sql +45 -0
- package/backend/prisma/migrations/migration_lock.toml +2 -2
- package/backend/prisma/schema.prisma +70 -1
- package/backend/src/__tests__/services/BotLifecycleService.test.js +9 -4
- package/backend/src/ai/plugin-assistant-system-prompt.md +788 -0
- package/backend/src/api/middleware/auth.js +27 -0
- package/backend/src/api/middleware/botAccess.js +7 -3
- package/backend/src/api/middleware/panelApiAuth.js +135 -0
- package/backend/src/api/routes/aiAssistant.js +995 -0
- package/backend/src/api/routes/auth.js +669 -633
- package/backend/src/api/routes/botCommands.js +107 -0
- package/backend/src/api/routes/botGroups.js +165 -0
- package/backend/src/api/routes/botHistory.js +108 -0
- package/backend/src/api/routes/botPermissions.js +99 -0
- package/backend/src/api/routes/botStatus.js +36 -0
- package/backend/src/api/routes/botUsers.js +162 -0
- package/backend/src/api/routes/bots.js +2451 -2402
- package/backend/src/api/routes/eventGraphs.js +4 -1
- package/backend/src/api/routes/logs.js +13 -3
- package/backend/src/api/routes/panel.js +66 -66
- package/backend/src/api/routes/panelApiKeys.js +179 -0
- package/backend/src/api/routes/pluginIde.js +1715 -135
- package/backend/src/api/routes/plugins.js +376 -219
- package/backend/src/api/routes/proxies.js +130 -0
- package/backend/src/api/routes/search.js +4 -0
- package/backend/src/api/routes/servers.js +20 -3
- package/backend/src/api/routes/settings.js +5 -0
- package/backend/src/api/routes/system.js +174 -174
- package/backend/src/api/routes/traces.js +131 -0
- package/backend/src/config/debug.config.js +36 -0
- package/backend/src/core/BotHistoryStore.js +180 -0
- package/backend/src/core/BotManager.js +14 -4
- package/backend/src/core/BotProcess.js +1517 -1092
- package/backend/src/core/EventGraphManager.js +37 -123
- package/backend/src/core/GraphExecutionEngine.js +977 -321
- package/backend/src/core/MessageQueue.js +12 -6
- package/backend/src/core/PluginLoader.js +99 -5
- package/backend/src/core/PluginManager.js +74 -13
- package/backend/src/core/TaskScheduler.js +1 -1
- package/backend/src/core/commands/whois.js +1 -1
- package/backend/src/core/node-registries/actions.js +70 -0
- package/backend/src/core/node-registries/arrays.js +18 -0
- package/backend/src/core/node-registries/data.js +1 -1
- package/backend/src/core/node-registries/events.js +14 -0
- package/backend/src/core/node-registries/logic.js +17 -0
- package/backend/src/core/node-registries/strings.js +34 -0
- package/backend/src/core/node-registries/type.js +25 -0
- package/backend/src/core/nodes/actions/bot_look_at.js +1 -1
- package/backend/src/core/nodes/actions/create_command.js +189 -0
- package/backend/src/core/nodes/actions/delete_command.js +92 -0
- package/backend/src/core/nodes/actions/update_command.js +133 -0
- package/backend/src/core/nodes/arrays/join.js +28 -0
- package/backend/src/core/nodes/data/cast.js +2 -1
- package/backend/src/core/nodes/logic/not.js +22 -0
- package/backend/src/core/nodes/strings/starts_with.js +1 -1
- package/backend/src/core/nodes/strings/to_lower.js +22 -0
- package/backend/src/core/nodes/strings/to_upper.js +22 -0
- package/backend/src/core/nodes/type/to_string.js +32 -0
- package/backend/src/core/services/BotLifecycleService.js +255 -16
- package/backend/src/core/services/CommandExecutionService.js +430 -351
- package/backend/src/core/services/DebugSessionManager.js +347 -0
- package/backend/src/core/services/GraphCollaborationManager.js +501 -0
- package/backend/src/core/services/MinecraftBotManager.js +259 -0
- package/backend/src/core/services/MinecraftViewerService.js +216 -0
- package/backend/src/core/services/TraceCollectorService.js +545 -0
- package/backend/src/core/system/RuntimeCommandRegistry.js +116 -0
- package/backend/src/core/system/Transport.js +0 -4
- package/backend/src/core/validation/nodeSchemas.js +6 -6
- package/backend/src/real-time/botApi/handlers/graphHandlers.js +2 -2
- package/backend/src/real-time/botApi/handlers/graphWebSocketHandlers.js +1 -1
- package/backend/src/real-time/botApi/utils.js +11 -0
- package/backend/src/real-time/panelNamespace.js +387 -0
- package/backend/src/real-time/presence.js +7 -2
- package/backend/src/real-time/socketHandler.js +395 -4
- package/backend/src/server.js +18 -0
- package/frontend/dist/assets/index-B1serztM.js +11210 -0
- package/frontend/dist/assets/index-t6K1u4OV.css +32 -0
- package/frontend/dist/index.html +2 -2
- package/frontend/package-lock.json +9437 -0
- package/frontend/package.json +8 -0
- package/package.json +2 -2
- package/screen/console.png +0 -0
- package/screen/dashboard.png +0 -0
- package/screen/graph_collabe.png +0 -0
- package/screen/graph_live_debug.png +0 -0
- package/screen/management_command.png +0 -0
- package/screen/node_debug_trace.png +0 -0
- package/screen/plugin_/320/276/320/261/320/267/320/276/321/200.png +0 -0
- package/screen/websocket.png +0 -0
- 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
- 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
- package/frontend/dist/assets/index-CfTo92bP.css +0 -1
- 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;
|