@loop_ouroboros/mcp-hub-lite 1.2.0 → 1.2.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 (83) hide show
  1. package/CHANGELOG.md +23 -4
  2. package/README.md +12 -8
  3. package/dist/client/assets/{HomeView-BBwvy1oj.js → HomeView-V1fKvWQ8.js} +1 -1
  4. package/dist/client/assets/{ResourceDetailView-CZ2aB73w.js → ResourceDetailView-DHGHssrh.js} +1 -1
  5. package/dist/client/assets/{ResourcesView-CN1NlhWs.js → ResourcesView-B1bvkmQD.js} +1 -1
  6. package/dist/client/assets/{ServerDashboard-k652Vw4Z.js → ServerDashboard-CZCByd7y.js} +1 -1
  7. package/dist/client/assets/{ServerDetail-BLQ-a4cO.js → ServerDetail-CI5UD8gj.js} +1 -1
  8. package/dist/client/assets/{ServerListView-BHrsFD5i.js → ServerListView-D8qv-xYg.js} +1 -1
  9. package/dist/client/assets/SettingsView-C-ae0-zz.js +1 -0
  10. package/dist/client/assets/{ToolCallDialog-BfPjLxfV.js → ToolCallDialog-BudOyGvS.js} +1 -1
  11. package/dist/client/assets/{ToolsView-CyuhYAE2.js → ToolsView-CbQkgTAu.js} +1 -1
  12. package/dist/client/assets/{_baseClone-DO5qfalW.js → _baseClone-e9R6V78L.js} +1 -1
  13. package/dist/client/assets/{el-form-item-CcGsD2K_.js → el-form-item-Dyx5MiWB.js} +1 -1
  14. package/dist/client/assets/{el-input-tYgeiaCT.js → el-input-CL9HPfdW.js} +1 -1
  15. package/dist/client/assets/{el-loading-Dwl9E_Vr.js → el-loading-2TW6JdfY.js} +1 -1
  16. package/dist/client/assets/{el-overlay-kqX_BABo.js → el-overlay-B5ZGCmXY.js} +1 -1
  17. package/dist/client/assets/{el-radio-group-D8aWBVOT.js → el-radio-group-Cr2ScjjJ.js} +1 -1
  18. package/dist/client/assets/{el-skeleton-item-BRwIFspE.js → el-skeleton-item-CdAfEgVR.js} +1 -1
  19. package/dist/client/assets/{el-switch-BF8c-xeU.js → el-switch-DnN1s0Wb.js} +1 -1
  20. package/dist/client/assets/{el-tab-pane-C4Ep94cd.js → el-tab-pane-BebZh0XF.js} +1 -1
  21. package/dist/client/assets/{el-table-column-Cog6uCh-.js → el-table-column-CV2zp3yI.js} +1 -1
  22. package/dist/client/assets/{index-ByNBhPAR.js → index-Ci5n5dA9.js} +1 -1
  23. package/dist/client/assets/index-DTZ9o3XO.js +2 -0
  24. package/dist/client/assets/{omit-CUnDT6sS.js → omit-DlmW8Yd6.js} +1 -1
  25. package/dist/client/assets/{raf-CmzeRPMd.js → raf-CeCd08aN.js} +1 -1
  26. package/dist/client/index.html +1 -1
  27. package/dist/server/shared/models/server.model.d.ts +22 -0
  28. package/dist/server/shared/models/server.model.d.ts.map +1 -1
  29. package/dist/server/shared/models/server.model.js +41 -5
  30. package/dist/server/src/api/mcp/gateway.d.ts.map +1 -1
  31. package/dist/server/src/api/mcp/gateway.js +13 -5
  32. package/dist/server/src/api/web/resources.d.ts.map +1 -1
  33. package/dist/server/src/api/web/resources.js +26 -2
  34. package/dist/server/src/cli/index.js +1 -1
  35. package/dist/server/src/config/config-loader.js +1 -1
  36. package/dist/server/src/config/config-migrator.d.ts.map +1 -1
  37. package/dist/server/src/config/config-migrator.js +1 -0
  38. package/dist/server/src/index.js +2 -7
  39. package/dist/server/src/server/dev-server.js +9 -48
  40. package/dist/server/src/server/runner.d.ts +12 -24
  41. package/dist/server/src/server/runner.d.ts.map +1 -1
  42. package/dist/server/src/server/runner.js +29 -109
  43. package/dist/server/src/server/startup.d.ts +43 -0
  44. package/dist/server/src/server/startup.d.ts.map +1 -0
  45. package/dist/server/src/server/startup.js +89 -0
  46. package/dist/server/src/services/connection/connection-manager.d.ts +52 -0
  47. package/dist/server/src/services/connection/connection-manager.d.ts.map +1 -1
  48. package/dist/server/src/services/connection/connection-manager.js +283 -193
  49. package/dist/server/src/services/gateway/gateway.service.d.ts.map +1 -1
  50. package/dist/server/src/services/gateway/gateway.service.js +31 -10
  51. package/dist/server/src/services/gateway/global-transport.d.ts.map +1 -1
  52. package/dist/server/src/services/gateway/global-transport.js +11 -5
  53. package/dist/server/src/services/hub-manager.service.d.ts +2 -0
  54. package/dist/server/src/services/hub-manager.service.d.ts.map +1 -1
  55. package/dist/server/src/services/hub-manager.service.js +3 -16
  56. package/dist/server/src/utils/json-utils.d.ts +7 -0
  57. package/dist/server/src/utils/json-utils.d.ts.map +1 -1
  58. package/dist/server/src/utils/json-utils.js +17 -0
  59. package/dist/server/src/utils/logger/log-modules.d.ts +3 -0
  60. package/dist/server/src/utils/logger/log-modules.d.ts.map +1 -1
  61. package/dist/server/src/utils/logger/log-modules.js +2 -0
  62. package/dist/server/src/utils/port-checker.d.ts +18 -0
  63. package/dist/server/src/utils/port-checker.d.ts.map +1 -1
  64. package/dist/server/src/utils/port-checker.js +38 -0
  65. package/dist/server/src/utils/transports/stdio-transport.d.ts +12 -0
  66. package/dist/server/src/utils/transports/stdio-transport.d.ts.map +1 -1
  67. package/dist/server/src/utils/transports/stdio-transport.js +51 -2
  68. package/dist/server/src/utils/transports/transport-factory.d.ts +5 -1
  69. package/dist/server/src/utils/transports/transport-factory.d.ts.map +1 -1
  70. package/dist/server/src/utils/transports/transport-factory.js +5 -2
  71. package/dist/server/tests/integration/gateway/fault-tolerance.test.js +13 -2
  72. package/dist/server/tests/integration/gateway/mcp-connection.test.js +13 -2
  73. package/dist/server/tests/unit/config/config-migrator.test.js +4 -2
  74. package/dist/server/tests/unit/config/config.schema.test.js +2 -1
  75. package/dist/server/tests/unit/server/runner.test.js +77 -92
  76. package/dist/server/tests/unit/services/hub-manager-service.test.js +3 -2
  77. package/dist/server/tests/unit/utils/config.test.js +14 -7
  78. package/dist/server/tests/unit/utils/json-utils.test.js +28 -14
  79. package/dist/server/vite.config.d.ts.map +1 -1
  80. package/dist/server/vite.config.js +1 -0
  81. package/package.json +1 -1
  82. package/dist/client/assets/SettingsView-CUOFNXrz.js +0 -1
  83. package/dist/client/assets/index-CTB6oe-9.js +0 -2
@@ -4,9 +4,8 @@ import { buildApp } from '../../../src/app.js';
4
4
  import { configManager } from '../../../src/config/config-manager.js';
5
5
  import { logger } from '../../../src/utils/logger.js';
6
6
  import { mcpConnectionManager } from '../../../src/services/mcp-connection-manager.js';
7
- import { gateway } from '../../../src/services/gateway.service.js';
8
7
  import { PidManager } from '../../../src/pid/manager.js';
9
- import { checkPort } from '../../../src/utils/port-checker.js';
8
+ import { checkPort, checkPortWithExit } from '../../../src/utils/port-checker.js';
10
9
  // Mock resolveInstanceConfig to return a valid resolved config
11
10
  vi.mock('@config/config-migrator.js', () => ({
12
11
  resolveInstanceConfig: vi.fn(() => ({
@@ -46,15 +45,10 @@ vi.mock('@utils/logger.js', () => ({
46
45
  }));
47
46
  vi.mock('@services/mcp-connection-manager.js', () => ({
48
47
  mcpConnectionManager: {
49
- connect: vi.fn(),
48
+ connect: vi.fn(() => Promise.resolve(true)),
50
49
  disconnectAll: vi.fn()
51
50
  }
52
51
  }));
53
- vi.mock('@services/gateway.service.js', () => ({
54
- gateway: {
55
- start: vi.fn()
56
- }
57
- }));
58
52
  vi.mock('@pid/manager.js', () => ({
59
53
  PidManager: {
60
54
  writePid: vi.fn(),
@@ -62,7 +56,8 @@ vi.mock('@pid/manager.js', () => ({
62
56
  }
63
57
  }));
64
58
  vi.mock('@utils/port-checker.js', () => ({
65
- checkPort: vi.fn()
59
+ checkPort: vi.fn(),
60
+ checkPortWithExit: vi.fn().mockResolvedValue(undefined)
66
61
  }));
67
62
  describe('Server Runner', () => {
68
63
  beforeEach(() => {
@@ -75,9 +70,13 @@ describe('Server Runner', () => {
75
70
  // Clean up any remaining listeners
76
71
  process.removeAllListeners('SIGTERM');
77
72
  process.removeAllListeners('SIGINT');
73
+ // Reset mock implementations that might persist between tests
74
+ vi.mocked(checkPortWithExit).mockReset();
75
+ vi.mocked(configManager.addServerInstance).mockReset();
76
+ vi.mocked(configManager.getServerInstancesByName).mockReset();
78
77
  });
79
78
  describe('runServer function', () => {
80
- it('should start server in HTTP mode successfully', async () => {
79
+ it('should start server successfully', async () => {
81
80
  // Setup mocks
82
81
  const mockApp = {
83
82
  listen: vi.fn().mockResolvedValue(undefined),
@@ -96,7 +95,8 @@ describe('Server Runner', () => {
96
95
  rotationAge: '7d',
97
96
  jsonPretty: true,
98
97
  mcpCommDebug: false,
99
- apiDebug: false
98
+ apiDebug: false,
99
+ gatewayDebug: false
100
100
  }
101
101
  },
102
102
  security: {
@@ -113,51 +113,13 @@ describe('Server Runner', () => {
113
113
  vi.mocked(configManager.getServers).mockReturnValue([]);
114
114
  vi.mocked(checkPort).mockResolvedValue({ inUse: false });
115
115
  // Execute
116
- await runServer({ stdio: false, port: 3000, host: 'localhost' });
116
+ await runServer({ port: 3000, host: 'localhost' });
117
117
  // Verify
118
118
  expect(buildApp).toHaveBeenCalled();
119
119
  expect(mockApp.listen).toHaveBeenCalledWith({ port: 3000, host: 'localhost' });
120
120
  expect(PidManager.writePid).toHaveBeenCalled();
121
121
  expect(logger.info).toHaveBeenCalledWith('MCP Hub Lite Server running at http://localhost:3000', expect.any(Object));
122
122
  });
123
- it('should start server in stdio mode successfully', async () => {
124
- // Setup mocks
125
- const mockConfig = {
126
- version: '1.1.0',
127
- system: {
128
- host: 'localhost',
129
- port: 3000,
130
- language: 'zh',
131
- theme: 'system',
132
- logging: {
133
- level: 'info',
134
- rotationAge: '7d',
135
- jsonPretty: true,
136
- mcpCommDebug: false,
137
- apiDebug: false
138
- }
139
- },
140
- security: {
141
- allowedNetworks: ['127.0.0.1'],
142
- maxConcurrentConnections: 50,
143
- connectionTimeout: 30000,
144
- idleConnectionTimeout: 300000,
145
- maxConnections: 50
146
- },
147
- servers: {},
148
- tagDefinitions: []
149
- };
150
- vi.mocked(configManager.getConfig).mockReturnValue(mockConfig);
151
- vi.mocked(configManager.getServers).mockReturnValue([]);
152
- // Execute
153
- await runServer({ stdio: true });
154
- // Verify
155
- expect(buildApp).not.toHaveBeenCalled();
156
- expect(gateway.start).toHaveBeenCalled();
157
- expect(PidManager.writePid).toHaveBeenCalled();
158
- expect(logger.setUseStderr).toHaveBeenCalledWith(true);
159
- expect(logger.info).toHaveBeenCalledWith('Starting in MCP Gateway mode (stdio)...', expect.any(Object));
160
- });
161
123
  it('should handle port already in use by self project', async () => {
162
124
  // Setup mocks
163
125
  const mockApp = { listen: vi.fn(), close: vi.fn() };
@@ -174,7 +136,8 @@ describe('Server Runner', () => {
174
136
  rotationAge: '7d',
175
137
  jsonPretty: true,
176
138
  mcpCommDebug: false,
177
- apiDebug: false
139
+ apiDebug: false,
140
+ gatewayDebug: false
178
141
  }
179
142
  },
180
143
  security: {
@@ -189,20 +152,20 @@ describe('Server Runner', () => {
189
152
  };
190
153
  vi.mocked(configManager.getConfig).mockReturnValue(mockConfig);
191
154
  vi.mocked(configManager.getServers).mockReturnValue([]);
192
- vi.mocked(checkPort).mockResolvedValue({
193
- inUse: true,
194
- isSelfProject: true,
195
- pid: 1234
196
- });
197
- // Spy on process.exit
155
+ // Spy on process.exit before setting up checkPortWithExit mock
198
156
  const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {
199
157
  throw new Error('process.exit called');
200
158
  }));
159
+ // Mock checkPortWithExit to call process.exit(1)
160
+ vi.mocked(checkPortWithExit).mockImplementation(() => {
161
+ // Call the real implementation's exit behavior
162
+ logger.error('MCP Hub Lite is already running on port 3000 (PID: 1234)', expect.any(Object));
163
+ logger.error("Use 'npm run stop' or 'mcp-hub-lite stop' to stop the running instance.", expect.any(Object));
164
+ process.exit(1);
165
+ });
201
166
  // Execute and expect error
202
- await expect(runServer({ stdio: false, port: 3000, host: 'localhost' })).rejects.toThrow('process.exit called');
167
+ await expect(runServer({ port: 3000, host: 'localhost' })).rejects.toThrow('process.exit called');
203
168
  // Verify
204
- expect(logger.error).toHaveBeenCalledWith('MCP Hub Lite is already running on port 3000 (PID: 1234)', expect.any(Object));
205
- expect(logger.error).toHaveBeenCalledWith("Use 'npm run stop' or 'mcp-hub-lite stop' to stop the running instance.", expect.any(Object));
206
169
  expect(exitSpy).toHaveBeenCalledWith(1);
207
170
  // Restore
208
171
  exitSpy.mockRestore();
@@ -223,7 +186,8 @@ describe('Server Runner', () => {
223
186
  rotationAge: '7d',
224
187
  jsonPretty: true,
225
188
  mcpCommDebug: false,
226
- apiDebug: false
189
+ apiDebug: false,
190
+ gatewayDebug: false
227
191
  }
228
192
  },
229
193
  security: {
@@ -238,24 +202,22 @@ describe('Server Runner', () => {
238
202
  };
239
203
  vi.mocked(configManager.getConfig).mockReturnValue(mockConfig);
240
204
  vi.mocked(configManager.getServers).mockReturnValue([]);
241
- vi.mocked(checkPort).mockResolvedValue({
242
- inUse: true,
243
- isSelfProject: false,
244
- pid: 5678,
245
- processName: 'other-app',
246
- commandLine: 'node other-app.js'
247
- });
248
- // Spy on process.exit
205
+ // Spy on process.exit before setting up checkPortWithExit mock
249
206
  const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {
250
207
  throw new Error('process.exit called');
251
208
  }));
209
+ // Mock checkPortWithExit to call process.exit(1)
210
+ vi.mocked(checkPortWithExit).mockImplementation(() => {
211
+ // Call the real implementation's exit behavior
212
+ logger.error('Port 3000 is already in use by another application:', expect.any(Object));
213
+ logger.error(' Process: other-app (PID: 5678)', expect.any(Object));
214
+ logger.error(' Command: node other-app.js', expect.any(Object));
215
+ logger.error('Please stop the conflicting application or use a different port.', expect.any(Object));
216
+ process.exit(1);
217
+ });
252
218
  // Execute and expect error
253
- await expect(runServer({ stdio: false, port: 3000, host: 'localhost' })).rejects.toThrow('process.exit called');
219
+ await expect(runServer({ port: 3000, host: 'localhost' })).rejects.toThrow('process.exit called');
254
220
  // Verify
255
- expect(logger.error).toHaveBeenCalledWith('Port 3000 is already in use by another application:', expect.any(Object));
256
- expect(logger.error).toHaveBeenCalledWith(' Process: other-app (PID: 5678)', expect.any(Object));
257
- expect(logger.error).toHaveBeenCalledWith(' Command: node other-app.js', expect.any(Object));
258
- expect(logger.error).toHaveBeenCalledWith('Please stop the conflicting application or use a different port.', expect.any(Object));
259
221
  expect(exitSpy).toHaveBeenCalledWith(1);
260
222
  // Restore
261
223
  exitSpy.mockRestore();
@@ -279,7 +241,8 @@ describe('Server Runner', () => {
279
241
  rotationAge: '7d',
280
242
  jsonPretty: true,
281
243
  mcpCommDebug: false,
282
- apiDebug: false
244
+ apiDebug: false,
245
+ gatewayDebug: false
283
246
  }
284
247
  },
285
248
  security: {
@@ -333,21 +296,40 @@ describe('Server Runner', () => {
333
296
  }
334
297
  ];
335
298
  vi.mocked(configManager.getServers).mockReturnValue(mockServers);
299
+ // Track if addServerInstance was called for enabled-server
300
+ let addServerInstanceCalled = false;
301
+ vi.mocked(configManager.addServerInstance).mockImplementation(async (name) => {
302
+ if (name === 'enabled-server') {
303
+ addServerInstanceCalled = true;
304
+ return {
305
+ id: 'new-instance',
306
+ enabled: true,
307
+ args: [],
308
+ env: {},
309
+ headers: {},
310
+ tags: {}
311
+ };
312
+ }
313
+ return {
314
+ id: 'instance-1',
315
+ enabled: false,
316
+ args: [],
317
+ env: {},
318
+ headers: {},
319
+ tags: {}
320
+ };
321
+ });
322
+ // Make getServerInstancesByName return the new instance after addServerInstance is called
336
323
  vi.mocked(configManager.getServerInstancesByName).mockImplementation((name) => {
337
- if (name === 'enabled-server')
338
- return [];
324
+ if (name === 'enabled-server') {
325
+ return addServerInstanceCalled
326
+ ? [{ id: 'new-instance', enabled: true, args: [], env: {}, headers: {}, tags: {} }]
327
+ : [];
328
+ }
339
329
  return [{ id: 'instance-1', enabled: false, args: [], env: {}, headers: {}, tags: {} }];
340
330
  });
341
- vi.mocked(configManager.addServerInstance).mockResolvedValue({
342
- id: 'new-instance',
343
- enabled: true,
344
- args: [],
345
- env: {},
346
- headers: {},
347
- tags: {}
348
- });
349
331
  // Execute
350
- await runServer({ stdio: false, port: 3000, host: 'localhost' });
332
+ await runServer({ port: 3000, host: 'localhost' });
351
333
  // Verify
352
334
  // Only enabled server should be connected (1 call expected)
353
335
  expect(mcpConnectionManager.connect).toHaveBeenCalledTimes(1);
@@ -377,7 +359,8 @@ describe('Server Runner', () => {
377
359
  rotationAge: '7d',
378
360
  jsonPretty: true,
379
361
  mcpCommDebug: false,
380
- apiDebug: false
362
+ apiDebug: false,
363
+ gatewayDebug: false
381
364
  }
382
365
  },
383
366
  security: {
@@ -398,7 +381,7 @@ describe('Server Runner', () => {
398
381
  .spyOn(process, 'exit')
399
382
  .mockImplementation((() => { }));
400
383
  // Start server
401
- await runServer({ stdio: false, port: 3000, host: 'localhost' });
384
+ await runServer({ port: 3000, host: 'localhost' });
402
385
  // Trigger SIGTERM
403
386
  process.emit('SIGTERM');
404
387
  // Wait for async operations
@@ -431,7 +414,8 @@ describe('Server Runner', () => {
431
414
  rotationAge: '7d',
432
415
  jsonPretty: true,
433
416
  mcpCommDebug: false,
434
- apiDebug: false
417
+ apiDebug: false,
418
+ gatewayDebug: false
435
419
  }
436
420
  },
437
421
  security: {
@@ -452,7 +436,7 @@ describe('Server Runner', () => {
452
436
  .spyOn(process, 'exit')
453
437
  .mockImplementation((() => { }));
454
438
  // Start server
455
- await runServer({ stdio: false, port: 3000, host: 'localhost' });
439
+ await runServer({ port: 3000, host: 'localhost' });
456
440
  // Trigger SIGINT
457
441
  process.emit('SIGINT');
458
442
  // Wait for async operations
@@ -481,7 +465,8 @@ describe('Server Runner', () => {
481
465
  rotationAge: '7d',
482
466
  jsonPretty: true,
483
467
  mcpCommDebug: false,
484
- apiDebug: false
468
+ apiDebug: false,
469
+ gatewayDebug: false
485
470
  }
486
471
  },
487
472
  security: {
@@ -500,7 +485,7 @@ describe('Server Runner', () => {
500
485
  throw new Error('process.exit called');
501
486
  }));
502
487
  // Execute and expect error
503
- await expect(runServer({ stdio: false, port: 3000, host: 'localhost' })).rejects.toThrow('process.exit called');
488
+ await expect(runServer({ port: 3000, host: 'localhost' })).rejects.toThrow('process.exit called');
504
489
  // Verify
505
490
  expect(logger.error).toHaveBeenCalledWith('Failed to start server:', expect.any(Error), expect.any(Object));
506
491
  expect(PidManager.removePid).toHaveBeenCalled();
@@ -49,7 +49,7 @@ describe('HubManagerService', () => {
49
49
  vi.clearAllMocks();
50
50
  service = new HubManagerService(configManager);
51
51
  });
52
- it('should auto-connect when adding an enabled server instance', async () => {
52
+ it('should add server instance without auto-connect', async () => {
53
53
  // Import the mocked module
54
54
  const { resolveInstanceConfig } = await import('../../../src/config/config-migrator.js');
55
55
  const serverName = 'Test Server';
@@ -91,7 +91,8 @@ describe('HubManagerService', () => {
91
91
  await service.addServerInstance(serverName, serverInstanceConfig);
92
92
  expect(configManager.addServer).toHaveBeenCalled();
93
93
  expect(configManager.addServerInstance).toHaveBeenCalled();
94
- expect(mcpConnectionManager.connect).toHaveBeenCalled();
94
+ // Note: addServerInstance no longer auto-connects - explicit connection via connectServerInstances is required
95
+ expect(mcpConnectionManager.connect).not.toHaveBeenCalled();
95
96
  });
96
97
  it('should NOT auto-connect when adding a disabled server instance', async () => {
97
98
  // Import the mocked module
@@ -80,7 +80,8 @@ describe('ConfigManager', () => {
80
80
  rotationAge: '30d',
81
81
  jsonPretty: true,
82
82
  mcpCommDebug: false,
83
- apiDebug: false
83
+ apiDebug: false,
84
+ gatewayDebug: false
84
85
  }
85
86
  },
86
87
  security: {
@@ -149,7 +150,8 @@ describe('ConfigManager', () => {
149
150
  rotationAge: '7d',
150
151
  jsonPretty: true,
151
152
  mcpCommDebug: false,
152
- apiDebug: false
153
+ apiDebug: false,
154
+ gatewayDebug: false
153
155
  }
154
156
  }
155
157
  });
@@ -193,7 +195,8 @@ describe('ConfigManager', () => {
193
195
  rotationAge: '7d',
194
196
  jsonPretty: true,
195
197
  mcpCommDebug: false,
196
- apiDebug: false
198
+ apiDebug: false,
199
+ gatewayDebug: false
197
200
  }
198
201
  }
199
202
  });
@@ -235,7 +238,8 @@ describe('ConfigManager', () => {
235
238
  rotationAge: '7d',
236
239
  jsonPretty: true,
237
240
  mcpCommDebug: false,
238
- apiDebug: false
241
+ apiDebug: false,
242
+ gatewayDebug: false
239
243
  }
240
244
  }
241
245
  };
@@ -404,7 +408,8 @@ describe('ConfigManager', () => {
404
408
  rotationAge: '7d',
405
409
  jsonPretty: true,
406
410
  mcpCommDebug: false,
407
- apiDebug: false
411
+ apiDebug: false,
412
+ gatewayDebug: false
408
413
  }
409
414
  },
410
415
  security: {
@@ -457,7 +462,8 @@ describe('ConfigManager', () => {
457
462
  rotationAge: '7d',
458
463
  jsonPretty: true,
459
464
  mcpCommDebug: false,
460
- apiDebug: false
465
+ apiDebug: false,
466
+ gatewayDebug: false
461
467
  }
462
468
  }
463
469
  });
@@ -474,7 +480,8 @@ describe('ConfigManager', () => {
474
480
  rotationAge: '7d',
475
481
  jsonPretty: true,
476
482
  mcpCommDebug: false,
477
- apiDebug: false
483
+ apiDebug: false,
484
+ gatewayDebug: false
478
485
  }
479
486
  },
480
487
  security: {
@@ -13,7 +13,8 @@ describe('json-utils', () => {
13
13
  logging: {
14
14
  jsonPretty: true,
15
15
  mcpCommDebug: false,
16
- apiDebug: false
16
+ apiDebug: false,
17
+ gatewayDebug: false
17
18
  }
18
19
  }
19
20
  }));
@@ -35,7 +36,8 @@ describe('json-utils', () => {
35
36
  logging: {
36
37
  jsonPretty: true,
37
38
  mcpCommDebug: false,
38
- apiDebug: false
39
+ apiDebug: false,
40
+ gatewayDebug: false
39
41
  }
40
42
  }
41
43
  }));
@@ -53,7 +55,8 @@ describe('json-utils', () => {
53
55
  logging: {
54
56
  jsonPretty: true,
55
57
  mcpCommDebug: false,
56
- apiDebug: false
58
+ apiDebug: false,
59
+ gatewayDebug: false
57
60
  }
58
61
  }
59
62
  }));
@@ -72,7 +75,8 @@ describe('json-utils', () => {
72
75
  logging: {
73
76
  jsonPretty: true,
74
77
  mcpCommDebug: false,
75
- apiDebug: false
78
+ apiDebug: false,
79
+ gatewayDebug: false
76
80
  }
77
81
  }
78
82
  }));
@@ -102,7 +106,8 @@ describe('json-utils', () => {
102
106
  logging: {
103
107
  jsonPretty: false,
104
108
  mcpCommDebug: false,
105
- apiDebug: false
109
+ apiDebug: false,
110
+ gatewayDebug: false
106
111
  }
107
112
  }
108
113
  }));
@@ -182,7 +187,8 @@ describe('json-utils', () => {
182
187
  logging: {
183
188
  jsonPretty: false,
184
189
  mcpCommDebug: false,
185
- apiDebug: false
190
+ apiDebug: false,
191
+ gatewayDebug: false
186
192
  }
187
193
  }
188
194
  }));
@@ -192,7 +198,8 @@ describe('json-utils', () => {
192
198
  logging: {
193
199
  jsonPretty: true,
194
200
  mcpCommDebug: false,
195
- apiDebug: false
201
+ apiDebug: false,
202
+ gatewayDebug: false
196
203
  }
197
204
  }
198
205
  }));
@@ -212,7 +219,8 @@ describe('json-utils', () => {
212
219
  logging: {
213
220
  jsonPretty: false, // Config says false, but env should override
214
221
  mcpCommDebug: false,
215
- apiDebug: false
222
+ apiDebug: false,
223
+ gatewayDebug: false
216
224
  }
217
225
  }
218
226
  }));
@@ -231,7 +239,8 @@ describe('json-utils', () => {
231
239
  logging: {
232
240
  jsonPretty: false, // Config says false, but env should override
233
241
  mcpCommDebug: false,
234
- apiDebug: false
242
+ apiDebug: false,
243
+ gatewayDebug: false
235
244
  }
236
245
  }
237
246
  }));
@@ -250,7 +259,8 @@ describe('json-utils', () => {
250
259
  logging: {
251
260
  jsonPretty: true, // Config says true, but env should override
252
261
  mcpCommDebug: false,
253
- apiDebug: false
262
+ apiDebug: false,
263
+ gatewayDebug: false
254
264
  }
255
265
  }
256
266
  }));
@@ -269,7 +279,8 @@ describe('json-utils', () => {
269
279
  logging: {
270
280
  jsonPretty: true, // Config says true, but env should override
271
281
  mcpCommDebug: false,
272
- apiDebug: false
282
+ apiDebug: false,
283
+ gatewayDebug: false
273
284
  }
274
285
  }
275
286
  }));
@@ -288,7 +299,8 @@ describe('json-utils', () => {
288
299
  logging: {
289
300
  jsonPretty: false,
290
301
  mcpCommDebug: false,
291
- apiDebug: false
302
+ apiDebug: false,
303
+ gatewayDebug: false
292
304
  }
293
305
  }
294
306
  }));
@@ -311,7 +323,8 @@ describe('json-utils', () => {
311
323
  logging: {
312
324
  jsonPretty: false,
313
325
  mcpCommDebug: true,
314
- apiDebug: true
326
+ apiDebug: true,
327
+ gatewayDebug: false
315
328
  }
316
329
  }
317
330
  }));
@@ -364,7 +377,8 @@ describe('json-utils', () => {
364
377
  logging: {
365
378
  jsonPretty: true,
366
379
  mcpCommDebug: false,
367
- apiDebug: false
380
+ apiDebug: false,
381
+ gatewayDebug: false
368
382
  }
369
383
  }
370
384
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"vite.config.d.ts","sourceRoot":"","sources":["../../vite.config.ts"],"names":[],"mappings":";AAwFA,wBAmFG"}
1
+ {"version":3,"file":"vite.config.d.ts","sourceRoot":"","sources":["../../vite.config.ts"],"names":[],"mappings":";AAwFA,wBAoFG"}
@@ -107,6 +107,7 @@ export default defineConfig({
107
107
  '@i18n': fileURLToPath(new URL('./frontend/src/i18n', import.meta.url)),
108
108
  '@locales': fileURLToPath(new URL('./frontend/src/locales', import.meta.url)),
109
109
  '@composables': fileURLToPath(new URL('./frontend/src/composables', import.meta.url)),
110
+ '@frontend-types': fileURLToPath(new URL('./frontend/src/types', import.meta.url)),
110
111
  '@utils': fileURLToPath(new URL('./frontend/src/utils', import.meta.url)),
111
112
  // Shared code aliases
112
113
  '@shared': fileURLToPath(new URL('./shared', import.meta.url)),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loop_ouroboros/mcp-hub-lite",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "A lightweight MCP management platform designed for independent developers",
5
5
  "license": "MIT",
6
6
  "author": "loop_ouroboros",
@@ -1 +0,0 @@
1
- import{h as J,E as Q,p as ae,L as ne,j as oe,P as ue,aL as ie,aM as de,aN as re,aO as me,s as ge,J as pe,aP as ce,aQ as fe}from"./index-CTB6oe-9.js";import{v as ve}from"./el-loading-Dwl9E_Vr.js";import{E as ye,a as _e}from"./el-tab-pane-C4Ep94cd.js";import{E as be,a as Ve}from"./el-switch-BF8c-xeU.js";import{a as W,E as X}from"./el-form-item-CcGsD2K_.js";import{a as he,E as Y}from"./el-input-tYgeiaCT.js";import{E as $e,a as ee,b as le}from"./el-overlay-kqX_BABo.js";import{t as te,a6 as se,c as O,r as k,A as h,C as n,$ as m,O as e,G as t,u as o,a9 as E,P as M,af as q,V as j,y as A,x as f,al as ke,h as H,j as xe,H as we}from"./vue-vendor-CbgVSHIh.js";import{E as R}from"./index-ByNBhPAR.js";import"./raf-CmzeRPMd.js";import"./typescript-Bp3YSIOJ.js";import"./event-BB_Ol6Sd.js";import"./omit-CUnDT6sS.js";import"./_baseClone-DO5qfalW.js";const Ce={class:"tag-manager"},Te={class:"flex items-center justify-between mb-4"},Ue={class:"text-lg font-semibold text-gray-900 dark:text-white"},Ee={key:0,class:"text-center py-8 text-gray-500 dark:text-gray-400"},De={key:1,class:"space-y-3"},Ne={class:"flex-1"},Pe={class:"flex items-center gap-2"},Se={class:"font-medium text-gray-900 dark:text-white"},je={key:0,class:"text-sm text-gray-500 dark:text-gray-400 mt-1"},Ae={key:1,class:"mt-2"},Ie={class:"flex flex-wrap gap-1"},Me={class:"flex items-center gap-2 ml-4"},Re={class:"flex justify-end gap-2"},ze={class:"text-gray-600 dark:text-gray-300"},Be={class:"flex justify-end gap-2"},Fe=te({__name:"TagManager",props:{modelValue:{}},emits:["update:modelValue"],setup(G,{emit:z}){const I=G,a=z,{t:B}=se(),b=O({get:()=>I.modelValue||[],set:d=>a("update:modelValue",d)}),T=k(!1),y=k(!1),U=k(!1),V=k(!1),N=k(),_=k(null),p=k({key:"",description:"",type:"string",values:[]}),D={key:[{required:!0,message:"Tag key is required",trigger:"blur"},{pattern:/^[a-zA-Z][a-zA-Z0-9-]*$/,message:"Key must start with a letter and contain only letters, numbers, and hyphens",trigger:"blur"}],type:[{required:!0,message:"Tag type is required",trigger:"change"}],values:[{validator:(d,i,v)=>{p.value.type==="enum"&&(!i||i.length===0)?v(new Error("At least one value is required for enum type")):v()},trigger:"change"}]};function P(){U.value=!1,_.value=null,p.value={key:"",description:"",type:"string",values:[]},T.value=!0}function K(d){U.value=!0,_.value=d,p.value={...d},T.value=!0}function l(){T.value=!1,N.value?.resetFields(),p.value={key:"",description:"",type:"string",values:[]},U.value=!1,_.value=null}function s(){N.value?.validate(d=>{if(d){V.value=!0;try{if(U.value&&_.value){const i=b.value.findIndex(v=>v.key===_.value.key);if(i!==-1){const v=[...b.value];v[i]={...p.value},b.value=v}}else{if(b.value.some(i=>i.key===p.value.key)){R.error("Tag key already exists"),V.value=!1;return}b.value=[...b.value,{...p.value}]}R.success(B("action.saved")),l()}finally{V.value=!1}}})}function c(d){_.value=d,y.value=!0}function $(){if(_.value){V.value=!0;try{b.value=b.value.filter(d=>d.key!==_.value.key),R.success(B("action.saved")),y.value=!1,_.value=null}finally{V.value=!1}}}return(d,i)=>{const v=Q,g=J,x=he,S=Y,w=X,C=le,F=ee,Z=W,u=$e;return f(),h("div",Ce,[n("div",Te,[n("h3",Ue,m(d.$t("settings.tagDefinitions")),1),e(g,{type:"primary",onClick:P},{default:t(()=>[e(v,{class:"mr-1"},{default:t(()=>[e(o(ae))]),_:1}),E(" "+m(d.$t("common.addTag")),1)]),_:1})]),b.value.length===0?(f(),h("div",Ee,m(d.$t("settings.noTagsDefined")),1)):(f(),h("div",De,[(f(!0),h(M,null,q(b.value,r=>(f(),h("div",{key:r.key,class:"flex items-center justify-between p-4 border rounded-lg dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"},[n("div",Ne,[n("div",Pe,[n("span",Se,m(r.key),1),e(x,{size:"small",type:"info"},{default:t(()=>[E(m(r.type),1)]),_:2},1024)]),r.description?(f(),h("div",je,m(r.description),1)):j("",!0),r.type==="enum"&&r.values&&r.values.length>0?(f(),h("div",Ae,[n("div",Ie,[(f(!0),h(M,null,q(r.values,L=>(f(),A(x,{key:L,size:"small",type:"success"},{default:t(()=>[E(m(L),1)]),_:2},1024))),128))])])):j("",!0)]),n("div",Me,[e(g,{size:"small",onClick:L=>K(r)},{default:t(()=>[e(v,null,{default:t(()=>[e(o(ne))]),_:1})]),_:1},8,["onClick"]),e(g,{size:"small",type:"danger",onClick:L=>c(r)},{default:t(()=>[e(v,null,{default:t(()=>[e(o(oe))]),_:1})]),_:1},8,["onClick"])])]))),128))])),e(u,{modelValue:T.value,"onUpdate:modelValue":i[4]||(i[4]=r=>T.value=r),title:U.value?d.$t("common.editTag"):d.$t("common.addTag"),width:"500px",class:"custom-dialog","before-close":l},{footer:t(()=>[n("div",Re,[e(g,{onClick:l},{default:t(()=>[E(m(d.$t("action.cancel")),1)]),_:1}),e(g,{type:"primary",onClick:s,loading:V.value},{default:t(()=>[E(m(d.$t("action.save")),1)]),_:1},8,["loading"])])]),default:t(()=>[e(Z,{model:p.value,rules:D,ref_key:"formRef",ref:N,"label-position":"top"},{default:t(()=>[e(w,{label:d.$t("settings.tagKey"),prop:"key"},{default:t(()=>[e(S,{modelValue:p.value.key,"onUpdate:modelValue":i[0]||(i[0]=r=>p.value.key=r),placeholder:d.$t("settings.tagKeyPlaceholder"),disabled:U.value},null,8,["modelValue","placeholder","disabled"])]),_:1},8,["label"]),e(w,{label:d.$t("settings.tagDescription"),prop:"description"},{default:t(()=>[e(S,{modelValue:p.value.description,"onUpdate:modelValue":i[1]||(i[1]=r=>p.value.description=r),type:"textarea",rows:2,placeholder:d.$t("settings.tagDescriptionPlaceholder")},null,8,["modelValue","placeholder"])]),_:1},8,["label"]),e(w,{label:d.$t("settings.tagType"),prop:"type"},{default:t(()=>[e(F,{modelValue:p.value.type,"onUpdate:modelValue":i[2]||(i[2]=r=>p.value.type=r),class:"w-full"},{default:t(()=>[e(C,{label:"String",value:"string"}),e(C,{label:"Number",value:"number"}),e(C,{label:"Boolean",value:"boolean"}),e(C,{label:"Enum",value:"enum"})]),_:1},8,["modelValue"])]),_:1},8,["label"]),p.value.type==="enum"?(f(),A(w,{key:0,label:d.$t("settings.tagValues"),prop:"values"},{default:t(()=>[e(F,{modelValue:p.value.values,"onUpdate:modelValue":i[3]||(i[3]=r=>p.value.values=r),multiple:"",filterable:"","allow-create":"","default-first-option":"","reserve-keyword":!1,placeholder:d.$t("settings.tagValuesPlaceholder"),class:"w-full"},{default:t(()=>[(f(!0),h(M,null,q(p.value.values,r=>(f(),A(C,{key:r,label:r,value:r},null,8,["label","value"]))),128))]),_:1},8,["modelValue","placeholder"])]),_:1},8,["label"])):j("",!0)]),_:1},8,["model"])]),_:1},8,["modelValue","title"]),e(u,{modelValue:y.value,"onUpdate:modelValue":i[6]||(i[6]=r=>y.value=r),title:d.$t("common.deleteTag"),width:"400px",class:"custom-dialog"},{footer:t(()=>[n("div",Be,[e(g,{onClick:i[5]||(i[5]=r=>y.value=!1)},{default:t(()=>[E(m(d.$t("action.cancel")),1)]),_:1}),e(g,{type:"danger",onClick:$,loading:V.value},{default:t(()=>[E(m(d.$t("action.delete")),1)]),_:1},8,["loading"])])]),default:t(()=>[n("p",ze,m(d.$t("settings.deleteTagConfirm")),1)]),_:1},8,["modelValue","title"])])}}}),Le={class:"h-full w-full overflow-y-auto"},Oe={class:"py-6 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto w-full"},qe={class:"mb-6 flex items-center justify-between"},Ke={class:"text-2xl font-bold text-gray-900 dark:text-white"},Ze={class:"pb-10"},Ge={class:"flex items-center gap-2"},He={class:"pt-4"},Je={class:"flex flex-col gap-2"},Qe={class:"flex items-center my-4"},We={class:"text-sm font-medium text-gray-900 dark:text-gray-100 mr-4"},Xe={class:"flex items-center gap-2"},Ye={class:"flex items-center gap-2"},el={class:"flex items-center gap-2"},ll={class:"flex items-center gap-2"},tl={class:"pt-4"},sl={class:"flex items-center my-4"},al={class:"text-sm font-medium text-gray-900 dark:text-gray-100 mr-4"},nl={class:"flex items-center gap-2"},ol={class:"pt-4"},ul={class:"text-xs text-gray-500 mt-1"},il={class:"space-y-4"},dl={class:"flex items-center gap-4"},rl={class:"w-[260px] text-sm font-medium text-gray-700 dark:text-gray-300"},ml={class:"flex items-center gap-4"},gl={class:"w-[260px] text-sm font-medium text-gray-700 dark:text-gray-300"},pl={class:"flex items-center gap-4"},cl={class:"w-[260px] text-sm font-medium text-gray-700 dark:text-gray-300"},fl={class:"flex items-center gap-2"},vl={class:"flex items-center gap-4"},yl={class:"w-[260px] text-sm font-medium text-gray-700 dark:text-gray-300"},_l={class:"flex items-center gap-2"},bl={class:"flex items-center gap-2"},Vl={class:"pt-4"},Al=te({__name:"SettingsView",setup(G){const{t:z}=se(),I=ue(),{config:a,loading:B}=ke(I),b=k(!1),T=k("system"),y={seconds:1,minutes:60,hours:3600,days:86400},U=["days","hours","minutes","seconds"],V=l=>{for(const s of U){const c=y[s];if(l>=c)return s}return"seconds"},N=O({get:()=>{const l=a.value?.system?.logging?.rotationAge||"7d",s=parseInt(l.replace(/[^\d]/g,""))||7;return Number(Math.round(s))},set:l=>{a.value?.system?.logging&&l!==void 0&&l!==null&&(a.value.system.logging.rotationAge=`${l}d`)}}),_=k(V((a.value?.security?.connectionTimeout||3e4)/1e3)),p=O({get:()=>{const s=(a.value?.security?.connectionTimeout||3e4)/1e3,c=V(s),$=s/y[c];return Number(Math.round($))},set:l=>{a.value?.security&&l!==void 0&&l!==null&&(a.value.security.connectionTimeout=Number(l)*y[_.value]*1e3)}}),D=k(V((a.value?.security?.idleConnectionTimeout||3e5)/1e3)),P=O({get:()=>{const s=(a.value?.security?.idleConnectionTimeout||3e5)/1e3,c=V(s),$=s/y[c];return Number(Math.round($))},set:l=>{a.value?.security&&l!==void 0&&l!==null&&(a.value.security.idleConnectionTimeout=Number(l)*y[D.value]*1e3)}});H(_,(l,s)=>{if(s&&l!==s){const c=y[l]/y[s],$=p.value;p.value=Math.round($/c)}}),H(D,(l,s)=>{if(s&&l!==s){const c=y[l]/y[s],$=P.value;P.value=Math.round($/c)}}),xe(async()=>{a.value.host||await I.fetchConfig(),a.value?.security&&(_.value=V((a.value.security.connectionTimeout||3e4)/1e3),D.value=V((a.value.security.idleConnectionTimeout||3e5)/1e3))});async function K(){b.value=!0;try{await I.updateConfig(a.value),R.success(z("settings.saveSuccess"))}catch(l){R.error(z("settings.saveError")+": "+l.message)}finally{b.value=!1}}return(l,s)=>{const c=Q,$=J,d=Y,i=X,v=be,g=le,x=ee,S=W,w=_e,C=Ve,F=ye,Z=ve;return f(),h("div",Le,[n("div",Oe,[n("div",qe,[n("h1",Ke,m(l.$t("settings.title")),1),e($,{type:"primary",onClick:K,loading:b.value},{default:t(()=>[e(c,{class:"mr-1"},{default:t(()=>[e(o(ie))]),_:1}),E(" "+m(l.$t("settings.save")),1)]),_:1},8,["loading"])]),we((f(),h("div",Ze,[e(F,{modelValue:T.value,"onUpdate:modelValue":s[17]||(s[17]=u=>T.value=u),class:"demo-tabs"},{default:t(()=>[e(w,{name:"system"},{label:t(()=>[n("span",Ge,[e(c,null,{default:t(()=>[e(o(ge))]),_:1}),n("span",null,m(l.$t("settings.systemTab")),1)])]),default:t(()=>[n("div",He,[e(S,{model:o(a),"label-position":"left","label-width":"260px"},{default:t(()=>[n("div",Je,[e(i,{label:l.$t("settings.host")},{default:t(()=>[e(d,{modelValue:o(a).system.host,"onUpdate:modelValue":s[0]||(s[0]=u=>o(a).system.host=u),class:"w-[200px]"},null,8,["modelValue"])]),_:1},8,["label"]),e(i,{label:l.$t("settings.port")},{default:t(()=>[e(v,{modelValue:o(a).system.port,"onUpdate:modelValue":s[1]||(s[1]=u=>o(a).system.port=u),min:1,max:65535,class:"w-[200px]"},null,8,["modelValue"])]),_:1},8,["label"])]),n("div",Qe,[n("span",We,m(l.$t("settings.appearance")),1),s[18]||(s[18]=n("div",{class:"h-px bg-gray-200 dark:bg-gray-700 flex-1"},null,-1))]),e(i,{label:l.$t("settings.theme")},{default:t(()=>[e(x,{modelValue:o(a).system.theme,"onUpdate:modelValue":s[2]||(s[2]=u=>o(a).system.theme=u),class:"w-[200px]"},{default:t(()=>[e(g,{label:l.$t("settings.themeLight"),value:"light"},{default:t(()=>[n("span",Xe,[e(c,null,{default:t(()=>[e(o(de))]),_:1}),n("span",null,m(l.$t("settings.themeLight")),1)])]),_:1},8,["label"]),e(g,{label:l.$t("settings.themeDark"),value:"dark"},{default:t(()=>[n("span",Ye,[e(c,null,{default:t(()=>[e(o(re))]),_:1}),n("span",null,m(l.$t("settings.themeDark")),1)])]),_:1},8,["label"]),e(g,{label:l.$t("settings.themeSystem"),value:"system"},{default:t(()=>[n("span",el,[e(c,null,{default:t(()=>[e(o(me))]),_:1}),n("span",null,m(l.$t("settings.themeSystem")),1)])]),_:1},8,["label"])]),_:1},8,["modelValue"])]),_:1},8,["label"]),e(i,{label:l.$t("settings.language")},{default:t(()=>[e(x,{modelValue:o(a).system.language,"onUpdate:modelValue":s[3]||(s[3]=u=>o(a).system.language=u),class:"w-[200px]"},{default:t(()=>[e(g,{label:l.$t("settings.langEn"),value:"en"},null,8,["label"]),e(g,{label:l.$t("settings.langZh"),value:"zh"},null,8,["label"])]),_:1},8,["modelValue"])]),_:1},8,["label"])]),_:1},8,["model"])])]),_:1}),e(w,{name:"logging"},{label:t(()=>[n("span",ll,[e(c,null,{default:t(()=>[e(o(pe))]),_:1}),n("span",null,m(l.$t("settings.logging")),1)])]),default:t(()=>[n("div",tl,[o(a).system.logging?(f(),A(S,{key:0,model:o(a).system.logging,"label-position":"left","label-width":"260px"},{default:t(()=>[e(i,{label:l.$t("settings.logLevel")},{default:t(()=>[e(x,{modelValue:o(a).system.logging.level,"onUpdate:modelValue":s[4]||(s[4]=u=>o(a).system.logging.level=u),class:"w-full md:w-64"},{default:t(()=>[e(g,{label:"DEBUG",value:"debug"}),e(g,{label:"INFO",value:"info"}),e(g,{label:"WARN",value:"warn"}),e(g,{label:"ERROR",value:"error"})]),_:1},8,["modelValue"])]),_:1},8,["label"]),e(i,{label:l.$t("settings.maxAge")},{default:t(()=>[e(v,{modelValue:N.value,"onUpdate:modelValue":s[5]||(s[5]=u=>N.value=u),min:1,class:"w-[150px]"},null,8,["modelValue"])]),_:1},8,["label"]),n("div",sl,[n("span",al,m(l.$t("settings.debugOptions")),1),s[19]||(s[19]=n("div",{class:"h-px bg-gray-200 dark:bg-gray-700 flex-1"},null,-1))]),o(a).system.logging.level==="debug"||o(a).isDevMode?(f(),h(M,{key:0},[e(i,{label:l.$t("settings.jsonPretty")},{default:t(()=>[e(C,{modelValue:o(a).system.logging.jsonPretty,"onUpdate:modelValue":s[6]||(s[6]=u=>o(a).system.logging.jsonPretty=u)},null,8,["modelValue"])]),_:1},8,["label"]),e(i,{label:l.$t("settings.mcpCommDebug")},{default:t(()=>[e(C,{modelValue:o(a).system.logging.mcpCommDebug,"onUpdate:modelValue":s[7]||(s[7]=u=>o(a).system.logging.mcpCommDebug=u)},null,8,["modelValue"])]),_:1},8,["label"]),e(i,{label:l.$t("settings.apiDebug")},{default:t(()=>[e(C,{modelValue:o(a).system.logging.apiDebug,"onUpdate:modelValue":s[8]||(s[8]=u=>o(a).system.logging.apiDebug=u)},null,8,["modelValue"])]),_:1},8,["label"])],64)):j("",!0)]),_:1},8,["model"])):j("",!0)])]),_:1}),e(w,{name:"security"},{label:t(()=>[n("span",nl,[e(c,null,{default:t(()=>[e(o(ce))]),_:1}),n("span",null,m(l.$t("settings.security")),1)])]),default:t(()=>[n("div",ol,[o(a).security?(f(),A(S,{key:0,model:o(a).security,"label-position":"left","label-width":"260px"},{default:t(()=>[e(i,{label:l.$t("settings.allowedNetworks")},{default:t(()=>[e(x,{modelValue:o(a).security.allowedNetworks,"onUpdate:modelValue":s[9]||(s[9]=u=>o(a).security.allowedNetworks=u),multiple:"",filterable:"","allow-create":"","default-first-option":"","reserve-keyword":!1,placeholder:"Enter IP CIDR",class:"w-full"},{default:t(()=>[(f(!0),h(M,null,q(o(a).security.allowedNetworks,u=>(f(),A(g,{key:u,label:u,value:u},null,8,["label","value"]))),128))]),_:1},8,["modelValue"]),n("div",ul,m(l.$t("settings.allowedNetworksHint")),1)]),_:1},8,["label"]),n("div",il,[n("div",dl,[n("span",rl,m(l.$t("settings.maxConcurrentConnections")),1),e(v,{modelValue:o(a).security.maxConcurrentConnections,"onUpdate:modelValue":s[10]||(s[10]=u=>o(a).security.maxConcurrentConnections=u),min:1,max:1e3,style:{width:"128px","flex-shrink":"0"}},null,8,["modelValue"])]),n("div",ml,[n("span",gl,m(l.$t("settings.maxConnections")),1),e(v,{modelValue:o(a).security.maxConnections,"onUpdate:modelValue":s[11]||(s[11]=u=>o(a).security.maxConnections=u),min:1,max:1e3,style:{width:"128px","flex-shrink":"0"}},null,8,["modelValue"])]),n("div",pl,[n("span",cl,m(l.$t("settings.connectionTimeout")),1),n("div",fl,[e(v,{modelValue:p.value,"onUpdate:modelValue":s[12]||(s[12]=u=>p.value=u),min:1,step:1,style:{width:"128px","flex-shrink":"0"}},null,8,["modelValue"]),e(x,{modelValue:_.value,"onUpdate:modelValue":s[13]||(s[13]=u=>_.value=u),style:{width:"128px","flex-shrink":"0"}},{default:t(()=>[e(g,{label:l.$t("settings.timeUnits.seconds"),value:"seconds"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.minutes"),value:"minutes"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.hours"),value:"hours"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.days"),value:"days"},null,8,["label"])]),_:1},8,["modelValue"])])]),n("div",vl,[n("span",yl,m(l.$t("settings.idleConnectionTimeout")),1),n("div",_l,[e(v,{modelValue:P.value,"onUpdate:modelValue":s[14]||(s[14]=u=>P.value=u),min:1,step:1,style:{width:"128px","flex-shrink":"0"}},null,8,["modelValue"]),e(x,{modelValue:D.value,"onUpdate:modelValue":s[15]||(s[15]=u=>D.value=u),style:{width:"128px","flex-shrink":"0"}},{default:t(()=>[e(g,{label:l.$t("settings.timeUnits.seconds"),value:"seconds"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.minutes"),value:"minutes"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.hours"),value:"hours"},null,8,["label"]),e(g,{label:l.$t("settings.timeUnits.days"),value:"days"},null,8,["label"])]),_:1},8,["modelValue"])])])])]),_:1},8,["model"])):j("",!0)])]),_:1}),e(w,{name:"tags"},{label:t(()=>[n("span",bl,[e(c,null,{default:t(()=>[e(o(fe))]),_:1}),n("span",null,m(l.$t("settings.tagsTab")),1)])]),default:t(()=>[n("div",Vl,[e(Fe,{modelValue:o(a).tagDefinitions,"onUpdate:modelValue":s[16]||(s[16]=u=>o(a).tagDefinitions=u)},null,8,["modelValue"])])]),_:1})]),_:1},8,["modelValue"])])),[[Z,o(B)]])])])}}});export{Al as default};