agentgui 1.0.720 → 1.0.721
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/lib/jsonl-watcher.js +18 -46
- package/lib/plugin-loader.js +162 -188
- package/lib/plugins/agents-plugin.js +1 -2
- package/lib/plugins/database-plugin.js +1 -1
- package/lib/plugins/stream-plugin.js +2 -1
- package/lib/tool-provisioner.js +1 -1
- package/package.json +1 -1
- package/server.js +3 -3
package/lib/jsonl-watcher.js
CHANGED
|
@@ -12,7 +12,7 @@ export class JsonlWatcher {
|
|
|
12
12
|
this._owned = ownedSessionIds;
|
|
13
13
|
this._tails = new Map();
|
|
14
14
|
this._convMap = new Map();
|
|
15
|
-
this.
|
|
15
|
+
this._frags = new Map();
|
|
16
16
|
this._timers = new Map();
|
|
17
17
|
this._seqs = new Map();
|
|
18
18
|
this._streaming = new Set();
|
|
@@ -42,7 +42,7 @@ export class JsonlWatcher {
|
|
|
42
42
|
this._convMap.delete(sid);
|
|
43
43
|
this._seqs.delete(sid);
|
|
44
44
|
this._streaming.delete(sid);
|
|
45
|
-
for (const key of [...this.
|
|
45
|
+
for (const key of [...this._frags.keys()]) if (key.startsWith(`${sid}:`)) this._frags.delete(key);
|
|
46
46
|
for (const [fp, s] of this._tails.entries()) {
|
|
47
47
|
if (!fp.includes(sid)) continue;
|
|
48
48
|
if (s.fd !== null) try { fs.closeSync(s.fd); } catch (_) {}
|
|
@@ -56,7 +56,7 @@ export class JsonlWatcher {
|
|
|
56
56
|
removeAllConversations() {
|
|
57
57
|
for (const s of this._tails.values()) if (s.fd !== null) try { fs.closeSync(s.fd); } catch (_) {}
|
|
58
58
|
for (const t of this._timers.values()) clearTimeout(t);
|
|
59
|
-
this._tails.clear(); this._convMap.clear(); this.
|
|
59
|
+
this._tails.clear(); this._convMap.clear(); this._frags.clear();
|
|
60
60
|
this._timers.clear(); this._seqs.clear(); this._streaming.clear();
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -114,8 +114,7 @@ export class JsonlWatcher {
|
|
|
114
114
|
if (this._convMap.has(sid)) return this._convMap.get(sid);
|
|
115
115
|
const found = this._q.getConversations().find(c => c.claudeSessionId === sid);
|
|
116
116
|
if (found) { this._convMap.set(sid, found.id); return found.id; }
|
|
117
|
-
if (e.type
|
|
118
|
-
if (e.type === 'user' && e.isMeta) return null;
|
|
117
|
+
if (e.type !== 'user' || e.isMeta) return null;
|
|
119
118
|
const cwd = e.cwd || process.cwd();
|
|
120
119
|
const branch = e.gitBranch || '';
|
|
121
120
|
const base = path.basename(cwd);
|
|
@@ -133,13 +132,6 @@ export class JsonlWatcher {
|
|
|
133
132
|
this._bc({ type: 'streaming_progress', sessionId: sid, conversationId: cid, block, blockRole: role, seq: this._seq(sid), timestamp: Date.now(), ...extra });
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
_emitBlocks(cid, sid, blocks, role) {
|
|
137
|
-
for (const b of blocks) {
|
|
138
|
-
if (!b || !b.type) continue;
|
|
139
|
-
this._emit(cid, sid, b, role);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
135
|
_startStreaming(cid, sid) {
|
|
144
136
|
if (this._streaming.has(sid)) return;
|
|
145
137
|
this._streaming.add(sid);
|
|
@@ -153,17 +145,11 @@ export class JsonlWatcher {
|
|
|
153
145
|
}
|
|
154
146
|
|
|
155
147
|
_route(cid, sid, e) {
|
|
156
|
-
if (e.type === 'queue-operation' ||
|
|
157
|
-
|
|
158
|
-
if (e.isApiErrorMessage && e.error === 'rate_limit') {
|
|
159
|
-
this._bc({ type: 'streaming_error', sessionId: sid, conversationId: cid, error: 'Rate limit hit', recoverable: true, timestamp: Date.now() });
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
148
|
+
if (e.type === 'queue-operation' || (e.type === 'user' && e.isMeta)) return;
|
|
162
149
|
|
|
163
150
|
if (e.type === 'system') {
|
|
164
151
|
if (e.subtype === 'init') { this._startStreaming(cid, sid); return; }
|
|
165
152
|
if (e.subtype === 'turn_duration' || e.subtype === 'stop_hook_summary') { this._endStreaming(cid, sid); return; }
|
|
166
|
-
this._startStreaming(cid, sid);
|
|
167
153
|
this._emit(cid, sid, { type: 'system', subtype: e.subtype, model: e.model, cwd: e.cwd, tools: e.tools, preTokens: e.compactMetadata?.preTokens }, 'system');
|
|
168
154
|
return;
|
|
169
155
|
}
|
|
@@ -171,14 +157,11 @@ export class JsonlWatcher {
|
|
|
171
157
|
if (e.type === 'assistant' && e.message?.content) {
|
|
172
158
|
this._startStreaming(cid, sid);
|
|
173
159
|
const key = `${sid}:${e.message.id}`;
|
|
174
|
-
const
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
this._emitBlocks(cid, sid, newBlocks, 'assistant');
|
|
180
|
-
}
|
|
181
|
-
if (e.message.stop_reason) this._emitted.delete(key);
|
|
160
|
+
const prevCount = this._frags.get(key)?.message?.content?.length || 0;
|
|
161
|
+
const newBlocks = e.message.content.slice(prevCount);
|
|
162
|
+
if (e.message.stop_reason === null || e.message.stop_reason === undefined) this._frags.set(key, e);
|
|
163
|
+
else this._frags.delete(key);
|
|
164
|
+
for (const b of newBlocks) this._emit(cid, sid, b, 'assistant');
|
|
182
165
|
return;
|
|
183
166
|
}
|
|
184
167
|
|
|
@@ -192,25 +175,14 @@ export class JsonlWatcher {
|
|
|
192
175
|
|
|
193
176
|
if (e.type === 'progress') {
|
|
194
177
|
this._startStreaming(cid, sid);
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
if (d.type === 'hook_progress') {
|
|
206
|
-
this._emit(cid, sid, { type: 'hook_progress', hookEvent: d.hookEvent, hookName: d.hookName }, 'system');
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
if (d.type === 'mcp_progress') {
|
|
210
|
-
this._emit(cid, sid, { type: 'mcp_progress', status: d.status, serverName: d.serverName, toolName: d.toolName }, 'system');
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
this._emit(cid, sid, { type: d.type || e.subtype || 'progress', content: e.content || d }, 'progress');
|
|
178
|
+
const dataType = e.data?.type || e.subtype || 'progress';
|
|
179
|
+
const content = dataType === 'agent_progress' ? e.data?.message : (e.data || e.content);
|
|
180
|
+
this._emit(cid, sid, { type: dataType, agentId: e.agentId, content }, 'progress');
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (e.isApiErrorMessage && e.error === 'rate_limit') {
|
|
185
|
+
this._bc({ type: 'streaming_error', sessionId: sid, conversationId: cid, error: 'Rate limit hit', recoverable: true, timestamp: Date.now() });
|
|
214
186
|
return;
|
|
215
187
|
}
|
|
216
188
|
|
package/lib/plugin-loader.js
CHANGED
|
@@ -1,188 +1,162 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
this.
|
|
11
|
-
this.
|
|
12
|
-
this.
|
|
13
|
-
this.
|
|
14
|
-
this.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
this.
|
|
29
|
-
return
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.error(`Failed to load plugin ${
|
|
32
|
-
throw error;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const name
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
for (const dep of (this.registry.get(name)?.dependencies || [])) { if (this.registry.has(dep)) visit(dep); }
|
|
164
|
-
result.push(name);
|
|
165
|
-
};
|
|
166
|
-
for (const name of this.registry.keys()) visit(name);
|
|
167
|
-
return result;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Graceful shutdown
|
|
171
|
-
async shutdown() {
|
|
172
|
-
const sorted = this.topologicalSort().reverse();
|
|
173
|
-
for (const name of sorted) {
|
|
174
|
-
const state = this.instances.get(name);
|
|
175
|
-
if (state && state.stop) {
|
|
176
|
-
try {
|
|
177
|
-
await state.stop();
|
|
178
|
-
} catch (error) {
|
|
179
|
-
console.error(`[PluginLoader] Error stopping ${name}:`, error.message);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
this.unwatchPlugin(name);
|
|
183
|
-
}
|
|
184
|
-
this.instances.clear();
|
|
185
|
-
this.registry.clear();
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
export default PluginLoader;
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
|
|
5
|
+
class PluginLoader extends EventEmitter {
|
|
6
|
+
constructor(pluginDir) {
|
|
7
|
+
super();
|
|
8
|
+
this.pluginDir = pluginDir;
|
|
9
|
+
this.registry = new Map();
|
|
10
|
+
this.instances = new Map();
|
|
11
|
+
this.states = new Map();
|
|
12
|
+
this.watchers = new Map();
|
|
13
|
+
this.errorCounts = new Map();
|
|
14
|
+
this.fileMap = new Map();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async loadPlugin(fileName) {
|
|
18
|
+
const filePath = path.join(this.pluginDir, `${fileName}.js`);
|
|
19
|
+
if (!fs.existsSync(filePath)) {
|
|
20
|
+
throw new Error(`Plugin file not found: ${filePath}`);
|
|
21
|
+
}
|
|
22
|
+
const fileUrl = `file://${filePath}?v=${Date.now()}`;
|
|
23
|
+
try {
|
|
24
|
+
const plugin = await import(fileUrl);
|
|
25
|
+
const mod = plugin.default || plugin;
|
|
26
|
+
const regName = mod.name || fileName;
|
|
27
|
+
this.registry.set(regName, mod);
|
|
28
|
+
this.fileMap.set(regName, fileName);
|
|
29
|
+
return mod;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error(`Failed to load plugin ${fileName}:`, error.message);
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async initializePlugin(name, config) {
|
|
37
|
+
const plugin = this.registry.get(name);
|
|
38
|
+
if (!plugin) {
|
|
39
|
+
throw new Error(`Plugin ${name} not found in registry`);
|
|
40
|
+
}
|
|
41
|
+
if (this.instances.has(name)) {
|
|
42
|
+
return this.instances.get(name);
|
|
43
|
+
}
|
|
44
|
+
for (const depName of (plugin.dependencies || [])) {
|
|
45
|
+
if (!this.instances.has(depName)) {
|
|
46
|
+
await this.initializePlugin(depName, config);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const result = await plugin.init(config, this.instances);
|
|
51
|
+
this.instances.set(name, result);
|
|
52
|
+
return result;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error(`[PluginLoader] Error initializing ${name}:`, error.message);
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get(name) {
|
|
60
|
+
return this.instances.get(name);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async reloadPlugin(name) {
|
|
64
|
+
const plugin = this.registry.get(name);
|
|
65
|
+
if (!plugin) {
|
|
66
|
+
console.warn(`[PluginLoader] Cannot reload ${name}: not found`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const state = this.instances.get(name);
|
|
70
|
+
if (!state) {
|
|
71
|
+
console.warn(`[PluginLoader] Cannot reload ${name}: not initialized`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
if (state.stop) await state.stop();
|
|
76
|
+
const fileName = this.fileMap.get(name) || name;
|
|
77
|
+
await this.loadPlugin(fileName);
|
|
78
|
+
const reloadedPlugin = this.registry.get(name);
|
|
79
|
+
const newState = await reloadedPlugin.reload(state);
|
|
80
|
+
this.instances.set(name, newState);
|
|
81
|
+
this.emit('reload', { name, success: true });
|
|
82
|
+
console.log(`[PluginLoader] Reloaded plugin: ${name}`);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error(`[PluginLoader] Error reloading ${name}:`, error.message);
|
|
85
|
+
this.emit('reload', { name, success: false, error: error.message });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
watchPlugin(name, callback) {
|
|
90
|
+
const fileName = this.fileMap.get(name) || name;
|
|
91
|
+
const filePath = path.join(this.pluginDir, `${fileName}.js`);
|
|
92
|
+
if (this.watchers.has(name)) return;
|
|
93
|
+
const watcher = fs.watch(filePath, async (eventType) => {
|
|
94
|
+
if (eventType === 'change') {
|
|
95
|
+
setTimeout(() => callback(name), 100);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
this.watchers.set(name, watcher);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
unwatchPlugin(name) {
|
|
102
|
+
const watcher = this.watchers.get(name);
|
|
103
|
+
if (watcher) {
|
|
104
|
+
watcher.close();
|
|
105
|
+
this.watchers.delete(name);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async loadAllPlugins(config) {
|
|
110
|
+
if (!fs.existsSync(this.pluginDir)) {
|
|
111
|
+
fs.mkdirSync(this.pluginDir, { recursive: true });
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const files = fs.readdirSync(this.pluginDir).filter(f => f.endsWith('.js'));
|
|
115
|
+
for (const file of files) {
|
|
116
|
+
const fileName = file.replace('.js', '');
|
|
117
|
+
try {
|
|
118
|
+
await this.loadPlugin(fileName);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error(`[PluginLoader] Failed to load ${fileName}:`, error.message);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const sorted = this.topologicalSort();
|
|
124
|
+
for (const name of sorted) {
|
|
125
|
+
try {
|
|
126
|
+
await this.initializePlugin(name, config);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error(`[PluginLoader] Failed to initialize ${name}:`, error.message);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
topologicalSort() {
|
|
134
|
+
const visited = new Set(), result = [];
|
|
135
|
+
const visit = (name) => {
|
|
136
|
+
if (visited.has(name)) return;
|
|
137
|
+
visited.add(name);
|
|
138
|
+
for (const dep of (this.registry.get(name)?.dependencies || [])) { if (this.registry.has(dep)) visit(dep); }
|
|
139
|
+
result.push(name);
|
|
140
|
+
};
|
|
141
|
+
for (const name of this.registry.keys()) visit(name);
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async shutdown() {
|
|
146
|
+
const sorted = this.topologicalSort().reverse();
|
|
147
|
+
for (const name of sorted) {
|
|
148
|
+
const state = this.instances.get(name);
|
|
149
|
+
if (state && state.stop) {
|
|
150
|
+
try {
|
|
151
|
+
await state.stop();
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.error(`[PluginLoader] Error stopping ${name}:`, error.message);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
this.unwatchPlugin(name);
|
|
157
|
+
}
|
|
158
|
+
this.instances.clear();
|
|
159
|
+
this.registry.clear();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
export default PluginLoader;
|
|
@@ -49,10 +49,9 @@ export default {
|
|
|
49
49
|
if (!agent) return res.status(404).json({ error: 'Agent not found' });
|
|
50
50
|
|
|
51
51
|
const session = stream.api.createSession(id);
|
|
52
|
-
// Use runClaudeWithStreaming instead
|
|
53
52
|
activeExecutions.set(id, { sessionId: session.id });
|
|
54
53
|
|
|
55
|
-
res.json({ sessionId: session.id
|
|
54
|
+
res.json({ sessionId: session.id });
|
|
56
55
|
} catch (e) {
|
|
57
56
|
res.status(500).json({ error: e.message });
|
|
58
57
|
}
|
|
@@ -8,7 +8,8 @@ export default {
|
|
|
8
8
|
dependencies: ['database'],
|
|
9
9
|
|
|
10
10
|
async init(config, plugins) {
|
|
11
|
-
const
|
|
11
|
+
const dbPlugin = plugins.get('database');
|
|
12
|
+
const db = dbPlugin?.api || {};
|
|
12
13
|
const activeSessions = new Map();
|
|
13
14
|
const pendingMessages = new Map();
|
|
14
15
|
const rateLimitState = new Map();
|
package/lib/tool-provisioner.js
CHANGED
|
@@ -38,7 +38,7 @@ export async function autoProvision(TOOLS, statusCache, install, broadcast) {
|
|
|
38
38
|
broadcast({ type: 'tool_update_failed', toolId: tool.id, data: result });
|
|
39
39
|
}
|
|
40
40
|
} else {
|
|
41
|
-
log(`${tool.id} v${status.installedVersion} up-to-date`);
|
|
41
|
+
log(`${tool.id} v${status.installedVersion || 'unknown'} up-to-date`);
|
|
42
42
|
broadcast({ type: 'tool_status_update', toolId: tool.id, data: { installed: true, isUpToDate: true, installedVersion: status.installedVersion, status: 'installed' } });
|
|
43
43
|
}
|
|
44
44
|
} catch (err) {
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -4479,7 +4479,7 @@ const BROADCAST_TYPES = new Set([
|
|
|
4479
4479
|
'streaming_start', 'streaming_progress', 'streaming_complete', 'streaming_error',
|
|
4480
4480
|
'tool_install_started', 'tool_install_progress', 'tool_install_complete', 'tool_install_failed',
|
|
4481
4481
|
'tool_update_progress', 'tool_update_complete', 'tool_update_failed',
|
|
4482
|
-
'tool_status_update',
|
|
4482
|
+
'tool_status_update', 'tool_update_available',
|
|
4483
4483
|
'tools_update_started', 'tools_update_complete', 'tools_refresh_complete',
|
|
4484
4484
|
'pm2_monit_update', 'pm2_monitoring_started', 'pm2_monitoring_stopped',
|
|
4485
4485
|
'pm2_list_response', 'pm2_start_response', 'pm2_stop_response',
|
|
@@ -5257,7 +5257,7 @@ import PluginLoader from './lib/plugin-loader.js';
|
|
|
5257
5257
|
const pluginLoader = new PluginLoader(path.join(__dirname, 'lib', 'plugins'));
|
|
5258
5258
|
async function loadPluginExtensions() {
|
|
5259
5259
|
try {
|
|
5260
|
-
await pluginLoader.loadAllPlugins({ router:
|
|
5260
|
+
await pluginLoader.loadAllPlugins({ router: expressApp, baseUrl: BASE_URL, logger: console, env: process.env });
|
|
5261
5261
|
const names = Array.from(pluginLoader.registry.keys());
|
|
5262
5262
|
if (names.length > 0) {
|
|
5263
5263
|
for (const name of names) {
|
|
@@ -5266,7 +5266,7 @@ async function loadPluginExtensions() {
|
|
|
5266
5266
|
for (const route of state.routes) {
|
|
5267
5267
|
const fullPath = BASE_URL + route.path;
|
|
5268
5268
|
const method = (route.method || 'GET').toLowerCase();
|
|
5269
|
-
if (
|
|
5269
|
+
if (expressApp[method]) expressApp[method](fullPath, route.handler);
|
|
5270
5270
|
}
|
|
5271
5271
|
}
|
|
5272
5272
|
console.log(`[PLUGINS] Loaded extensions: ${names.join(', ')}`);
|