@qwickapps/server 1.5.1 → 1.5.2

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 (77) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/core/control-panel.d.ts.map +1 -1
  3. package/dist/core/control-panel.js +41 -0
  4. package/dist/core/control-panel.js.map +1 -1
  5. package/dist/core/guards.d.ts.map +1 -1
  6. package/dist/core/guards.js +77 -0
  7. package/dist/core/guards.js.map +1 -1
  8. package/dist/core/health-manager.d.ts +4 -0
  9. package/dist/core/health-manager.d.ts.map +1 -1
  10. package/dist/core/health-manager.js +6 -1
  11. package/dist/core/health-manager.js.map +1 -1
  12. package/dist/core/plugin-registry.d.ts +55 -5
  13. package/dist/core/plugin-registry.d.ts.map +1 -1
  14. package/dist/core/plugin-registry.js +57 -19
  15. package/dist/core/plugin-registry.js.map +1 -1
  16. package/dist/core/types.d.ts +2 -0
  17. package/dist/core/types.d.ts.map +1 -1
  18. package/dist/index.d.ts +2 -2
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +3 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/plugins/auth/auth-plugin.d.ts.map +1 -1
  23. package/dist/plugins/auth/auth-plugin.js +16 -0
  24. package/dist/plugins/auth/auth-plugin.js.map +1 -1
  25. package/dist/plugins/auth/auth-plugin.test.js +133 -0
  26. package/dist/plugins/auth/auth-plugin.test.js.map +1 -1
  27. package/dist/plugins/auth/env-config.d.ts.map +1 -1
  28. package/dist/plugins/auth/env-config.js +4 -0
  29. package/dist/plugins/auth/env-config.js.map +1 -1
  30. package/dist/plugins/auth/types.d.ts +10 -0
  31. package/dist/plugins/auth/types.d.ts.map +1 -1
  32. package/dist/plugins/auth/types.js.map +1 -1
  33. package/dist/plugins/devices/__tests__/token-utils.test.js +4 -2
  34. package/dist/plugins/devices/__tests__/token-utils.test.js.map +1 -1
  35. package/dist/plugins/frontend-app-plugin.d.ts.map +1 -1
  36. package/dist/plugins/frontend-app-plugin.js +18 -4
  37. package/dist/plugins/frontend-app-plugin.js.map +1 -1
  38. package/dist/plugins/index.d.ts +2 -0
  39. package/dist/plugins/index.d.ts.map +1 -1
  40. package/dist/plugins/index.js +2 -0
  41. package/dist/plugins/index.js.map +1 -1
  42. package/dist/plugins/qwickbrain/index.d.ts +25 -0
  43. package/dist/plugins/qwickbrain/index.d.ts.map +1 -0
  44. package/dist/plugins/qwickbrain/index.js +24 -0
  45. package/dist/plugins/qwickbrain/index.js.map +1 -0
  46. package/dist/plugins/qwickbrain/qwickbrain-plugin.d.ts +23 -0
  47. package/dist/plugins/qwickbrain/qwickbrain-plugin.d.ts.map +1 -0
  48. package/dist/plugins/qwickbrain/qwickbrain-plugin.js +528 -0
  49. package/dist/plugins/qwickbrain/qwickbrain-plugin.js.map +1 -0
  50. package/dist/plugins/qwickbrain/types.d.ts +131 -0
  51. package/dist/plugins/qwickbrain/types.d.ts.map +1 -0
  52. package/dist/plugins/qwickbrain/types.js +9 -0
  53. package/dist/plugins/qwickbrain/types.js.map +1 -0
  54. package/dist-ui/assets/{index-CynOqPkb.js → index-BfC7mG5L.js} +2 -2
  55. package/dist-ui/assets/{index-CynOqPkb.js.map → index-BfC7mG5L.js.map} +1 -1
  56. package/dist-ui/index.html +1 -1
  57. package/dist-ui-lib/api/controlPanelApi.d.ts +6 -0
  58. package/dist-ui-lib/index.js +277 -266
  59. package/dist-ui-lib/index.js.map +1 -1
  60. package/package.json +1 -1
  61. package/src/core/control-panel.ts +47 -0
  62. package/src/core/guards.ts +89 -0
  63. package/src/core/health-manager.ts +6 -1
  64. package/src/core/plugin-registry.ts +123 -25
  65. package/src/core/types.ts +2 -0
  66. package/src/index.ts +11 -0
  67. package/src/plugins/auth/auth-plugin.test.ts +167 -0
  68. package/src/plugins/auth/auth-plugin.ts +16 -0
  69. package/src/plugins/auth/env-config.ts +4 -0
  70. package/src/plugins/auth/types.ts +10 -0
  71. package/src/plugins/devices/__tests__/token-utils.test.ts +4 -2
  72. package/src/plugins/frontend-app-plugin.ts +19 -4
  73. package/src/plugins/index.ts +15 -0
  74. package/src/plugins/qwickbrain/index.ts +33 -0
  75. package/src/plugins/qwickbrain/qwickbrain-plugin.ts +642 -0
  76. package/src/plugins/qwickbrain/types.ts +146 -0
  77. package/ui/src/api/controlPanelApi.ts +49 -37
@@ -0,0 +1,528 @@
1
+ /**
2
+ * QwickBrain Plugin
3
+ *
4
+ * MCP proxy plugin for @qwickapps/server that exposes QwickBrain tools
5
+ * to external AI clients via authenticated API endpoints.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+ import { isAuthenticated, getAuthenticatedUser } from '../auth/auth-plugin.js';
10
+ // Connection status tracking
11
+ let connectionStatus = {
12
+ connected: false,
13
+ lastCheck: new Date(),
14
+ tailscaleStatus: 'unknown',
15
+ };
16
+ // Health check interval
17
+ let healthCheckInterval = null;
18
+ const rateLimitStore = new Map();
19
+ // Cleanup interval for rate limit entries
20
+ let rateLimitCleanupInterval = null;
21
+ /**
22
+ * Proxy a request to the QwickBrain instance
23
+ */
24
+ async function proxyToQwickBrain(baseUrl, path, options = {}) {
25
+ const { method = 'GET', body, timeout = 30000 } = options;
26
+ const url = `${baseUrl}${path}`;
27
+ const controller = new AbortController();
28
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
29
+ try {
30
+ const fetchOptions = {
31
+ method,
32
+ signal: controller.signal,
33
+ headers: {
34
+ 'Content-Type': 'application/json',
35
+ 'Accept': 'application/json',
36
+ },
37
+ };
38
+ if (body && method !== 'GET') {
39
+ fetchOptions.body = JSON.stringify(body);
40
+ }
41
+ const response = await fetch(url, fetchOptions);
42
+ return {
43
+ ok: response.ok,
44
+ status: response.status,
45
+ json: () => response.json(),
46
+ text: () => response.text(),
47
+ };
48
+ }
49
+ finally {
50
+ clearTimeout(timeoutId);
51
+ }
52
+ }
53
+ /**
54
+ * Check Tailscale connectivity status
55
+ */
56
+ async function checkTailscaleStatus() {
57
+ try {
58
+ const { exec } = await import('child_process');
59
+ const { promisify } = await import('util');
60
+ const execAsync = promisify(exec);
61
+ const { stdout } = await execAsync('tailscale status --json', { timeout: 5000 });
62
+ const status = JSON.parse(stdout);
63
+ return status.BackendState === 'Running' ? 'connected' : 'disconnected';
64
+ }
65
+ catch {
66
+ return 'unknown';
67
+ }
68
+ }
69
+ /**
70
+ * Check QwickBrain connectivity
71
+ */
72
+ async function checkQwickBrainHealth(baseUrl, timeout) {
73
+ const startTime = Date.now();
74
+ try {
75
+ const response = await proxyToQwickBrain(baseUrl, '/health', { timeout });
76
+ const latencyMs = Date.now() - startTime;
77
+ if (response.ok) {
78
+ return { connected: true, latencyMs };
79
+ }
80
+ else {
81
+ return { connected: false, error: `HTTP ${response.status}` };
82
+ }
83
+ }
84
+ catch (error) {
85
+ return {
86
+ connected: false,
87
+ error: error instanceof Error ? error.message : 'Connection failed',
88
+ };
89
+ }
90
+ }
91
+ /**
92
+ * Create the QwickBrain plugin
93
+ */
94
+ export function createQwickBrainPlugin(config) {
95
+ const debug = config.debug || false;
96
+ // Note: For regular plugins with slug-based routing, routes are auto-prefixed with slug
97
+ // So we use empty prefix here. The framework will add /mcp (or configured slug) automatically
98
+ const apiPrefix = '';
99
+ const apiEnabled = config.api?.enabled !== false;
100
+ const timeout = config.timeout || 30000;
101
+ const exposedTools = config.exposedTools || '*';
102
+ const authRequired = config.auth?.required !== false; // Default true
103
+ const allowedRoles = config.auth?.allowedRoles;
104
+ const rateLimitEnabled = config.rateLimit?.enabled !== false; // Default true
105
+ const perClientPerMinute = config.rateLimit?.perClientPerMinute || 60;
106
+ const globalPerMinute = config.rateLimit?.globalPerMinute || 1000;
107
+ const windowMs = 60000; // 1 minute window
108
+ function log(message, data) {
109
+ if (debug) {
110
+ console.log(`[QwickBrainPlugin] ${message}`, data || '');
111
+ }
112
+ }
113
+ /**
114
+ * Check rate limit for a key
115
+ * Returns remaining requests or -1 if limited
116
+ */
117
+ function checkRateLimit(key, maxRequests) {
118
+ const now = Date.now();
119
+ const entry = rateLimitStore.get(key);
120
+ if (!entry || now - entry.windowStart >= windowMs) {
121
+ // New window
122
+ rateLimitStore.set(key, { count: 1, windowStart: now });
123
+ return { limited: false, remaining: maxRequests - 1, resetAt: now + windowMs };
124
+ }
125
+ // Within window
126
+ if (entry.count >= maxRequests) {
127
+ return { limited: true, remaining: 0, resetAt: entry.windowStart + windowMs };
128
+ }
129
+ entry.count++;
130
+ return { limited: false, remaining: maxRequests - entry.count, resetAt: entry.windowStart + windowMs };
131
+ }
132
+ /**
133
+ * Check rate limits for a request (per-client and global)
134
+ * Returns error response if limited, null otherwise
135
+ */
136
+ function checkRateLimits(userId) {
137
+ if (!rateLimitEnabled)
138
+ return null;
139
+ // Check global rate limit
140
+ const globalKey = 'global:mcp';
141
+ const globalResult = checkRateLimit(globalKey, globalPerMinute);
142
+ if (globalResult.limited) {
143
+ log('Global rate limit exceeded');
144
+ return {
145
+ status: 429,
146
+ body: {
147
+ error: 'Too Many Requests',
148
+ message: 'Global rate limit exceeded. Please try again later.',
149
+ retryAfter: Math.ceil((globalResult.resetAt - Date.now()) / 1000),
150
+ },
151
+ headers: {
152
+ 'Retry-After': String(Math.ceil((globalResult.resetAt - Date.now()) / 1000)),
153
+ 'X-RateLimit-Limit': String(globalPerMinute),
154
+ 'X-RateLimit-Remaining': '0',
155
+ 'X-RateLimit-Reset': String(Math.ceil(globalResult.resetAt / 1000)),
156
+ },
157
+ };
158
+ }
159
+ // Check per-client rate limit (by user ID or IP)
160
+ const clientKey = `client:${userId || 'anonymous'}`;
161
+ const clientResult = checkRateLimit(clientKey, perClientPerMinute);
162
+ if (clientResult.limited) {
163
+ log('Client rate limit exceeded', { userId });
164
+ return {
165
+ status: 429,
166
+ body: {
167
+ error: 'Too Many Requests',
168
+ message: 'Rate limit exceeded. Please try again later.',
169
+ retryAfter: Math.ceil((clientResult.resetAt - Date.now()) / 1000),
170
+ },
171
+ headers: {
172
+ 'Retry-After': String(Math.ceil((clientResult.resetAt - Date.now()) / 1000)),
173
+ 'X-RateLimit-Limit': String(perClientPerMinute),
174
+ 'X-RateLimit-Remaining': '0',
175
+ 'X-RateLimit-Reset': String(Math.ceil(clientResult.resetAt / 1000)),
176
+ },
177
+ };
178
+ }
179
+ return null;
180
+ }
181
+ /**
182
+ * Check if a tool should be exposed
183
+ */
184
+ function isToolExposed(toolName) {
185
+ if (exposedTools === '*')
186
+ return true;
187
+ return exposedTools.includes(toolName);
188
+ }
189
+ /**
190
+ * Check if user has required role
191
+ */
192
+ function hasAllowedRole(user) {
193
+ if (!allowedRoles || allowedRoles.length === 0)
194
+ return true;
195
+ if (!user || !user.roles)
196
+ return false;
197
+ return allowedRoles.some(role => user.roles?.includes(role));
198
+ }
199
+ /**
200
+ * Check authentication and authorization for protected routes
201
+ * Returns error response object if not authorized, null if authorized
202
+ */
203
+ function checkAuth(req) {
204
+ if (!authRequired)
205
+ return null;
206
+ if (!isAuthenticated(req)) {
207
+ log('Unauthorized access attempt', { path: req.path });
208
+ return {
209
+ status: 401,
210
+ body: {
211
+ error: 'Unauthorized',
212
+ message: 'Authentication required to access MCP tools',
213
+ },
214
+ };
215
+ }
216
+ const user = getAuthenticatedUser(req);
217
+ if (!hasAllowedRole(user)) {
218
+ log('Forbidden access attempt', { path: req.path, userId: user?.id });
219
+ return {
220
+ status: 403,
221
+ body: {
222
+ error: 'Forbidden',
223
+ message: 'Insufficient permissions to access MCP tools',
224
+ requiredRoles: allowedRoles,
225
+ },
226
+ };
227
+ }
228
+ return null;
229
+ }
230
+ return {
231
+ id: 'qwickbrain',
232
+ name: 'QwickBrain MCP',
233
+ version: '1.0.0',
234
+ type: 'regular',
235
+ slug: 'mcp',
236
+ configurable: {
237
+ slug: true, // Allow users to customize slug via UI
238
+ },
239
+ async onStart(_pluginConfig, registry) {
240
+ log('Starting QwickBrain plugin');
241
+ log('Configuration', {
242
+ qwickbrainUrl: config.qwickbrainUrl,
243
+ timeout,
244
+ exposedTools: exposedTools === '*' ? 'all' : exposedTools,
245
+ authRequired,
246
+ allowedRoles: allowedRoles || 'any',
247
+ rateLimitEnabled,
248
+ perClientPerMinute,
249
+ globalPerMinute,
250
+ });
251
+ // Set up rate limit cleanup (every 5 minutes)
252
+ rateLimitCleanupInterval = setInterval(() => {
253
+ const now = Date.now();
254
+ let cleaned = 0;
255
+ for (const [key, entry] of rateLimitStore.entries()) {
256
+ if (now - entry.windowStart >= windowMs * 2) {
257
+ rateLimitStore.delete(key);
258
+ cleaned++;
259
+ }
260
+ }
261
+ if (cleaned > 0) {
262
+ log('Rate limit cleanup', { cleaned, remaining: rateLimitStore.size });
263
+ }
264
+ }, 300000); // 5 minutes
265
+ // Initial health check
266
+ const tailscaleStatus = await checkTailscaleStatus();
267
+ const healthResult = await checkQwickBrainHealth(config.qwickbrainUrl, timeout);
268
+ connectionStatus = {
269
+ connected: healthResult.connected,
270
+ lastCheck: new Date(),
271
+ latencyMs: healthResult.latencyMs,
272
+ error: healthResult.error,
273
+ tailscaleStatus,
274
+ };
275
+ log('Initial connection status', connectionStatus);
276
+ // Set up periodic health check
277
+ healthCheckInterval = setInterval(async () => {
278
+ const tsStatus = await checkTailscaleStatus();
279
+ const health = await checkQwickBrainHealth(config.qwickbrainUrl, timeout);
280
+ connectionStatus = {
281
+ connected: health.connected,
282
+ lastCheck: new Date(),
283
+ latencyMs: health.latencyMs,
284
+ error: health.error,
285
+ tailscaleStatus: tsStatus,
286
+ };
287
+ }, 30000); // Check every 30 seconds
288
+ // Register health checks
289
+ registry.registerHealthCheck({
290
+ name: 'qwickbrain-connection',
291
+ type: 'custom',
292
+ check: async () => {
293
+ const health = await checkQwickBrainHealth(config.qwickbrainUrl, timeout);
294
+ return {
295
+ healthy: health.connected,
296
+ latencyMs: health.latencyMs,
297
+ error: health.error,
298
+ };
299
+ },
300
+ });
301
+ registry.registerHealthCheck({
302
+ name: 'qwickbrain-tailscale',
303
+ type: 'custom',
304
+ check: async () => {
305
+ const status = await checkTailscaleStatus();
306
+ return {
307
+ healthy: status === 'connected',
308
+ status,
309
+ };
310
+ },
311
+ });
312
+ // Add API routes if enabled
313
+ if (apiEnabled) {
314
+ // GET /mcp/status - Connection status (no auth required)
315
+ registry.addRoute({
316
+ method: 'get',
317
+ path: `${apiPrefix}/status`,
318
+ pluginId: 'qwickbrain',
319
+ handler: async (_req, res) => {
320
+ res.json({
321
+ connected: connectionStatus.connected,
322
+ lastCheck: connectionStatus.lastCheck.toISOString(),
323
+ latencyMs: connectionStatus.latencyMs,
324
+ tailscaleStatus: connectionStatus.tailscaleStatus,
325
+ error: connectionStatus.error,
326
+ });
327
+ },
328
+ });
329
+ // GET /mcp/tools - List available MCP tools (auth required)
330
+ registry.addRoute({
331
+ method: 'get',
332
+ path: `${apiPrefix}/tools`,
333
+ pluginId: 'qwickbrain',
334
+ handler: async (req, res) => {
335
+ // Check authentication
336
+ const authError = checkAuth(req);
337
+ if (authError) {
338
+ res.status(authError.status).json(authError.body);
339
+ return;
340
+ }
341
+ const user = getAuthenticatedUser(req);
342
+ // Check rate limits
343
+ const rateLimitError = checkRateLimits(user?.id);
344
+ if (rateLimitError) {
345
+ Object.entries(rateLimitError.headers).forEach(([key, value]) => {
346
+ res.setHeader(key, value);
347
+ });
348
+ res.status(rateLimitError.status).json(rateLimitError.body);
349
+ return;
350
+ }
351
+ try {
352
+ if (!connectionStatus.connected) {
353
+ res.status(503).json({
354
+ error: 'QwickBrain not connected',
355
+ details: connectionStatus.error,
356
+ });
357
+ return;
358
+ }
359
+ // Fetch tools from QwickBrain
360
+ const response = await proxyToQwickBrain(config.qwickbrainUrl, '/tools', { timeout });
361
+ if (!response.ok) {
362
+ res.status(response.status).json({
363
+ error: 'Failed to fetch tools from QwickBrain',
364
+ });
365
+ return;
366
+ }
367
+ const data = await response.json();
368
+ const tools = data.tools || [];
369
+ // Filter to exposed tools only
370
+ const filteredTools = tools.filter(tool => isToolExposed(tool.name));
371
+ res.json({
372
+ tools: filteredTools,
373
+ count: filteredTools.length,
374
+ });
375
+ }
376
+ catch (error) {
377
+ log('Error fetching tools', { error: String(error) });
378
+ res.status(500).json({
379
+ error: 'Failed to fetch tools',
380
+ details: error instanceof Error ? error.message : 'Unknown error',
381
+ });
382
+ }
383
+ },
384
+ });
385
+ // POST /mcp/tools/:name - Execute an MCP tool (auth required)
386
+ registry.addRoute({
387
+ method: 'post',
388
+ path: `${apiPrefix}/tools/:name`,
389
+ pluginId: 'qwickbrain',
390
+ handler: async (req, res) => {
391
+ // Check authentication
392
+ const authError = checkAuth(req);
393
+ if (authError) {
394
+ res.status(authError.status).json(authError.body);
395
+ return;
396
+ }
397
+ const toolName = req.params.name;
398
+ const user = getAuthenticatedUser(req);
399
+ // Check rate limits
400
+ const rateLimitError = checkRateLimits(user?.id);
401
+ if (rateLimitError) {
402
+ Object.entries(rateLimitError.headers).forEach(([key, value]) => {
403
+ res.setHeader(key, value);
404
+ });
405
+ res.status(rateLimitError.status).json(rateLimitError.body);
406
+ return;
407
+ }
408
+ try {
409
+ // Check if tool is exposed
410
+ if (!isToolExposed(toolName)) {
411
+ res.status(403).json({
412
+ error: 'Tool not available',
413
+ tool: toolName,
414
+ });
415
+ return;
416
+ }
417
+ if (!connectionStatus.connected) {
418
+ res.status(503).json({
419
+ error: 'QwickBrain not connected',
420
+ details: connectionStatus.error,
421
+ });
422
+ return;
423
+ }
424
+ const toolRequest = {
425
+ name: toolName,
426
+ arguments: req.body || {},
427
+ };
428
+ log('Executing tool', { tool: toolName, userId: user?.id, arguments: req.body });
429
+ // Proxy the tool call to QwickBrain
430
+ const response = await proxyToQwickBrain(config.qwickbrainUrl, `/tools/${toolName}`, {
431
+ method: 'POST',
432
+ body: toolRequest.arguments,
433
+ timeout,
434
+ });
435
+ if (!response.ok) {
436
+ const errorText = await response.text();
437
+ res.status(response.status).json({
438
+ error: 'Tool execution failed',
439
+ details: errorText,
440
+ });
441
+ return;
442
+ }
443
+ const result = await response.json();
444
+ log('Tool executed successfully', { tool: toolName });
445
+ res.json(result);
446
+ }
447
+ catch (error) {
448
+ log('Error executing tool', { tool: toolName, error: String(error) });
449
+ res.status(500).json({
450
+ error: 'Tool execution failed',
451
+ tool: toolName,
452
+ details: error instanceof Error ? error.message : 'Unknown error',
453
+ });
454
+ }
455
+ },
456
+ });
457
+ // GET /mcp/sse - Server-Sent Events endpoint for streaming (auth required)
458
+ registry.addRoute({
459
+ method: 'get',
460
+ path: `${apiPrefix}/sse`,
461
+ pluginId: 'qwickbrain',
462
+ handler: async (req, res) => {
463
+ // Check authentication
464
+ const authError = checkAuth(req);
465
+ if (authError) {
466
+ res.status(authError.status).json(authError.body);
467
+ return;
468
+ }
469
+ const user = getAuthenticatedUser(req);
470
+ // Set SSE headers
471
+ res.setHeader('Content-Type', 'text/event-stream');
472
+ res.setHeader('Cache-Control', 'no-cache');
473
+ res.setHeader('Connection', 'keep-alive');
474
+ res.setHeader('X-Accel-Buffering', 'no');
475
+ // Send initial connection event
476
+ res.write(`event: connected\ndata: ${JSON.stringify({ status: 'connected', userId: user?.id })}\n\n`);
477
+ // Keep connection alive with periodic pings
478
+ const pingInterval = setInterval(() => {
479
+ res.write(`event: ping\ndata: ${JSON.stringify({ time: new Date().toISOString() })}\n\n`);
480
+ }, 30000);
481
+ // Handle client disconnect
482
+ req.on('close', () => {
483
+ clearInterval(pingInterval);
484
+ log('SSE client disconnected', { userId: user?.id });
485
+ });
486
+ log('SSE client connected', { userId: user?.id });
487
+ },
488
+ });
489
+ }
490
+ log('QwickBrain plugin started');
491
+ },
492
+ async onStop() {
493
+ log('Stopping QwickBrain plugin');
494
+ if (healthCheckInterval) {
495
+ clearInterval(healthCheckInterval);
496
+ healthCheckInterval = null;
497
+ }
498
+ if (rateLimitCleanupInterval) {
499
+ clearInterval(rateLimitCleanupInterval);
500
+ rateLimitCleanupInterval = null;
501
+ }
502
+ // Clear rate limit store
503
+ rateLimitStore.clear();
504
+ connectionStatus = {
505
+ connected: false,
506
+ lastCheck: new Date(),
507
+ tailscaleStatus: 'unknown',
508
+ };
509
+ log('QwickBrain plugin stopped');
510
+ },
511
+ };
512
+ }
513
+ // ========================================
514
+ // Helper Functions
515
+ // ========================================
516
+ /**
517
+ * Get the current connection status
518
+ */
519
+ export function getConnectionStatus() {
520
+ return { ...connectionStatus };
521
+ }
522
+ /**
523
+ * Check if QwickBrain is connected
524
+ */
525
+ export function isConnected() {
526
+ return connectionStatus.connected;
527
+ }
528
+ //# sourceMappingURL=qwickbrain-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qwickbrain-plugin.js","sourceRoot":"","sources":["../../../src/plugins/qwickbrain/qwickbrain-plugin.ts"],"names":[],"mappings":"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"}