@alepha/devtools 0.10.3 → 0.10.4

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/dist/index.d.ts CHANGED
@@ -55,10 +55,6 @@ type DevLogEntry = Static<typeof devLogEntrySchema> & {
55
55
  //#endregion
56
56
  //#region src/schemas/DevMetadata.d.ts
57
57
  declare const devMetadataSchema: typebox0.TObject<{
58
- logs: typebox0.TArray<typebox0.TObject<{
59
- formatted: typebox0.TString;
60
- entry: typebox0.TAny;
61
- }>>;
62
58
  actions: typebox0.TArray<typebox0.TObject<{
63
59
  name: typebox0.TString;
64
60
  group: typebox0.TString;
@@ -236,17 +232,13 @@ type DevTopicMetadata = Static<typeof devTopicMetadataSchema>;
236
232
  declare class DevCollectorProvider {
237
233
  protected readonly alepha: Alepha;
238
234
  protected readonly logs: DevLogEntry[];
239
- protected readonly maxLogs = 1000;
235
+ protected readonly maxLogs = 10000;
240
236
  protected readonly onLog: _alepha_core1.HookDescriptor<"log">;
241
237
  protected readonly uiRoute: _alepha_server0.RouteDescriptor<{
242
238
  response: typebox0.TString;
243
239
  }>;
244
240
  protected readonly metadataRoute: _alepha_server0.RouteDescriptor<{
245
241
  response: typebox0.TObject<{
246
- logs: typebox0.TArray<typebox0.TObject<{
247
- formatted: typebox0.TString;
248
- entry: typebox0.TAny;
249
- }>>;
250
242
  actions: typebox0.TArray<typebox0.TObject<{
251
243
  name: typebox0.TString;
252
244
  group: typebox0.TString;
@@ -339,6 +331,12 @@ declare class DevCollectorProvider {
339
331
  }>>;
340
332
  }>;
341
333
  }>;
334
+ protected readonly logsRoute: _alepha_server0.RouteDescriptor<{
335
+ response: typebox0.TArray<typebox0.TObject<{
336
+ formatted: typebox0.TString;
337
+ entry: typebox0.TAny;
338
+ }>>;
339
+ }>;
342
340
  getLogs(): DevLogEntry[];
343
341
  getActions(): DevActionMetadata[];
344
342
  getQueues(): DevQueueMetadata[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/schemas/DevActionMetadata.ts","../src/schemas/DevBucketMetadata.ts","../src/schemas/DevCacheMetadata.ts","../src/schemas/DevLogEntry.ts","../src/schemas/DevMetadata.ts","../src/schemas/DevModuleMetadata.ts","../src/schemas/DevPageMetadata.ts","../src/schemas/DevProviderMetadata.ts","../src/schemas/DevQueueMetadata.ts","../src/schemas/DevRealmMetadata.ts","../src/schemas/DevSchedulerMetadata.ts","../src/schemas/DevTopicMetadata.ts","../src/DevCollectorProvider.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/schemas/DevActionMetadata.ts","../src/schemas/DevBucketMetadata.ts","../src/schemas/DevCacheMetadata.ts","../src/schemas/DevLogEntry.ts","../src/schemas/DevMetadata.ts","../src/schemas/DevModuleMetadata.ts","../src/schemas/DevPageMetadata.ts","../src/schemas/DevProviderMetadata.ts","../src/schemas/DevQueueMetadata.ts","../src/schemas/DevRealmMetadata.ts","../src/schemas/DevSchedulerMetadata.ts","../src/schemas/DevTopicMetadata.ts","../src/DevCollectorProvider.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1329,14 +1329,14 @@ const ui = `<!DOCTYPE html>
1329
1329
  //#endregion
1330
1330
  //#region src/schemas/DevActionMetadata.ts
1331
1331
  const devActionMetadataSchema = t.object({
1332
- name: t.string(),
1333
- group: t.string(),
1334
- method: t.string(),
1335
- path: t.string(),
1336
- prefix: t.string(),
1337
- fullPath: t.string(),
1338
- description: t.optional(t.string()),
1339
- summary: t.optional(t.string()),
1332
+ name: t.text(),
1333
+ group: t.text(),
1334
+ method: t.text(),
1335
+ path: t.text(),
1336
+ prefix: t.text(),
1337
+ fullPath: t.text(),
1338
+ description: t.optional(t.text()),
1339
+ summary: t.optional(t.text()),
1340
1340
  disabled: t.optional(t.boolean()),
1341
1341
  secure: t.optional(t.boolean()),
1342
1342
  hide: t.optional(t.boolean()),
@@ -1344,48 +1344,41 @@ const devActionMetadataSchema = t.object({
1344
1344
  params: t.optional(t.any()),
1345
1345
  query: t.optional(t.any()),
1346
1346
  response: t.optional(t.any()),
1347
- bodyContentType: t.optional(t.string())
1347
+ bodyContentType: t.optional(t.text())
1348
1348
  });
1349
1349
 
1350
1350
  //#endregion
1351
1351
  //#region src/schemas/DevBucketMetadata.ts
1352
1352
  const devBucketMetadataSchema = t.object({
1353
- name: t.string(),
1354
- description: t.optional(t.string()),
1355
- mimeTypes: t.optional(t.array(t.string())),
1353
+ name: t.text(),
1354
+ description: t.optional(t.text()),
1355
+ mimeTypes: t.optional(t.array(t.text())),
1356
1356
  maxSize: t.optional(t.number()),
1357
- provider: t.string()
1357
+ provider: t.text()
1358
1358
  });
1359
1359
 
1360
1360
  //#endregion
1361
1361
  //#region src/schemas/DevCacheMetadata.ts
1362
1362
  const devCacheMetadataSchema = t.object({
1363
- name: t.string(),
1363
+ name: t.text(),
1364
1364
  ttl: t.optional(t.any()),
1365
1365
  disabled: t.optional(t.boolean()),
1366
- provider: t.string()
1367
- });
1368
-
1369
- //#endregion
1370
- //#region src/schemas/DevLogEntry.ts
1371
- const devLogEntrySchema = t.object({
1372
- formatted: t.string(),
1373
- entry: t.any()
1366
+ provider: t.text()
1374
1367
  });
1375
1368
 
1376
1369
  //#endregion
1377
1370
  //#region src/schemas/DevModuleMetadata.ts
1378
1371
  const devModuleMetadataSchema = t.object({
1379
- name: t.string(),
1380
- providers: t.array(t.string())
1372
+ name: t.text(),
1373
+ providers: t.array(t.text())
1381
1374
  });
1382
1375
 
1383
1376
  //#endregion
1384
1377
  //#region src/schemas/DevPageMetadata.ts
1385
1378
  const devPageMetadataSchema = t.object({
1386
- name: t.string(),
1387
- description: t.optional(t.string()),
1388
- path: t.optional(t.string()),
1379
+ name: t.text(),
1380
+ description: t.optional(t.text()),
1381
+ path: t.optional(t.text()),
1389
1382
  params: t.optional(t.any()),
1390
1383
  query: t.optional(t.any()),
1391
1384
  hasComponent: t.boolean(),
@@ -1403,26 +1396,26 @@ const devPageMetadataSchema = t.object({
1403
1396
  //#endregion
1404
1397
  //#region src/schemas/DevProviderMetadata.ts
1405
1398
  const devProviderMetadataSchema = t.object({
1406
- name: t.string(),
1407
- module: t.optional(t.string()),
1408
- dependencies: t.array(t.string()),
1409
- aliases: t.optional(t.array(t.string()))
1399
+ name: t.text(),
1400
+ module: t.optional(t.text()),
1401
+ dependencies: t.array(t.text()),
1402
+ aliases: t.optional(t.array(t.text()))
1410
1403
  });
1411
1404
 
1412
1405
  //#endregion
1413
1406
  //#region src/schemas/DevQueueMetadata.ts
1414
1407
  const devQueueMetadataSchema = t.object({
1415
- name: t.string(),
1416
- description: t.optional(t.string()),
1408
+ name: t.text(),
1409
+ description: t.optional(t.text()),
1417
1410
  schema: t.optional(t.any()),
1418
- provider: t.string()
1411
+ provider: t.text()
1419
1412
  });
1420
1413
 
1421
1414
  //#endregion
1422
1415
  //#region src/schemas/DevRealmMetadata.ts
1423
1416
  const devRealmMetadataSchema = t.object({
1424
- name: t.string(),
1425
- description: t.optional(t.string()),
1417
+ name: t.text(),
1418
+ description: t.optional(t.text()),
1426
1419
  roles: t.optional(t.array(t.any())),
1427
1420
  type: t.enum(["internal", "external"]),
1428
1421
  settings: t.optional(t.object({
@@ -1437,9 +1430,9 @@ const devRealmMetadataSchema = t.object({
1437
1430
  //#endregion
1438
1431
  //#region src/schemas/DevSchedulerMetadata.ts
1439
1432
  const devSchedulerMetadataSchema = t.object({
1440
- name: t.string(),
1441
- description: t.optional(t.string()),
1442
- cron: t.optional(t.string()),
1433
+ name: t.text(),
1434
+ description: t.optional(t.text()),
1435
+ cron: t.optional(t.text()),
1443
1436
  interval: t.optional(t.any()),
1444
1437
  lock: t.optional(t.boolean())
1445
1438
  });
@@ -1447,16 +1440,15 @@ const devSchedulerMetadataSchema = t.object({
1447
1440
  //#endregion
1448
1441
  //#region src/schemas/DevTopicMetadata.ts
1449
1442
  const devTopicMetadataSchema = t.object({
1450
- name: t.string(),
1451
- description: t.optional(t.string()),
1443
+ name: t.text(),
1444
+ description: t.optional(t.text()),
1452
1445
  schema: t.optional(t.any()),
1453
- provider: t.string()
1446
+ provider: t.text()
1454
1447
  });
1455
1448
 
1456
1449
  //#endregion
1457
1450
  //#region src/schemas/DevMetadata.ts
1458
1451
  const devMetadataSchema = t.object({
1459
- logs: t.array(devLogEntrySchema),
1460
1452
  actions: t.array(devActionMetadataSchema),
1461
1453
  queues: t.array(devQueueMetadataSchema),
1462
1454
  schedulers: t.array(devSchedulerMetadataSchema),
@@ -1474,7 +1466,7 @@ const devMetadataSchema = t.object({
1474
1466
  var DevCollectorProvider = class {
1475
1467
  alepha = $inject(Alepha);
1476
1468
  logs = [];
1477
- maxLogs = 1e3;
1469
+ maxLogs = 1e4;
1478
1470
  onLog = $hook({
1479
1471
  on: "log",
1480
1472
  handler: (ev) => {
@@ -1488,7 +1480,7 @@ var DevCollectorProvider = class {
1488
1480
  uiRoute = $route({
1489
1481
  method: "GET",
1490
1482
  path: "/devtools",
1491
- schema: { response: t.string() },
1483
+ schema: { response: t.text() },
1492
1484
  handler: () => {
1493
1485
  return ui;
1494
1486
  }
@@ -1501,6 +1493,17 @@ var DevCollectorProvider = class {
1501
1493
  return this.getMetadata();
1502
1494
  }
1503
1495
  });
1496
+ logsRoute = $route({
1497
+ method: "GET",
1498
+ path: "/devtools/logs",
1499
+ schema: { response: t.array(t.object({
1500
+ formatted: t.text(),
1501
+ entry: t.any()
1502
+ })) },
1503
+ handler: () => {
1504
+ return this.getLogs();
1505
+ }
1506
+ });
1504
1507
  getLogs() {
1505
1508
  return this.logs;
1506
1509
  }
@@ -1635,7 +1638,6 @@ var DevCollectorProvider = class {
1635
1638
  }
1636
1639
  getMetadata() {
1637
1640
  return {
1638
- logs: this.getLogs(),
1639
1641
  actions: this.getActions(),
1640
1642
  queues: this.getQueues(),
1641
1643
  schedulers: this.getSchedulers(),
@@ -1655,6 +1657,13 @@ var DevCollectorProvider = class {
1655
1657
  }
1656
1658
  };
1657
1659
 
1660
+ //#endregion
1661
+ //#region src/schemas/DevLogEntry.ts
1662
+ const devLogEntrySchema = t.object({
1663
+ formatted: t.text(),
1664
+ entry: t.any()
1665
+ });
1666
+
1658
1667
  //#endregion
1659
1668
  //#region src/index.ts
1660
1669
  /**
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/constants/ui.ts","../src/schemas/DevActionMetadata.ts","../src/schemas/DevBucketMetadata.ts","../src/schemas/DevCacheMetadata.ts","../src/schemas/DevLogEntry.ts","../src/schemas/DevModuleMetadata.ts","../src/schemas/DevPageMetadata.ts","../src/schemas/DevProviderMetadata.ts","../src/schemas/DevQueueMetadata.ts","../src/schemas/DevRealmMetadata.ts","../src/schemas/DevSchedulerMetadata.ts","../src/schemas/DevTopicMetadata.ts","../src/schemas/DevMetadata.ts","../src/DevCollectorProvider.ts","../src/index.ts"],"sourcesContent":["// language=HTML\nexport const ui = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n\t\t<title>Alepha DevTools</title>\n\t\t<style>\n\t\t\t:root {\n\t\t\t\t--primary: #3b82f6;\n\t\t\t\t--primary-dark: #2563eb;\n\t\t\t\t--success: #10b981;\n\t\t\t\t--warning: #f59e0b;\n\t\t\t\t--danger: #ef4444;\n\t\t\t\t--bg-primary: #0f172a;\n\t\t\t\t--bg-secondary: #1e293b;\n\t\t\t\t--bg-tertiary: #334155;\n\t\t\t\t--text-primary: #f8fafc;\n\t\t\t\t--text-secondary: #cbd5e1;\n\t\t\t\t--text-muted: #94a3b8;\n\t\t\t\t--border: #334155;\n\t\t\t\t--code-bg: #1e293b;\n\t\t\t\t--shadow: rgba(0, 0, 0, 0.3);\n\t\t\t}\n\n\t\t\t* {\n\t\t\t\tbox-sizing: border-box;\n\t\t\t\tmargin: 0;\n\t\t\t\tpadding: 0;\n\t\t\t}\n\n\t\t\tbody {\n\t\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n\t\t\t\tbackground: linear-gradient(135deg, var(--bg-primary) 0%, #0c1222 100%);\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t\tmin-height: 100vh;\n\t\t\t}\n\n\t\t\t/* Header */\n\t\t\t.header {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder-bottom: 1px solid var(--border);\n\t\t\t\tpadding: 1.5rem 2rem;\n\t\t\t\tposition: sticky;\n\t\t\t\ttop: 0;\n\t\t\t\tz-index: 1000;\n\t\t\t\tbox-shadow: 0 4px 6px var(--shadow);\n\t\t\t}\n\n\t\t\t.header-content {\n\t\t\t\tmax-width: 1600px;\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: space-between;\n\t\t\t\talign-items: center;\n\t\t\t}\n\n\t\t\t.logo {\n\t\t\t\tfont-size: 1.5rem;\n\t\t\t\tfont-weight: 700;\n\t\t\t\tbackground: linear-gradient(135deg, var(--primary), #8b5cf6);\n\t\t\t\t-webkit-background-clip: text;\n\t\t\t\t-webkit-text-fill-color: transparent;\n\t\t\t\tbackground-clip: text;\n\t\t\t}\n\n\t\t\t.header-stats {\n\t\t\t\tdisplay: flex;\n\t\t\t\tgap: 2rem;\n\t\t\t}\n\n\t\t\t.stat {\n\t\t\t\ttext-align: center;\n\t\t\t}\n\n\t\t\t.stat-value {\n\t\t\t\tfont-size: 1.5rem;\n\t\t\t\tfont-weight: 700;\n\t\t\t\tcolor: var(--primary);\n\t\t\t}\n\n\t\t\t.stat-label {\n\t\t\t\tfont-size: 0.75rem;\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tletter-spacing: 0.05em;\n\t\t\t}\n\n\t\t\t/* Navigation */\n\t\t\t.nav {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder-bottom: 1px solid var(--border);\n\t\t\t\tposition: sticky;\n\t\t\t\ttop: 73px;\n\t\t\t\tz-index: 999;\n\t\t\t}\n\n\t\t\t.nav-container {\n\t\t\t\tmax-width: 1600px;\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tpadding: 0 2rem;\n\t\t\t\tdisplay: flex;\n\t\t\t\tgap: 0.5rem;\n\t\t\t\toverflow-x: auto;\n\t\t\t}\n\n\t\t\t.nav-tab {\n\t\t\t\tpadding: 1rem 1.5rem;\n\t\t\t\tbackground: transparent;\n\t\t\t\tborder: none;\n\t\t\t\tcolor: var(--text-secondary);\n\t\t\t\tcursor: pointer;\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tfont-weight: 600;\n\t\t\t\tborder-bottom: 2px solid transparent;\n\t\t\t\ttransition: all 0.2s;\n\t\t\t\twhite-space: nowrap;\n\t\t\t}\n\n\t\t\t.nav-tab:hover {\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t\tbackground: rgba(255, 255, 255, 0.05);\n\t\t\t}\n\n\t\t\t.nav-tab.active {\n\t\t\t\tcolor: var(--primary);\n\t\t\t\tborder-bottom-color: var(--primary);\n\t\t\t}\n\n\t\t\t/* Main Container */\n\t\t\t.container {\n\t\t\t\tmax-width: 1600px;\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tpadding: 2rem;\n\t\t\t}\n\n\t\t\t.tab-content {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\n\t\t\t.tab-content.active {\n\t\t\t\tdisplay: block;\n\t\t\t\tanimation: fadeIn 0.3s;\n\t\t\t}\n\n\t\t\t@keyframes fadeIn {\n\t\t\t\tfrom { opacity: 0; transform: translateY(10px); }\n\t\t\t\tto { opacity: 1; transform: translateY(0); }\n\t\t\t}\n\n\t\t\t/* Search and Filters */\n\t\t\t.controls {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tpadding: 1.5rem;\n\t\t\t\tmargin-bottom: 1.5rem;\n\t\t\t}\n\n\t\t\t.search-box {\n\t\t\t\tdisplay: flex;\n\t\t\t\tgap: 1rem;\n\t\t\t\tmargin-bottom: 1rem;\n\t\t\t}\n\n\t\t\t.search-input {\n\t\t\t\tflex: 1;\n\t\t\t\tpadding: 0.75rem 1rem;\n\t\t\t\tbackground: var(--bg-tertiary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 6px;\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t}\n\n\t\t\t.search-input:focus {\n\t\t\t\toutline: none;\n\t\t\t\tborder-color: var(--primary);\n\t\t\t\tbox-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n\t\t\t}\n\n\t\t\t.filter-buttons {\n\t\t\t\tdisplay: flex;\n\t\t\t\tgap: 0.5rem;\n\t\t\t\tflex-wrap: wrap;\n\t\t\t}\n\n\t\t\t.filter-btn {\n\t\t\t\tpadding: 0.5rem 1rem;\n\t\t\t\tbackground: var(--bg-tertiary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 6px;\n\t\t\t\tcolor: var(--text-secondary);\n\t\t\t\tfont-size: 0.75rem;\n\t\t\t\tcursor: pointer;\n\t\t\t\ttransition: all 0.2s;\n\t\t\t}\n\n\t\t\t.filter-btn:hover {\n\t\t\t\tbackground: var(--bg-primary);\n\t\t\t\tborder-color: var(--primary);\n\t\t\t}\n\n\t\t\t.filter-btn.active {\n\t\t\t\tbackground: var(--primary);\n\t\t\t\tcolor: white;\n\t\t\t\tborder-color: var(--primary);\n\t\t\t}\n\n\t\t\t/* Cards */\n\t\t\t.card-grid {\n\t\t\t\tdisplay: grid;\n\t\t\t\tgrid-template-columns: repeat(auto-fill, minmax(350px, 1fr));\n\t\t\t\tgap: 1.5rem;\n\t\t\t\tmargin-bottom: 2rem;\n\t\t\t}\n\n\t\t\t.card {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tpadding: 1.5rem;\n\t\t\t\ttransition: all 0.2s;\n\t\t\t\tcursor: pointer;\n\t\t\t}\n\n\t\t\t.card:hover {\n\t\t\t\tborder-color: var(--primary);\n\t\t\t\tbox-shadow: 0 4px 12px var(--shadow);\n\t\t\t\ttransform: translateY(-2px);\n\t\t\t}\n\n\t\t\t.card-header {\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: space-between;\n\t\t\t\talign-items: start;\n\t\t\t\tmargin-bottom: 1rem;\n\t\t\t}\n\n\t\t\t.card-title {\n\t\t\t\tfont-size: 1.125rem;\n\t\t\t\tfont-weight: 600;\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t\tword-break: break-word;\n\t\t\t}\n\n\t\t\t.badge {\n\t\t\t\tpadding: 0.25rem 0.75rem;\n\t\t\t\tborder-radius: 12px;\n\t\t\t\tfont-size: 0.75rem;\n\t\t\t\tfont-weight: 600;\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\twhite-space: nowrap;\n\t\t\t}\n\n\t\t\t.badge-get { background: #10b981; color: white; }\n\t\t\t.badge-post { background: #3b82f6; color: white; }\n\t\t\t.badge-put { background: #f59e0b; color: white; }\n\t\t\t.badge-delete { background: #ef4444; color: white; }\n\t\t\t.badge-patch { background: #8b5cf6; color: white; }\n\t\t\t.badge-secure { background: #dc2626; color: white; }\n\t\t\t.badge-internal { background: #3b82f6; color: white; }\n\t\t\t.badge-external { background: #8b5cf6; color: white; }\n\n\t\t\t.card-description {\n\t\t\t\tcolor: var(--text-secondary);\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tmargin-bottom: 1rem;\n\t\t\t\tline-height: 1.5;\n\t\t\t}\n\n\t\t\t.card-meta {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-wrap: wrap;\n\t\t\t\tgap: 1rem;\n\t\t\t\tfont-size: 0.75rem;\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t}\n\n\t\t\t.card-meta-item {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tgap: 0.5rem;\n\t\t\t}\n\n\t\t\t.card-path {\n\t\t\t\tbackground: var(--code-bg);\n\t\t\t\tpadding: 0.5rem;\n\t\t\t\tborder-radius: 4px;\n\t\t\t\tfont-family: 'Courier New', monospace;\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tword-break: break-all;\n\t\t\t\tmargin-top: 0.5rem;\n\t\t\t}\n\n\t\t\t/* Table */\n\t\t\t.table-container {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\toverflow: hidden;\n\t\t\t}\n\n\t\t\ttable {\n\t\t\t\twidth: 100%;\n\t\t\t\tborder-collapse: collapse;\n\t\t\t}\n\n\t\t\tthead {\n\t\t\t\tbackground: var(--bg-tertiary);\n\t\t\t}\n\n\t\t\tth {\n\t\t\t\tpadding: 1rem;\n\t\t\t\ttext-align: left;\n\t\t\t\tfont-weight: 600;\n\t\t\t\tfont-size: 0.75rem;\n\t\t\t\tcolor: var(--text-secondary);\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tletter-spacing: 0.05em;\n\t\t\t\tborder-bottom: 1px solid var(--border);\n\t\t\t}\n\n\t\t\ttd {\n\t\t\t\tpadding: 1rem;\n\t\t\t\tborder-bottom: 1px solid var(--border);\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t}\n\n\t\t\ttbody tr {\n\t\t\t\ttransition: background 0.2s;\n\t\t\t}\n\n\t\t\ttbody tr:hover {\n\t\t\t\tbackground: var(--bg-tertiary);\n\t\t\t}\n\n\t\t\t/* Code Block */\n\t\t\t.code-block {\n\t\t\t\tbackground: var(--code-bg);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tpadding: 1rem;\n\t\t\t\toverflow-x: auto;\n\t\t\t\tfont-family: 'Courier New', monospace;\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tline-height: 1.6;\n\t\t\t}\n\n\t\t\t/* Logs */\n\t\t\t.log-container {\n\t\t\t\tbackground: var(--code-bg);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tmax-height: 600px;\n\t\t\t\toverflow-y: auto;\n\t\t\t}\n\n\t\t\t.log-entry {\n\t\t\t\tpadding: 0.75rem 1rem;\n\t\t\t\tborder-bottom: 1px solid var(--border);\n\t\t\t\tfont-family: 'Courier New', monospace;\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\twhite-space: pre-wrap;\n\t\t\t\tword-break: break-word;\n\t\t\t}\n\n\t\t\t.log-entry:last-child {\n\t\t\t\tborder-bottom: none;\n\t\t\t}\n\n\t\t\t.log-error { background: rgba(239, 68, 68, 0.1); color: #fca5a5; }\n\t\t\t.log-warn { background: rgba(245, 158, 11, 0.1); color: #fcd34d; }\n\t\t\t.log-info { background: rgba(59, 130, 246, 0.1); color: #93c5fd; }\n\t\t\t.log-debug { background: rgba(156, 163, 175, 0.1); color: #d1d5db; }\n\n\t\t\t/* Empty State */\n\t\t\t.empty-state {\n\t\t\t\ttext-align: center;\n\t\t\t\tpadding: 4rem 2rem;\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t}\n\n\t\t\t.empty-icon {\n\t\t\t\tfont-size: 4rem;\n\t\t\t\tmargin-bottom: 1rem;\n\t\t\t\topacity: 0.3;\n\t\t\t}\n\n\t\t\t/* Detail View */\n\t\t\t.detail-section {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tpadding: 1.5rem;\n\t\t\t\tmargin-bottom: 1.5rem;\n\t\t\t}\n\n\t\t\t.detail-title {\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tfont-weight: 600;\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tletter-spacing: 0.05em;\n\t\t\t\tmargin-bottom: 1rem;\n\t\t\t}\n\n\t\t\t.property-list {\n\t\t\t\tdisplay: grid;\n\t\t\t\tgap: 0.75rem;\n\t\t\t}\n\n\t\t\t.property {\n\t\t\t\tdisplay: grid;\n\t\t\t\tgrid-template-columns: 150px 1fr;\n\t\t\t\tgap: 1rem;\n\t\t\t}\n\n\t\t\t.property-key {\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t}\n\n\t\t\t.property-value {\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tword-break: break-word;\n\t\t\t}\n\n\t\t\t.property-value code {\n\t\t\t\tbackground: var(--code-bg);\n\t\t\t\tpadding: 0.125rem 0.5rem;\n\t\t\t\tborder-radius: 4px;\n\t\t\t\tfont-family: 'Courier New', monospace;\n\t\t\t}\n\n\t\t\t/* Loading */\n\t\t\t.loading {\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: center;\n\t\t\t\talign-items: center;\n\t\t\t\tpadding: 4rem;\n\t\t\t}\n\n\t\t\t.spinner {\n\t\t\t\twidth: 40px;\n\t\t\t\theight: 40px;\n\t\t\t\tborder: 3px solid var(--border);\n\t\t\t\tborder-top-color: var(--primary);\n\t\t\t\tborder-radius: 50%;\n\t\t\t\tanimation: spin 0.8s linear infinite;\n\t\t\t}\n\n\t\t\t@keyframes spin {\n\t\t\t\tto { transform: rotate(360deg); }\n\t\t\t}\n\n\t\t\t/* Utility */\n\t\t\t.hidden {\n\t\t\t\tdisplay: none !important;\n\t\t\t}\n\n\t\t\t.text-muted {\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t}\n\n\t\t\t.text-code {\n\t\t\t\tfont-family: 'Courier New', monospace;\n\t\t\t\tbackground: var(--code-bg);\n\t\t\t\tpadding: 0.125rem 0.5rem;\n\t\t\t\tborder-radius: 4px;\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t}\n\n\t\t\t/* Scrollbar */\n\t\t\t::-webkit-scrollbar {\n\t\t\t\twidth: 8px;\n\t\t\t\theight: 8px;\n\t\t\t}\n\n\t\t\t::-webkit-scrollbar-track {\n\t\t\t\tbackground: var(--bg-primary);\n\t\t\t}\n\n\t\t\t::-webkit-scrollbar-thumb {\n\t\t\t\tbackground: var(--border);\n\t\t\t\tborder-radius: 4px;\n\t\t\t}\n\n\t\t\t::-webkit-scrollbar-thumb:hover {\n\t\t\t\tbackground: var(--text-muted);\n\t\t\t}\n\n\t\t\t/* Responsive */\n\t\t\t@media (max-width: 768px) {\n\t\t\t\t.header-stats {\n\t\t\t\t\tdisplay: none;\n\t\t\t\t}\n\n\t\t\t\t.card-grid {\n\t\t\t\t\tgrid-template-columns: 1fr;\n\t\t\t\t}\n\n\t\t\t\t.property {\n\t\t\t\t\tgrid-template-columns: 1fr;\n\t\t\t\t\tgap: 0.25rem;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n</head>\n<body>\n\t\t<!-- Header -->\n\t\t<div class=\"header\">\n\t\t\t<div class=\"header-content\">\n\t\t\t\t<div class=\"logo\">⚡ Alepha DevTools</div>\n\t\t\t\t<div class=\"header-stats\">\n\t\t\t\t\t<div class=\"stat\">\n\t\t\t\t\t\t<div class=\"stat-value\" id=\"stat-actions\">0</div>\n\t\t\t\t\t\t<div class=\"stat-label\">Actions</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"stat\">\n\t\t\t\t\t\t<div class=\"stat-value\" id=\"stat-pages\">0</div>\n\t\t\t\t\t\t<div class=\"stat-label\">Pages</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"stat\">\n\t\t\t\t\t\t<div class=\"stat-value\" id=\"stat-modules\">0</div>\n\t\t\t\t\t\t<div class=\"stat-label\">Modules</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"stat\">\n\t\t\t\t\t\t<div class=\"stat-value\" id=\"stat-providers\">0</div>\n\t\t\t\t\t\t<div class=\"stat-label\">Providers</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- Navigation -->\n\t\t<div class=\"nav\">\n\t\t\t<div class=\"nav-container\">\n\t\t\t\t<button class=\"nav-tab active\" data-tab=\"overview\">Overview</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"actions\">Actions</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"pages\">Pages</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"queues\">Queues</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"schedulers\">Schedulers</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"topics\">Topics</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"buckets\">Buckets</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"caches\">Caches</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"realms\">Realms</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"providers\">Providers</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"modules\">Modules</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"logs\">Logs</button>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- Main Container -->\n\t\t<div class=\"container\">\n\t\t\t<!-- Overview Tab -->\n\t\t\t<div class=\"tab-content active\" id=\"tab-overview\">\n\t\t\t\t<div class=\"detail-section\">\n\t\t\t\t\t<h2 class=\"detail-title\">System Overview</h2>\n\t\t\t\t\t<div id=\"overview-content\" class=\"loading\">\n\t\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Actions Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-actions\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-actions\" placeholder=\"Search actions by name, path, or group...\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"filter-buttons\" id=\"filter-actions-methods\"></div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"actions-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Pages Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-pages\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-pages\" placeholder=\"Search pages by name or path...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"pages-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Queues Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-queues\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-queues\" placeholder=\"Search queues...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"queues-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Schedulers Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-schedulers\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-schedulers\" placeholder=\"Search schedulers...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"schedulers-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Topics Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-topics\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-topics\" placeholder=\"Search topics...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"topics-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Buckets Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-buckets\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-buckets\" placeholder=\"Search buckets...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"buckets-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Caches Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-caches\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-caches\" placeholder=\"Search caches...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"caches-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Realms Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-realms\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-realms\" placeholder=\"Search realms...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"realms-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Providers Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-providers\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-providers\" placeholder=\"Search providers...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"providers-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Modules Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-modules\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-modules\" placeholder=\"Search modules...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"modules-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Logs Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-logs\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-logs\" placeholder=\"Search logs...\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"filter-buttons\">\n\t\t\t\t\t\t<button class=\"filter-btn active\" data-level=\"all\">All</button>\n\t\t\t\t\t\t<button class=\"filter-btn\" data-level=\"error\">Errors</button>\n\t\t\t\t\t\t<button class=\"filter-btn\" data-level=\"warn\">Warnings</button>\n\t\t\t\t\t\t<button class=\"filter-btn\" data-level=\"info\">Info</button>\n\t\t\t\t\t\t<button class=\"filter-btn\" data-level=\"debug\">Debug</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"logs-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<script>\n\t\t\tlet metadata = null;\n\t\t\tlet activeFilters = {\n\t\t\t\tactions: { methods: new Set() },\n\t\t\t\tlogs: { level: 'all' }\n\t\t\t};\n\n\t\t\t// Tab Navigation\n\t\t\tdocument.querySelectorAll('.nav-tab').forEach(tab => {\n\t\t\t\ttab.addEventListener('click', () => {\n\t\t\t\t\tconst tabName = tab.dataset.tab;\n\t\t\t\t\tdocument.querySelectorAll('.nav-tab').forEach(t => t.classList.remove('active'));\n\t\t\t\t\tdocument.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));\n\t\t\t\t\ttab.classList.add('active');\n\t\t\t\t\tdocument.getElementById(\\`tab-\\${tabName}\\`).classList.add('active');\n\t\t\t\t\trenderTab(tabName);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// Utility Functions\n\t\t\tfunction escapeHtml(text) {\n\t\t\t\tconst div = document.createElement('div');\n\t\t\t\tdiv.textContent = text;\n\t\t\t\treturn div.innerHTML;\n\t\t\t}\n\n\t\t\tfunction formatJson(obj) {\n\t\t\t\treturn JSON.stringify(obj, null, 2);\n\t\t\t}\n\n\t\t\tfunction getLogLevel(formatted) {\n\t\t\t\tconst lower = formatted.toLowerCase();\n\t\t\t\tif (lower.includes('error')) return 'error';\n\t\t\t\tif (lower.includes('warn')) return 'warn';\n\t\t\t\tif (lower.includes('info')) return 'info';\n\t\t\t\treturn 'debug';\n\t\t\t}\n\n\t\t\t// Search Functions\n\t\t\tfunction setupSearch(inputId, renderFn) {\n\t\t\t\tconst input = document.getElementById(inputId);\n\t\t\t\tif (!input) return;\n\n\t\t\t\tlet debounceTimer;\n\t\t\t\tinput.addEventListener('input', () => {\n\t\t\t\t\tclearTimeout(debounceTimer);\n\t\t\t\t\tdebounceTimer = setTimeout(renderFn, 300);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction matchesSearch(item, searchTerm, fields) {\n\t\t\t\tif (!searchTerm) return true;\n\t\t\t\tconst term = searchTerm.toLowerCase();\n\t\t\t\treturn fields.some(field => {\n\t\t\t\t\tconst value = field.split('.').reduce((obj, key) => obj?.[key], item);\n\t\t\t\t\treturn value && String(value).toLowerCase().includes(term);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Render Functions\n\t\t\tfunction renderOverview() {\n\t\t\t\tif (!metadata) return;\n\n\t\t\t\tconst content = document.getElementById('overview-content');\n\t\t\t\tconst stats = {\n\t\t\t\t\t'Total Actions': metadata.actions?.length || 0,\n\t\t\t\t\t'Total Pages': metadata.pages?.length || 0,\n\t\t\t\t\t'Total Queues': metadata.queues?.length || 0,\n\t\t\t\t\t'Total Schedulers': metadata.schedulers?.length || 0,\n\t\t\t\t\t'Total Topics': metadata.topics?.length || 0,\n\t\t\t\t\t'Total Buckets': metadata.buckets?.length || 0,\n\t\t\t\t\t'Total Caches': metadata.caches?.length || 0,\n\t\t\t\t\t'Total Realms': metadata.realms?.length || 0,\n\t\t\t\t\t'Total Providers': metadata.providers?.length || 0,\n\t\t\t\t\t'Total Modules': metadata.modules?.length || 0,\n\t\t\t\t\t'Log Entries': metadata.logs?.length || 0,\n\t\t\t\t};\n\n\t\t\t\tconst methodCounts = {};\n\t\t\t\tmetadata.actions?.forEach(action => {\n\t\t\t\t\tmethodCounts[action.method] = (methodCounts[action.method] || 0) + 1;\n\t\t\t\t});\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div style=\"display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 2rem;\">\n\t\t\t\t\t\t\\${Object.entries(stats).map(([key, value]) => \\`\n\t\t\t\t\t\t\t<div style=\"background: var(--bg-tertiary); padding: 1.5rem; border-radius: 8px; text-align: center;\">\n\t\t\t\t\t\t\t\t<div style=\"font-size: 2rem; font-weight: 700; color: var(--primary);\">\\${value}</div>\n\t\t\t\t\t\t\t\t<div style=\"font-size: 0.875rem; color: var(--text-muted); margin-top: 0.5rem;\">\\${escapeHtml(key)}</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t\\${Object.keys(methodCounts).length > 0 ? \\`\n\t\t\t\t\t\t<div class=\"detail-section\">\n\t\t\t\t\t\t\t<h3 class=\"detail-title\">HTTP Methods Distribution</h3>\n\t\t\t\t\t\t\t<div style=\"display: flex; gap: 1rem; flex-wrap: wrap;\">\n\t\t\t\t\t\t\t\t\\${Object.entries(methodCounts).map(([method, count]) => \\`\n\t\t\t\t\t\t\t\t\t<div class=\"badge badge-\\${method.toLowerCase()}\">\\${method}: \\${count}</div>\n\t\t\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\\` : ''}\n\n\t\t\t\t\t<div class=\"detail-section\">\n\t\t\t\t\t\t<h3 class=\"detail-title\">Raw Metadata</h3>\n\t\t\t\t\t\t<div class=\"code-block\">\\${escapeHtml(formatJson(metadata))}</div>\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderActions() {\n\t\t\t\tif (!metadata?.actions) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-actions')?.value || '';\n\t\t\t\tconst filteredActions = metadata.actions.filter(action => {\n\t\t\t\t\tconst matchesMethod = activeFilters.actions.methods.size === 0 ||\n\t\t\t\t\t\tactiveFilters.actions.methods.has(action.method);\n\t\t\t\t\tconst matchesSearchTerm = matchesSearch(action, searchTerm, ['name', 'path', 'group', 'fullPath']);\n\t\t\t\t\treturn matchesMethod && matchesSearchTerm;\n\t\t\t\t});\n\n\t\t\t\tconst content = document.getElementById('actions-content');\n\n\t\t\t\tif (filteredActions.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t\t<div class=\"empty-state\">\n\t\t\t\t\t\t\t<div class=\"empty-icon\">🔍</div>\n\t\t\t\t\t\t\t<div>No actions found</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredActions.map(action => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(action.name)}</div>\n\t\t\t\t\t\t\t\t\t<div style=\"display: flex; gap: 0.5rem; flex-wrap: wrap;\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"badge badge-\\${action.method.toLowerCase()}\">\\${action.method}</span>\n\t\t\t\t\t\t\t\t\t\t\\${action.secure ? '<span class=\"badge badge-secure\">🔒 Secure</span>' : ''}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${action.description ? \\`<div class=\"card-description\">\\${escapeHtml(action.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t<div class=\"card-path\">\\${escapeHtml(action.fullPath)}</div>\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-meta-item\">\n\t\t\t\t\t\t\t\t\t\t<span>📁</span>\n\t\t\t\t\t\t\t\t\t\t<span>\\${escapeHtml(action.group)}</span>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\\${action.disabled ? '<div class=\"card-meta-item\"><span>⚠️</span><span>Disabled</span></div>' : ''}\n\t\t\t\t\t\t\t\t\t\\${action.hide ? '<div class=\"card-meta-item\"><span>👁️</span><span>Hidden</span></div>' : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderPages() {\n\t\t\t\tif (!metadata?.pages) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-pages')?.value || '';\n\t\t\t\tconst filteredPages = metadata.pages.filter(page =>\n\t\t\t\t\tmatchesSearch(page, searchTerm, ['name', 'path'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('pages-content');\n\n\t\t\t\tif (filteredPages.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No pages found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredPages.map(page => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(page.name)}</div>\n\t\t\t\t\t\t\t\t\t\\${page.static ? '<span class=\"badge\" style=\"background: var(--success);\">Static</span>' : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${page.description ? \\`<div class=\"card-description\">\\${escapeHtml(page.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t\\${page.path ? \\`<div class=\"card-path\">\\${escapeHtml(page.path)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t\\${page.hasComponent ? '<div class=\"card-meta-item\"><span>✓</span><span>Component</span></div>' : ''}\n\t\t\t\t\t\t\t\t\t\\${page.hasLazy ? '<div class=\"card-meta-item\"><span>⚡</span><span>Lazy</span></div>' : ''}\n\t\t\t\t\t\t\t\t\t\\${page.hasResolve ? '<div class=\"card-meta-item\"><span>🔄</span><span>Resolve</span></div>' : ''}\n\t\t\t\t\t\t\t\t\t\\${page.hasChildren ? '<div class=\"card-meta-item\"><span>👶</span><span>Children</span></div>' : ''}\n\t\t\t\t\t\t\t\t\t\\${page.hasErrorHandler ? '<div class=\"card-meta-item\"><span>⚠️</span><span>Error Handler</span></div>' : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderQueues() {\n\t\t\t\tif (!metadata?.queues) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-queues')?.value || '';\n\t\t\t\tconst filteredQueues = metadata.queues.filter(queue =>\n\t\t\t\t\tmatchesSearch(queue, searchTerm, ['name', 'provider'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('queues-content');\n\n\t\t\t\tif (filteredQueues.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No queues found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredQueues.map(queue => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(queue.name)}</div>\n\t\t\t\t\t\t\t\t\t<span class=\"badge\" style=\"background: var(--primary);\">\\${escapeHtml(queue.provider)}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${queue.description ? \\`<div class=\"card-description\">\\${escapeHtml(queue.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t\\${queue.schema ? \\`<div class=\"detail-section\" style=\"margin-top: 1rem;\"><div class=\"detail-title\">Schema</div><div class=\"code-block\">\\${escapeHtml(formatJson(queue.schema))}</div></div>\\` : ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderSchedulers() {\n\t\t\t\tif (!metadata?.schedulers) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-schedulers')?.value || '';\n\t\t\t\tconst filteredSchedulers = metadata.schedulers.filter(scheduler =>\n\t\t\t\t\tmatchesSearch(scheduler, searchTerm, ['name', 'cron'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('schedulers-content');\n\n\t\t\t\tif (filteredSchedulers.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No schedulers found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredSchedulers.map(scheduler => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(scheduler.name)}</div>\n\t\t\t\t\t\t\t\t\t\\${scheduler.lock ? '<span class=\"badge\" style=\"background: var(--warning);\">🔒 Locked</span>' : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${scheduler.description ? \\`<div class=\"card-description\">\\${escapeHtml(scheduler.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t\\${scheduler.cron ? \\`<div class=\"card-meta-item\"><span>⏰</span><span class=\"text-code\">\\${escapeHtml(scheduler.cron)}</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\\${scheduler.interval ? \\`<div class=\"card-meta-item\"><span>🔄</span><span>\\${JSON.stringify(scheduler.interval)}</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderTopics() {\n\t\t\t\tif (!metadata?.topics) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-topics')?.value || '';\n\t\t\t\tconst filteredTopics = metadata.topics.filter(topic =>\n\t\t\t\t\tmatchesSearch(topic, searchTerm, ['name', 'provider'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('topics-content');\n\n\t\t\t\tif (filteredTopics.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No topics found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredTopics.map(topic => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(topic.name)}</div>\n\t\t\t\t\t\t\t\t\t<span class=\"badge\" style=\"background: var(--primary);\">\\${escapeHtml(topic.provider)}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${topic.description ? \\`<div class=\"card-description\">\\${escapeHtml(topic.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t\\${topic.schema ? \\`<div class=\"detail-section\" style=\"margin-top: 1rem;\"><div class=\"detail-title\">Schema</div><div class=\"code-block\">\\${escapeHtml(formatJson(topic.schema))}</div></div>\\` : ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderBuckets() {\n\t\t\t\tif (!metadata?.buckets) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-buckets')?.value || '';\n\t\t\t\tconst filteredBuckets = metadata.buckets.filter(bucket =>\n\t\t\t\t\tmatchesSearch(bucket, searchTerm, ['name', 'provider'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('buckets-content');\n\n\t\t\t\tif (filteredBuckets.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No buckets found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredBuckets.map(bucket => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(bucket.name)}</div>\n\t\t\t\t\t\t\t\t\t<span class=\"badge\" style=\"background: var(--primary);\">\\${escapeHtml(bucket.provider)}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${bucket.description ? \\`<div class=\"card-description\">\\${escapeHtml(bucket.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t\\${bucket.maxSize ? \\`<div class=\"card-meta-item\"><span>📦</span><span>Max: \\${bucket.maxSize} bytes</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\\${bucket.mimeTypes?.length ? \\`<div class=\"card-meta-item\"><span>📄</span><span>\\${bucket.mimeTypes.length} mime types</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderCaches() {\n\t\t\t\tif (!metadata?.caches) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-caches')?.value || '';\n\t\t\t\tconst filteredCaches = metadata.caches.filter(cache =>\n\t\t\t\t\tmatchesSearch(cache, searchTerm, ['name', 'provider'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('caches-content');\n\n\t\t\t\tif (filteredCaches.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No caches found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredCaches.map(cache => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(cache.name)}</div>\n\t\t\t\t\t\t\t\t\t<div style=\"display: flex; gap: 0.5rem;\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"badge\" style=\"background: var(--primary);\">\\${escapeHtml(cache.provider)}</span>\n\t\t\t\t\t\t\t\t\t\t\\${cache.disabled ? '<span class=\"badge\" style=\"background: var(--danger);\">Disabled</span>' : ''}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t\\${cache.ttl ? \\`<div class=\"card-meta-item\"><span>⏱️</span><span>TTL: \\${JSON.stringify(cache.ttl)}</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderRealms() {\n\t\t\t\tif (!metadata?.realms) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-realms')?.value || '';\n\t\t\t\tconst filteredRealms = metadata.realms.filter(realm =>\n\t\t\t\t\tmatchesSearch(realm, searchTerm, ['name', 'type'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('realms-content');\n\n\t\t\t\tif (filteredRealms.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No realms found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredRealms.map(realm => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(realm.name)}</div>\n\t\t\t\t\t\t\t\t\t<span class=\"badge badge-\\${realm.type}\">\\${escapeHtml(realm.type)}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${realm.description ? \\`<div class=\"card-description\">\\${escapeHtml(realm.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t\\${realm.roles?.length ? \\`<div class=\"card-meta\"><div class=\"card-meta-item\"><span>👥</span><span>\\${realm.roles.length} roles</span></div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\\${realm.settings ? \\`\n\t\t\t\t\t\t\t\t\t<div class=\"detail-section\" style=\"margin-top: 1rem;\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"detail-title\">Settings</div>\n\t\t\t\t\t\t\t\t\t\t<div class=\"property-list\">\n\t\t\t\t\t\t\t\t\t\t\t\\${realm.settings.accessTokenExpiration ? \\`<div class=\"property\"><div class=\"property-key\">Access Token</div><div class=\"property-value\">\\${JSON.stringify(realm.settings.accessTokenExpiration)}</div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\t\t\\${realm.settings.refreshTokenExpiration ? \\`<div class=\"property\"><div class=\"property-key\">Refresh Token</div><div class=\"property-value\">\\${JSON.stringify(realm.settings.refreshTokenExpiration)}</div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\t\t\\${realm.settings.hasOnCreateSession ? \\`<div class=\"property\"><div class=\"property-key\">On Create</div><div class=\"property-value\">✓</div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\t\t\\${realm.settings.hasOnRefreshSession ? \\`<div class=\"property\"><div class=\"property-key\">On Refresh</div><div class=\"property-value\">✓</div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\t\t\\${realm.settings.hasOnDeleteSession ? \\`<div class=\"property\"><div class=\"property-key\">On Delete</div><div class=\"property-value\">✓</div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\` : ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderProviders() {\n\t\t\t\tif (!metadata?.providers) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-providers')?.value || '';\n\t\t\t\tconst filteredProviders = metadata.providers.filter(provider =>\n\t\t\t\t\tmatchesSearch(provider, searchTerm, ['name', 'module'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('providers-content');\n\n\t\t\t\tif (filteredProviders.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No providers found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredProviders.map(provider => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(provider.name)}</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${provider.module ? \\`<div class=\"card-description\">📦 \\${escapeHtml(provider.module)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t\\${provider.dependencies?.length ? \\`<div class=\"card-meta-item\"><span>🔗</span><span>\\${provider.dependencies.length} dependencies</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\\${provider.aliases?.length ? \\`<div class=\"card-meta-item\"><span>🏷️</span><span>\\${provider.aliases.length} aliases</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${provider.dependencies?.length ? \\`\n\t\t\t\t\t\t\t\t\t<div class=\"detail-section\" style=\"margin-top: 1rem;\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"detail-title\">Dependencies</div>\n\t\t\t\t\t\t\t\t\t\t<div style=\"display: flex; flex-wrap: wrap; gap: 0.5rem;\">\n\t\t\t\t\t\t\t\t\t\t\t\\${provider.dependencies.map(dep => \\`<span class=\"text-code\">\\${escapeHtml(dep)}</span>\\`).join('')}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\` : ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderModules() {\n\t\t\t\tif (!metadata?.modules) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-modules')?.value || '';\n\t\t\t\tconst filteredModules = metadata.modules.filter(module =>\n\t\t\t\t\tmatchesSearch(module, searchTerm, ['name'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('modules-content');\n\n\t\t\t\tif (filteredModules.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No modules found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredModules.map(module => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(module.name)}</div>\n\t\t\t\t\t\t\t\t\t<span class=\"badge\" style=\"background: var(--success);\">\\${module.providers?.length || 0} providers</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${module.providers?.length ? \\`\n\t\t\t\t\t\t\t\t\t<div class=\"detail-section\" style=\"margin-top: 1rem;\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"detail-title\">Providers</div>\n\t\t\t\t\t\t\t\t\t\t<div style=\"display: flex; flex-wrap: wrap; gap: 0.5rem;\">\n\t\t\t\t\t\t\t\t\t\t\t\\${module.providers.map(prov => \\`<span class=\"text-code\">\\${escapeHtml(prov)}</span>\\`).join('')}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\` : ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderLogs() {\n\t\t\t\tif (!metadata?.logs) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-logs')?.value || '';\n\t\t\t\tconst level = activeFilters.logs.level;\n\n\t\t\t\tconst filteredLogs = metadata.logs.filter(log => {\n\t\t\t\t\tconst matchesLevel = level === 'all' || getLogLevel(log.formatted) === level;\n\t\t\t\t\tconst matchesSearchTerm = !searchTerm || log.formatted.toLowerCase().includes(searchTerm.toLowerCase());\n\t\t\t\t\treturn matchesLevel && matchesSearchTerm;\n\t\t\t\t});\n\n\t\t\t\tconst content = document.getElementById('logs-content');\n\n\t\t\t\tif (filteredLogs.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">📋</div><div>No logs found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"log-container\">\n\t\t\t\t\t\t\\${filteredLogs.map(log => {\n\t\t\t\t\t\t\tconst level = getLogLevel(log.formatted);\n\t\t\t\t\t\t\treturn \\`<div class=\"log-entry log-\\${level}\">\\${escapeHtml(log.formatted)}</div>\\`;\n\t\t\t\t\t\t}).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderTab(tabName) {\n\t\t\t\tif (!metadata) return;\n\n\t\t\t\tswitch(tabName) {\n\t\t\t\t\tcase 'overview': renderOverview(); break;\n\t\t\t\t\tcase 'actions': renderActions(); break;\n\t\t\t\t\tcase 'pages': renderPages(); break;\n\t\t\t\t\tcase 'queues': renderQueues(); break;\n\t\t\t\t\tcase 'schedulers': renderSchedulers(); break;\n\t\t\t\t\tcase 'topics': renderTopics(); break;\n\t\t\t\t\tcase 'buckets': renderBuckets(); break;\n\t\t\t\t\tcase 'caches': renderCaches(); break;\n\t\t\t\t\tcase 'realms': renderRealms(); break;\n\t\t\t\t\tcase 'providers': renderProviders(); break;\n\t\t\t\t\tcase 'modules': renderModules(); break;\n\t\t\t\t\tcase 'logs': renderLogs(); break;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Initialize\n\t\t\tasync function init() {\n\t\t\t\ttry {\n\t\t\t\t\tconst res = await fetch('/_devtools/metadata');\n\t\t\t\t\tmetadata = await res.json();\n\n\t\t\t\t\t// Update header stats\n\t\t\t\t\tdocument.getElementById('stat-actions').textContent = metadata.actions?.length || 0;\n\t\t\t\t\tdocument.getElementById('stat-pages').textContent = metadata.pages?.length || 0;\n\t\t\t\t\tdocument.getElementById('stat-modules').textContent = metadata.modules?.length || 0;\n\t\t\t\t\tdocument.getElementById('stat-providers').textContent = metadata.providers?.length || 0;\n\n\t\t\t\t\t// Setup method filters for actions\n\t\t\t\t\tconst methods = [...new Set(metadata.actions?.map(a => a.method) || [])];\n\t\t\t\t\tconst filterContainer = document.getElementById('filter-actions-methods');\n\t\t\t\t\tfilterContainer.innerHTML = methods.map(method =>\n\t\t\t\t\t\t\\`<button class=\"filter-btn\" data-method=\"\\${method}\">\\${method}</button>\\`\n\t\t\t\t\t).join('');\n\n\t\t\t\t\tfilterContainer.querySelectorAll('.filter-btn').forEach(btn => {\n\t\t\t\t\t\tbtn.addEventListener('click', () => {\n\t\t\t\t\t\t\tconst method = btn.dataset.method;\n\t\t\t\t\t\t\tif (activeFilters.actions.methods.has(method)) {\n\t\t\t\t\t\t\t\tactiveFilters.actions.methods.delete(method);\n\t\t\t\t\t\t\t\tbtn.classList.remove('active');\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tactiveFilters.actions.methods.add(method);\n\t\t\t\t\t\t\t\tbtn.classList.add('active');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trenderActions();\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\n\t\t\t\t\t// Setup log level filters\n\t\t\t\t\tdocument.querySelectorAll('[data-level]').forEach(btn => {\n\t\t\t\t\t\tbtn.addEventListener('click', () => {\n\t\t\t\t\t\t\tdocument.querySelectorAll('[data-level]').forEach(b => b.classList.remove('active'));\n\t\t\t\t\t\t\tbtn.classList.add('active');\n\t\t\t\t\t\t\tactiveFilters.logs.level = btn.dataset.level;\n\t\t\t\t\t\t\trenderLogs();\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\n\t\t\t\t\t// Setup search handlers\n\t\t\t\t\tsetupSearch('search-actions', renderActions);\n\t\t\t\t\tsetupSearch('search-pages', renderPages);\n\t\t\t\t\tsetupSearch('search-queues', renderQueues);\n\t\t\t\t\tsetupSearch('search-schedulers', renderSchedulers);\n\t\t\t\t\tsetupSearch('search-topics', renderTopics);\n\t\t\t\t\tsetupSearch('search-buckets', renderBuckets);\n\t\t\t\t\tsetupSearch('search-caches', renderCaches);\n\t\t\t\t\tsetupSearch('search-realms', renderRealms);\n\t\t\t\t\tsetupSearch('search-providers', renderProviders);\n\t\t\t\t\tsetupSearch('search-modules', renderModules);\n\t\t\t\t\tsetupSearch('search-logs', renderLogs);\n\n\t\t\t\t\t// Render initial tab\n\t\t\t\t\trenderTab('overview');\n\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('Failed to load metadata:', error);\n\t\t\t\t\tdocument.querySelectorAll('.loading').forEach(el => {\n\t\t\t\t\t\tel.innerHTML = \\`\n\t\t\t\t\t\t\t<div class=\"empty-state\">\n\t\t\t\t\t\t\t\t<div class=\"empty-icon\">⚠️</div>\n\t\t\t\t\t\t\t\t<div>Failed to load metadata</div>\n\t\t\t\t\t\t\t\t<div style=\"margin-top: 0.5rem; color: var(--text-muted);\">\\${escapeHtml(error.message)}</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinit();\n\t\t</script>\n</body>\n</html>`;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devActionMetadataSchema = t.object({\n\tname: t.string(),\n\tgroup: t.string(),\n\tmethod: t.string(),\n\tpath: t.string(),\n\tprefix: t.string(),\n\tfullPath: t.string(),\n\tdescription: t.optional(t.string()),\n\tsummary: t.optional(t.string()),\n\tdisabled: t.optional(t.boolean()),\n\tsecure: t.optional(t.boolean()),\n\thide: t.optional(t.boolean()),\n\tbody: t.optional(t.any()),\n\tparams: t.optional(t.any()),\n\tquery: t.optional(t.any()),\n\tresponse: t.optional(t.any()),\n\tbodyContentType: t.optional(t.string()),\n});\n\nexport type DevActionMetadata = Static<typeof devActionMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devBucketMetadataSchema = t.object({\n\tname: t.string(),\n\tdescription: t.optional(t.string()),\n\tmimeTypes: t.optional(t.array(t.string())),\n\tmaxSize: t.optional(t.number()),\n\tprovider: t.string(),\n});\n\nexport type DevBucketMetadata = Static<typeof devBucketMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devCacheMetadataSchema = t.object({\n\tname: t.string(),\n\tttl: t.optional(t.any()),\n\tdisabled: t.optional(t.boolean()),\n\tprovider: t.string(),\n});\n\nexport type DevCacheMetadata = Static<typeof devCacheMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\nimport type { LogEntry } from \"@alepha/logger\";\n\nexport const devLogEntrySchema = t.object({\n\tformatted: t.string(),\n\tentry: t.any(), // Use any since LogEntry has Date instead of string for timestamp\n});\n\nexport type DevLogEntry = Static<typeof devLogEntrySchema> & {\n\tentry: LogEntry;\n};\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devModuleMetadataSchema = t.object({\n\tname: t.string(),\n\tproviders: t.array(t.string()),\n});\n\nexport type DevModuleMetadata = Static<typeof devModuleMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devPageMetadataSchema = t.object({\n\tname: t.string(),\n\tdescription: t.optional(t.string()),\n\tpath: t.optional(t.string()),\n\tparams: t.optional(t.any()),\n\tquery: t.optional(t.any()),\n\thasComponent: t.boolean(),\n\thasLazy: t.boolean(),\n\thasResolve: t.boolean(),\n\thasChildren: t.boolean(),\n\thasParent: t.boolean(),\n\thasErrorHandler: t.boolean(),\n\tstatic: t.optional(t.boolean()),\n\tcache: t.optional(t.any()),\n\tclient: t.optional(t.any()),\n\tanimation: t.optional(t.any()),\n});\n\nexport type DevPageMetadata = Static<typeof devPageMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devProviderMetadataSchema = t.object({\n\tname: t.string(),\n\tmodule: t.optional(t.string()),\n\tdependencies: t.array(t.string()),\n\taliases: t.optional(t.array(t.string())),\n});\n\nexport type DevProviderMetadata = Static<typeof devProviderMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devQueueMetadataSchema = t.object({\n\tname: t.string(),\n\tdescription: t.optional(t.string()),\n\tschema: t.optional(t.any()),\n\tprovider: t.string(),\n});\n\nexport type DevQueueMetadata = Static<typeof devQueueMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devRealmMetadataSchema = t.object({\n\tname: t.string(),\n\tdescription: t.optional(t.string()),\n\troles: t.optional(t.array(t.any())),\n\ttype: t.enum([\"internal\", \"external\"]),\n\tsettings: t.optional(\n\t\tt.object({\n\t\t\taccessTokenExpiration: t.optional(t.any()),\n\t\t\trefreshTokenExpiration: t.optional(t.any()),\n\t\t\thasOnCreateSession: t.boolean(),\n\t\t\thasOnRefreshSession: t.boolean(),\n\t\t\thasOnDeleteSession: t.boolean(),\n\t\t}),\n\t),\n});\n\nexport type DevRealmMetadata = Static<typeof devRealmMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devSchedulerMetadataSchema = t.object({\n\tname: t.string(),\n\tdescription: t.optional(t.string()),\n\tcron: t.optional(t.string()),\n\tinterval: t.optional(t.any()),\n\tlock: t.optional(t.boolean()),\n});\n\nexport type DevSchedulerMetadata = Static<typeof devSchedulerMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devTopicMetadataSchema = t.object({\n\tname: t.string(),\n\tdescription: t.optional(t.string()),\n\tschema: t.optional(t.any()),\n\tprovider: t.string(),\n});\n\nexport type DevTopicMetadata = Static<typeof devTopicMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\nimport { devActionMetadataSchema } from \"./DevActionMetadata.ts\";\nimport { devBucketMetadataSchema } from \"./DevBucketMetadata.ts\";\nimport { devCacheMetadataSchema } from \"./DevCacheMetadata.ts\";\nimport { devLogEntrySchema } from \"./DevLogEntry.ts\";\nimport { devModuleMetadataSchema } from \"./DevModuleMetadata.ts\";\nimport { devPageMetadataSchema } from \"./DevPageMetadata.ts\";\nimport { devProviderMetadataSchema } from \"./DevProviderMetadata.ts\";\nimport { devQueueMetadataSchema } from \"./DevQueueMetadata.ts\";\nimport { devRealmMetadataSchema } from \"./DevRealmMetadata.ts\";\nimport { devSchedulerMetadataSchema } from \"./DevSchedulerMetadata.ts\";\nimport { devTopicMetadataSchema } from \"./DevTopicMetadata.ts\";\n\nexport const devMetadataSchema = t.object({\n\tlogs: t.array(devLogEntrySchema),\n\tactions: t.array(devActionMetadataSchema),\n\tqueues: t.array(devQueueMetadataSchema),\n\tschedulers: t.array(devSchedulerMetadataSchema),\n\ttopics: t.array(devTopicMetadataSchema),\n\tbuckets: t.array(devBucketMetadataSchema),\n\trealms: t.array(devRealmMetadataSchema),\n\tcaches: t.array(devCacheMetadataSchema),\n\tpages: t.array(devPageMetadataSchema),\n\tproviders: t.array(devProviderMetadataSchema),\n\tmodules: t.array(devModuleMetadataSchema),\n\t// More metadata will be added here later\n});\n\nexport type DevMetadata = Static<typeof devMetadataSchema>;\n","import { $bucket } from \"@alepha/bucket\";\nimport { $cache } from \"@alepha/cache\";\nimport { $hook, $inject, Alepha, t } from \"@alepha/core\";\nimport type { LogEntry } from \"@alepha/logger\";\nimport { $queue } from \"@alepha/queue\";\nimport { $page } from \"@alepha/react\";\nimport { $scheduler } from \"@alepha/scheduler\";\nimport { $realm } from \"@alepha/security\";\nimport { $action, $route } from \"@alepha/server\";\nimport { $topic } from \"@alepha/topic\";\nimport { ui } from \"./constants/ui.ts\";\nimport type { DevActionMetadata } from \"./schemas/DevActionMetadata.ts\";\nimport type { DevBucketMetadata } from \"./schemas/DevBucketMetadata.ts\";\nimport type { DevCacheMetadata } from \"./schemas/DevCacheMetadata.ts\";\nimport type { DevLogEntry } from \"./schemas/DevLogEntry.ts\";\nimport { type DevMetadata, devMetadataSchema } from \"./schemas/DevMetadata.ts\";\nimport type { DevModuleMetadata } from \"./schemas/DevModuleMetadata.ts\";\nimport type { DevPageMetadata } from \"./schemas/DevPageMetadata.ts\";\nimport type { DevProviderMetadata } from \"./schemas/DevProviderMetadata.ts\";\nimport type { DevQueueMetadata } from \"./schemas/DevQueueMetadata.ts\";\nimport type { DevRealmMetadata } from \"./schemas/DevRealmMetadata.ts\";\nimport type { DevSchedulerMetadata } from \"./schemas/DevSchedulerMetadata.ts\";\nimport type { DevTopicMetadata } from \"./schemas/DevTopicMetadata.ts\";\n\nexport class DevCollectorProvider {\n\tprotected readonly alepha = $inject(Alepha);\n\tprotected readonly logs: DevLogEntry[] = [];\n\tprotected readonly maxLogs = 1000;\n\n\tprotected readonly onLog = $hook({\n\t\ton: \"log\",\n\t\thandler: (ev: { message: string; entry: LogEntry }) => {\n\t\t\tthis.logs.push({\n\t\t\t\tformatted: ev.message,\n\t\t\t\tentry: ev.entry,\n\t\t\t});\n\n\t\t\t// Keep only the last 1000 logs\n\t\t\tif (this.logs.length > this.maxLogs) {\n\t\t\t\tthis.logs.shift();\n\t\t\t}\n\t\t},\n\t});\n\n\tprotected readonly uiRoute = $route({\n\t\tmethod: \"GET\",\n\t\tpath: \"/devtools\",\n\t\tschema: {\n\t\t\tresponse: t.string(),\n\t\t},\n\t\thandler: () => {\n\t\t\treturn ui;\n\t\t},\n\t});\n\n\tprotected readonly metadataRoute = $route({\n\t\tmethod: \"GET\",\n\t\tpath: \"/devtools/metadata\",\n\t\tschema: {\n\t\t\tresponse: devMetadataSchema,\n\t\t},\n\t\thandler: () => {\n\t\t\treturn this.getMetadata();\n\t\t},\n\t});\n\n\tpublic getLogs(): DevLogEntry[] {\n\t\treturn this.logs;\n\t}\n\n\tpublic getActions(): DevActionMetadata[] {\n\t\tconst actionDescriptors = this.alepha.descriptors($action);\n\n\t\treturn actionDescriptors.map((action) => {\n\t\t\tconst schema = action.schema;\n\t\t\tconst options = action.options as any; // Allow accessing augmented properties\n\n\t\t\treturn {\n\t\t\t\tname: action.name,\n\t\t\t\tgroup: action.group,\n\t\t\t\tmethod: action.method,\n\t\t\t\tpath: action.path,\n\t\t\t\tprefix: action.prefix,\n\t\t\t\tfullPath: action.route.path,\n\t\t\t\tdescription: action.options.description,\n\t\t\t\tsummary: options.summary,\n\t\t\t\tdisabled: action.options.disabled,\n\t\t\t\tsecure: options.secure,\n\t\t\t\thide: options.hide,\n\t\t\t\tbody: schema?.body,\n\t\t\t\tparams: schema?.params,\n\t\t\t\tquery: schema?.query,\n\t\t\t\tresponse: schema?.response,\n\t\t\t\tbodyContentType: action.getBodyContentType(),\n\t\t\t};\n\t\t});\n\t}\n\n\tpublic getQueues(): DevQueueMetadata[] {\n\t\tconst queueDescriptors = this.alepha.descriptors($queue);\n\n\t\treturn queueDescriptors.map((queue) => ({\n\t\t\tname: queue.name,\n\t\t\tdescription: queue.options.description,\n\t\t\tschema: queue.options.schema,\n\t\t\tprovider: this.getProviderName(queue.options.provider),\n\t\t}));\n\t}\n\n\tpublic getSchedulers(): DevSchedulerMetadata[] {\n\t\tconst schedulerDescriptors = this.alepha.descriptors($scheduler);\n\n\t\treturn schedulerDescriptors.map((scheduler) => ({\n\t\t\tname: scheduler.name,\n\t\t\tdescription: scheduler.options.description,\n\t\t\tcron: scheduler.options.cron,\n\t\t\tinterval: scheduler.options.interval,\n\t\t\tlock: scheduler.options.lock,\n\t\t}));\n\t}\n\n\tpublic getTopics(): DevTopicMetadata[] {\n\t\tconst topicDescriptors = this.alepha.descriptors($topic);\n\n\t\treturn topicDescriptors.map((topic) => ({\n\t\t\tname: topic.name,\n\t\t\tdescription: topic.options.description,\n\t\t\tschema: topic.options.schema,\n\t\t\tprovider: this.getProviderName(topic.options.provider),\n\t\t}));\n\t}\n\n\tpublic getBuckets(): DevBucketMetadata[] {\n\t\tconst bucketDescriptors = this.alepha.descriptors($bucket);\n\n\t\treturn bucketDescriptors.map((bucket) => ({\n\t\t\tname: bucket.name,\n\t\t\tdescription: bucket.options.description,\n\t\t\tmimeTypes: bucket.options.mimeTypes,\n\t\t\tmaxSize: bucket.options.maxSize,\n\t\t\tprovider: this.getProviderName(bucket.options.provider),\n\t\t}));\n\t}\n\n\tpublic getRealms(): DevRealmMetadata[] {\n\t\tconst realmDescriptors = this.alepha.descriptors($realm);\n\n\t\treturn realmDescriptors.map((realm) => ({\n\t\t\tname: realm.name,\n\t\t\tdescription: realm.options.description,\n\t\t\troles: realm.options.roles,\n\t\t\ttype: \"secret\" in realm.options ? \"internal\" : \"external\",\n\t\t\tsettings: {\n\t\t\t\taccessTokenExpiration: realm.options.settings?.accessToken?.expiration,\n\t\t\t\trefreshTokenExpiration:\n\t\t\t\t\trealm.options.settings?.refreshToken?.expiration,\n\t\t\t\thasOnCreateSession: !!realm.options.settings?.onCreateSession,\n\t\t\t\thasOnRefreshSession: !!realm.options.settings?.onRefreshSession,\n\t\t\t\thasOnDeleteSession: !!realm.options.settings?.onDeleteSession,\n\t\t\t},\n\t\t}));\n\t}\n\n\tpublic getCaches(): DevCacheMetadata[] {\n\t\tconst cacheDescriptors = this.alepha.descriptors($cache);\n\n\t\treturn cacheDescriptors.map((cache) => ({\n\t\t\tname: cache.container,\n\t\t\tttl: cache.options.ttl,\n\t\t\tdisabled: cache.options.disabled,\n\t\t\tprovider: this.getProviderName(cache.options.provider),\n\t\t}));\n\t}\n\n\tpublic getPages(): DevPageMetadata[] {\n\t\tconst pageDescriptors = this.alepha.descriptors($page);\n\n\t\treturn pageDescriptors.map((page) => ({\n\t\t\tname: page.name,\n\t\t\tdescription: page.options.description,\n\t\t\tpath: page.options.path,\n\t\t\tparams: page.options.schema?.params,\n\t\t\tquery: page.options.schema?.query,\n\t\t\thasComponent: !!page.options.component,\n\t\t\thasLazy: !!page.options.lazy,\n\t\t\thasResolve: !!page.options.resolve,\n\t\t\thasChildren: !!page.options.children,\n\t\t\thasParent: !!page.options.parent,\n\t\t\thasErrorHandler: !!page.options.errorHandler,\n\t\t\tstatic:\n\t\t\t\ttypeof page.options.static === \"boolean\"\n\t\t\t\t\t? page.options.static\n\t\t\t\t\t: !!page.options.static,\n\t\t\tcache: page.options.cache,\n\t\t\tclient: page.options.client,\n\t\t\tanimation: page.options.animation,\n\t\t}));\n\t}\n\n\tpublic getProviders(): DevProviderMetadata[] {\n\t\tconst graph = this.alepha.graph();\n\n\t\treturn Object.entries(graph).map(([name, info]) => ({\n\t\t\tname,\n\t\t\tmodule: info.module,\n\t\t\tdependencies: info.from,\n\t\t\taliases: info.as,\n\t\t}));\n\t}\n\n\tpublic getModules(): DevModuleMetadata[] {\n\t\tconst graph = this.alepha.graph();\n\t\tconst moduleMap = new Map<string, Set<string>>();\n\n\t\t// Group providers by module\n\t\tfor (const [providerName, info] of Object.entries(graph)) {\n\t\t\tif (info.module) {\n\t\t\t\tif (!moduleMap.has(info.module)) {\n\t\t\t\t\tmoduleMap.set(info.module, new Set());\n\t\t\t\t}\n\t\t\t\tmoduleMap.get(info.module)!.add(providerName);\n\t\t\t}\n\t\t}\n\n\t\treturn Array.from(moduleMap.entries()).map(([name, providers]) => ({\n\t\t\tname,\n\t\t\tproviders: Array.from(providers),\n\t\t}));\n\t}\n\n\tpublic getMetadata(): DevMetadata {\n\t\treturn {\n\t\t\tlogs: this.getLogs(),\n\t\t\tactions: this.getActions(),\n\t\t\tqueues: this.getQueues(),\n\t\t\tschedulers: this.getSchedulers(),\n\t\t\ttopics: this.getTopics(),\n\t\t\tbuckets: this.getBuckets(),\n\t\t\trealms: this.getRealms(),\n\t\t\tcaches: this.getCaches(),\n\t\t\tpages: this.getPages(),\n\t\t\tproviders: this.getProviders(),\n\t\t\tmodules: this.getModules(),\n\t\t};\n\t}\n\n\tprotected getProviderName(provider?: \"memory\" | any): string {\n\t\tif (!provider) {\n\t\t\treturn \"default\";\n\t\t}\n\t\tif (provider === \"memory\") {\n\t\t\treturn \"memory\";\n\t\t}\n\t\treturn provider.name || \"custom\";\n\t}\n}\n","import { $module } from \"@alepha/core\";\nimport { DevCollectorProvider } from \"./DevCollectorProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./DevCollectorProvider.ts\";\nexport * from \"./schemas/DevActionMetadata.ts\";\nexport * from \"./schemas/DevBucketMetadata.ts\";\nexport * from \"./schemas/DevCacheMetadata.ts\";\nexport * from \"./schemas/DevLogEntry.ts\";\nexport * from \"./schemas/DevMetadata.ts\";\nexport * from \"./schemas/DevModuleMetadata.ts\";\nexport * from \"./schemas/DevPageMetadata.ts\";\nexport * from \"./schemas/DevProviderMetadata.ts\";\nexport * from \"./schemas/DevQueueMetadata.ts\";\nexport * from \"./schemas/DevRealmMetadata.ts\";\nexport * from \"./schemas/DevSchedulerMetadata.ts\";\nexport * from \"./schemas/DevTopicMetadata.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Developer tools module for monitoring and debugging Alepha applications.\n *\n * This module provides comprehensive data collection capabilities for tracking application behavior,\n * performance metrics, and debugging information in real-time.\n *\n * @see {@link DevCollectorProvider}\n * @module alepha.devtools\n */\nexport const AlephaDevtools = $module({\n\tname: \"alepha.devtools\",\n\tdescriptors: [],\n\tservices: [DevCollectorProvider],\n});\n"],"mappings":";;;;;;;;;;;AACA,MAAa,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACClB,MAAa,0BAA0B,EAAE,OAAO;CAC/C,MAAM,EAAE;CACR,OAAO,EAAE;CACT,QAAQ,EAAE;CACV,MAAM,EAAE;CACR,QAAQ,EAAE;CACV,UAAU,EAAE;CACZ,aAAa,EAAE,SAAS,EAAE;CAC1B,SAAS,EAAE,SAAS,EAAE;CACtB,UAAU,EAAE,SAAS,EAAE;CACvB,QAAQ,EAAE,SAAS,EAAE;CACrB,MAAM,EAAE,SAAS,EAAE;CACnB,MAAM,EAAE,SAAS,EAAE;CACnB,QAAQ,EAAE,SAAS,EAAE;CACrB,OAAO,EAAE,SAAS,EAAE;CACpB,UAAU,EAAE,SAAS,EAAE;CACvB,iBAAiB,EAAE,SAAS,EAAE;CAC9B;;;;ACjBD,MAAa,0BAA0B,EAAE,OAAO;CAC/C,MAAM,EAAE;CACR,aAAa,EAAE,SAAS,EAAE;CAC1B,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE;CAChC,SAAS,EAAE,SAAS,EAAE;CACtB,UAAU,EAAE;CACZ;;;;ACND,MAAa,yBAAyB,EAAE,OAAO;CAC9C,MAAM,EAAE;CACR,KAAK,EAAE,SAAS,EAAE;CAClB,UAAU,EAAE,SAAS,EAAE;CACvB,UAAU,EAAE;CACZ;;;;ACJD,MAAa,oBAAoB,EAAE,OAAO;CACzC,WAAW,EAAE;CACb,OAAO,EAAE;CACT;;;;ACJD,MAAa,0BAA0B,EAAE,OAAO;CAC/C,MAAM,EAAE;CACR,WAAW,EAAE,MAAM,EAAE;CACrB;;;;ACHD,MAAa,wBAAwB,EAAE,OAAO;CAC7C,MAAM,EAAE;CACR,aAAa,EAAE,SAAS,EAAE;CAC1B,MAAM,EAAE,SAAS,EAAE;CACnB,QAAQ,EAAE,SAAS,EAAE;CACrB,OAAO,EAAE,SAAS,EAAE;CACpB,cAAc,EAAE;CAChB,SAAS,EAAE;CACX,YAAY,EAAE;CACd,aAAa,EAAE;CACf,WAAW,EAAE;CACb,iBAAiB,EAAE;CACnB,QAAQ,EAAE,SAAS,EAAE;CACrB,OAAO,EAAE,SAAS,EAAE;CACpB,QAAQ,EAAE,SAAS,EAAE;CACrB,WAAW,EAAE,SAAS,EAAE;CACxB;;;;AChBD,MAAa,4BAA4B,EAAE,OAAO;CACjD,MAAM,EAAE;CACR,QAAQ,EAAE,SAAS,EAAE;CACrB,cAAc,EAAE,MAAM,EAAE;CACxB,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE;CAC9B;;;;ACLD,MAAa,yBAAyB,EAAE,OAAO;CAC9C,MAAM,EAAE;CACR,aAAa,EAAE,SAAS,EAAE;CAC1B,QAAQ,EAAE,SAAS,EAAE;CACrB,UAAU,EAAE;CACZ;;;;ACLD,MAAa,yBAAyB,EAAE,OAAO;CAC9C,MAAM,EAAE;CACR,aAAa,EAAE,SAAS,EAAE;CAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE;CAC5B,MAAM,EAAE,KAAK,CAAC,YAAY,WAAW;CACrC,UAAU,EAAE,SACX,EAAE,OAAO;EACR,uBAAuB,EAAE,SAAS,EAAE;EACpC,wBAAwB,EAAE,SAAS,EAAE;EACrC,oBAAoB,EAAE;EACtB,qBAAqB,EAAE;EACvB,oBAAoB,EAAE;EACtB;CAEF;;;;ACdD,MAAa,6BAA6B,EAAE,OAAO;CAClD,MAAM,EAAE;CACR,aAAa,EAAE,SAAS,EAAE;CAC1B,MAAM,EAAE,SAAS,EAAE;CACnB,UAAU,EAAE,SAAS,EAAE;CACvB,MAAM,EAAE,SAAS,EAAE;CACnB;;;;ACND,MAAa,yBAAyB,EAAE,OAAO;CAC9C,MAAM,EAAE;CACR,aAAa,EAAE,SAAS,EAAE;CAC1B,QAAQ,EAAE,SAAS,EAAE;CACrB,UAAU,EAAE;CACZ;;;;ACMD,MAAa,oBAAoB,EAAE,OAAO;CACzC,MAAM,EAAE,MAAM;CACd,SAAS,EAAE,MAAM;CACjB,QAAQ,EAAE,MAAM;CAChB,YAAY,EAAE,MAAM;CACpB,QAAQ,EAAE,MAAM;CAChB,SAAS,EAAE,MAAM;CACjB,QAAQ,EAAE,MAAM;CAChB,QAAQ,EAAE,MAAM;CAChB,OAAO,EAAE,MAAM;CACf,WAAW,EAAE,MAAM;CACnB,SAAS,EAAE,MAAM;CAEjB;;;;ACFD,IAAa,uBAAb,MAAkC;CACjC,AAAmB,SAAS,QAAQ;CACpC,AAAmB,OAAsB,EAAE;CAC3C,AAAmB,UAAU;CAE7B,AAAmB,QAAQ,MAAM;EAChC,IAAI;EACJ,UAAU,OAA6C;AACtD,QAAK,KAAK,KAAK;IACd,WAAW,GAAG;IACd,OAAO,GAAG;IACV;AAGD,OAAI,KAAK,KAAK,SAAS,KAAK,QAC3B,MAAK,KAAK;EAEX;EACD;CAED,AAAmB,UAAU,OAAO;EACnC,QAAQ;EACR,MAAM;EACN,QAAQ,EACP,UAAU,EAAE,UACZ;EACD,eAAe;AACd,UAAO;EACP;EACD;CAED,AAAmB,gBAAgB,OAAO;EACzC,QAAQ;EACR,MAAM;EACN,QAAQ,EACP,UAAU,mBACV;EACD,eAAe;AACd,UAAO,KAAK;EACZ;EACD;CAED,AAAO,UAAyB;AAC/B,SAAO,KAAK;CACZ;CAED,AAAO,aAAkC;EACxC,MAAM,oBAAoB,KAAK,OAAO,YAAY;AAElD,SAAO,kBAAkB,KAAK,WAAW;GACxC,MAAM,SAAS,OAAO;GACtB,MAAM,UAAU,OAAO;AAEvB,UAAO;IACN,MAAM,OAAO;IACb,OAAO,OAAO;IACd,QAAQ,OAAO;IACf,MAAM,OAAO;IACb,QAAQ,OAAO;IACf,UAAU,OAAO,MAAM;IACvB,aAAa,OAAO,QAAQ;IAC5B,SAAS,QAAQ;IACjB,UAAU,OAAO,QAAQ;IACzB,QAAQ,QAAQ;IAChB,MAAM,QAAQ;IACd,MAAM,QAAQ;IACd,QAAQ,QAAQ;IAChB,OAAO,QAAQ;IACf,UAAU,QAAQ;IAClB,iBAAiB,OAAO;IACxB;EACD;CACD;CAED,AAAO,YAAgC;EACtC,MAAM,mBAAmB,KAAK,OAAO,YAAY;AAEjD,SAAO,iBAAiB,KAAK,WAAW;GACvC,MAAM,MAAM;GACZ,aAAa,MAAM,QAAQ;GAC3B,QAAQ,MAAM,QAAQ;GACtB,UAAU,KAAK,gBAAgB,MAAM,QAAQ;GAC7C;CACD;CAED,AAAO,gBAAwC;EAC9C,MAAM,uBAAuB,KAAK,OAAO,YAAY;AAErD,SAAO,qBAAqB,KAAK,eAAe;GAC/C,MAAM,UAAU;GAChB,aAAa,UAAU,QAAQ;GAC/B,MAAM,UAAU,QAAQ;GACxB,UAAU,UAAU,QAAQ;GAC5B,MAAM,UAAU,QAAQ;GACxB;CACD;CAED,AAAO,YAAgC;EACtC,MAAM,mBAAmB,KAAK,OAAO,YAAY;AAEjD,SAAO,iBAAiB,KAAK,WAAW;GACvC,MAAM,MAAM;GACZ,aAAa,MAAM,QAAQ;GAC3B,QAAQ,MAAM,QAAQ;GACtB,UAAU,KAAK,gBAAgB,MAAM,QAAQ;GAC7C;CACD;CAED,AAAO,aAAkC;EACxC,MAAM,oBAAoB,KAAK,OAAO,YAAY;AAElD,SAAO,kBAAkB,KAAK,YAAY;GACzC,MAAM,OAAO;GACb,aAAa,OAAO,QAAQ;GAC5B,WAAW,OAAO,QAAQ;GAC1B,SAAS,OAAO,QAAQ;GACxB,UAAU,KAAK,gBAAgB,OAAO,QAAQ;GAC9C;CACD;CAED,AAAO,YAAgC;EACtC,MAAM,mBAAmB,KAAK,OAAO,YAAY;AAEjD,SAAO,iBAAiB,KAAK,WAAW;GACvC,MAAM,MAAM;GACZ,aAAa,MAAM,QAAQ;GAC3B,OAAO,MAAM,QAAQ;GACrB,MAAM,YAAY,MAAM,UAAU,aAAa;GAC/C,UAAU;IACT,uBAAuB,MAAM,QAAQ,UAAU,aAAa;IAC5D,wBACC,MAAM,QAAQ,UAAU,cAAc;IACvC,oBAAoB,CAAC,CAAC,MAAM,QAAQ,UAAU;IAC9C,qBAAqB,CAAC,CAAC,MAAM,QAAQ,UAAU;IAC/C,oBAAoB,CAAC,CAAC,MAAM,QAAQ,UAAU;IAC9C;GACD;CACD;CAED,AAAO,YAAgC;EACtC,MAAM,mBAAmB,KAAK,OAAO,YAAY;AAEjD,SAAO,iBAAiB,KAAK,WAAW;GACvC,MAAM,MAAM;GACZ,KAAK,MAAM,QAAQ;GACnB,UAAU,MAAM,QAAQ;GACxB,UAAU,KAAK,gBAAgB,MAAM,QAAQ;GAC7C;CACD;CAED,AAAO,WAA8B;EACpC,MAAM,kBAAkB,KAAK,OAAO,YAAY;AAEhD,SAAO,gBAAgB,KAAK,UAAU;GACrC,MAAM,KAAK;GACX,aAAa,KAAK,QAAQ;GAC1B,MAAM,KAAK,QAAQ;GACnB,QAAQ,KAAK,QAAQ,QAAQ;GAC7B,OAAO,KAAK,QAAQ,QAAQ;GAC5B,cAAc,CAAC,CAAC,KAAK,QAAQ;GAC7B,SAAS,CAAC,CAAC,KAAK,QAAQ;GACxB,YAAY,CAAC,CAAC,KAAK,QAAQ;GAC3B,aAAa,CAAC,CAAC,KAAK,QAAQ;GAC5B,WAAW,CAAC,CAAC,KAAK,QAAQ;GAC1B,iBAAiB,CAAC,CAAC,KAAK,QAAQ;GAChC,QACC,OAAO,KAAK,QAAQ,WAAW,YAC5B,KAAK,QAAQ,SACb,CAAC,CAAC,KAAK,QAAQ;GACnB,OAAO,KAAK,QAAQ;GACpB,QAAQ,KAAK,QAAQ;GACrB,WAAW,KAAK,QAAQ;GACxB;CACD;CAED,AAAO,eAAsC;EAC5C,MAAM,QAAQ,KAAK,OAAO;AAE1B,SAAO,OAAO,QAAQ,OAAO,KAAK,CAAC,MAAM,KAAK,MAAM;GACnD;GACA,QAAQ,KAAK;GACb,cAAc,KAAK;GACnB,SAAS,KAAK;GACd;CACD;CAED,AAAO,aAAkC;EACxC,MAAM,QAAQ,KAAK,OAAO;EAC1B,MAAM,4BAAY,IAAI;AAGtB,OAAK,MAAM,CAAC,cAAc,KAAK,IAAI,OAAO,QAAQ,OACjD,KAAI,KAAK,QAAQ;AAChB,OAAI,CAAC,UAAU,IAAI,KAAK,QACvB,WAAU,IAAI,KAAK,wBAAQ,IAAI;AAEhC,aAAU,IAAI,KAAK,QAAS,IAAI;EAChC;AAGF,SAAO,MAAM,KAAK,UAAU,WAAW,KAAK,CAAC,MAAM,UAAU,MAAM;GAClE;GACA,WAAW,MAAM,KAAK;GACtB;CACD;CAED,AAAO,cAA2B;AACjC,SAAO;GACN,MAAM,KAAK;GACX,SAAS,KAAK;GACd,QAAQ,KAAK;GACb,YAAY,KAAK;GACjB,QAAQ,KAAK;GACb,SAAS,KAAK;GACd,QAAQ,KAAK;GACb,QAAQ,KAAK;GACb,OAAO,KAAK;GACZ,WAAW,KAAK;GAChB,SAAS,KAAK;GACd;CACD;CAED,AAAU,gBAAgB,UAAmC;AAC5D,MAAI,CAAC,SACJ,QAAO;AAER,MAAI,aAAa,SAChB,QAAO;AAER,SAAO,SAAS,QAAQ;CACxB;AACD;;;;;;;;;;;;;ACjOD,MAAa,iBAAiB,QAAQ;CACrC,MAAM;CACN,aAAa,EAAE;CACf,UAAU,CAAC,qBAAqB;CAChC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/constants/ui.ts","../src/schemas/DevActionMetadata.ts","../src/schemas/DevBucketMetadata.ts","../src/schemas/DevCacheMetadata.ts","../src/schemas/DevModuleMetadata.ts","../src/schemas/DevPageMetadata.ts","../src/schemas/DevProviderMetadata.ts","../src/schemas/DevQueueMetadata.ts","../src/schemas/DevRealmMetadata.ts","../src/schemas/DevSchedulerMetadata.ts","../src/schemas/DevTopicMetadata.ts","../src/schemas/DevMetadata.ts","../src/DevCollectorProvider.ts","../src/schemas/DevLogEntry.ts","../src/index.ts"],"sourcesContent":["// language=HTML\nexport const ui = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n\t\t<title>Alepha DevTools</title>\n\t\t<style>\n\t\t\t:root {\n\t\t\t\t--primary: #3b82f6;\n\t\t\t\t--primary-dark: #2563eb;\n\t\t\t\t--success: #10b981;\n\t\t\t\t--warning: #f59e0b;\n\t\t\t\t--danger: #ef4444;\n\t\t\t\t--bg-primary: #0f172a;\n\t\t\t\t--bg-secondary: #1e293b;\n\t\t\t\t--bg-tertiary: #334155;\n\t\t\t\t--text-primary: #f8fafc;\n\t\t\t\t--text-secondary: #cbd5e1;\n\t\t\t\t--text-muted: #94a3b8;\n\t\t\t\t--border: #334155;\n\t\t\t\t--code-bg: #1e293b;\n\t\t\t\t--shadow: rgba(0, 0, 0, 0.3);\n\t\t\t}\n\n\t\t\t* {\n\t\t\t\tbox-sizing: border-box;\n\t\t\t\tmargin: 0;\n\t\t\t\tpadding: 0;\n\t\t\t}\n\n\t\t\tbody {\n\t\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n\t\t\t\tbackground: linear-gradient(135deg, var(--bg-primary) 0%, #0c1222 100%);\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t\tmin-height: 100vh;\n\t\t\t}\n\n\t\t\t/* Header */\n\t\t\t.header {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder-bottom: 1px solid var(--border);\n\t\t\t\tpadding: 1.5rem 2rem;\n\t\t\t\tposition: sticky;\n\t\t\t\ttop: 0;\n\t\t\t\tz-index: 1000;\n\t\t\t\tbox-shadow: 0 4px 6px var(--shadow);\n\t\t\t}\n\n\t\t\t.header-content {\n\t\t\t\tmax-width: 1600px;\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: space-between;\n\t\t\t\talign-items: center;\n\t\t\t}\n\n\t\t\t.logo {\n\t\t\t\tfont-size: 1.5rem;\n\t\t\t\tfont-weight: 700;\n\t\t\t\tbackground: linear-gradient(135deg, var(--primary), #8b5cf6);\n\t\t\t\t-webkit-background-clip: text;\n\t\t\t\t-webkit-text-fill-color: transparent;\n\t\t\t\tbackground-clip: text;\n\t\t\t}\n\n\t\t\t.header-stats {\n\t\t\t\tdisplay: flex;\n\t\t\t\tgap: 2rem;\n\t\t\t}\n\n\t\t\t.stat {\n\t\t\t\ttext-align: center;\n\t\t\t}\n\n\t\t\t.stat-value {\n\t\t\t\tfont-size: 1.5rem;\n\t\t\t\tfont-weight: 700;\n\t\t\t\tcolor: var(--primary);\n\t\t\t}\n\n\t\t\t.stat-label {\n\t\t\t\tfont-size: 0.75rem;\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tletter-spacing: 0.05em;\n\t\t\t}\n\n\t\t\t/* Navigation */\n\t\t\t.nav {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder-bottom: 1px solid var(--border);\n\t\t\t\tposition: sticky;\n\t\t\t\ttop: 73px;\n\t\t\t\tz-index: 999;\n\t\t\t}\n\n\t\t\t.nav-container {\n\t\t\t\tmax-width: 1600px;\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tpadding: 0 2rem;\n\t\t\t\tdisplay: flex;\n\t\t\t\tgap: 0.5rem;\n\t\t\t\toverflow-x: auto;\n\t\t\t}\n\n\t\t\t.nav-tab {\n\t\t\t\tpadding: 1rem 1.5rem;\n\t\t\t\tbackground: transparent;\n\t\t\t\tborder: none;\n\t\t\t\tcolor: var(--text-secondary);\n\t\t\t\tcursor: pointer;\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tfont-weight: 600;\n\t\t\t\tborder-bottom: 2px solid transparent;\n\t\t\t\ttransition: all 0.2s;\n\t\t\t\twhite-space: nowrap;\n\t\t\t}\n\n\t\t\t.nav-tab:hover {\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t\tbackground: rgba(255, 255, 255, 0.05);\n\t\t\t}\n\n\t\t\t.nav-tab.active {\n\t\t\t\tcolor: var(--primary);\n\t\t\t\tborder-bottom-color: var(--primary);\n\t\t\t}\n\n\t\t\t/* Main Container */\n\t\t\t.container {\n\t\t\t\tmax-width: 1600px;\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tpadding: 2rem;\n\t\t\t}\n\n\t\t\t.tab-content {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\n\t\t\t.tab-content.active {\n\t\t\t\tdisplay: block;\n\t\t\t\tanimation: fadeIn 0.3s;\n\t\t\t}\n\n\t\t\t@keyframes fadeIn {\n\t\t\t\tfrom { opacity: 0; transform: translateY(10px); }\n\t\t\t\tto { opacity: 1; transform: translateY(0); }\n\t\t\t}\n\n\t\t\t/* Search and Filters */\n\t\t\t.controls {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tpadding: 1.5rem;\n\t\t\t\tmargin-bottom: 1.5rem;\n\t\t\t}\n\n\t\t\t.search-box {\n\t\t\t\tdisplay: flex;\n\t\t\t\tgap: 1rem;\n\t\t\t\tmargin-bottom: 1rem;\n\t\t\t}\n\n\t\t\t.search-input {\n\t\t\t\tflex: 1;\n\t\t\t\tpadding: 0.75rem 1rem;\n\t\t\t\tbackground: var(--bg-tertiary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 6px;\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t}\n\n\t\t\t.search-input:focus {\n\t\t\t\toutline: none;\n\t\t\t\tborder-color: var(--primary);\n\t\t\t\tbox-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n\t\t\t}\n\n\t\t\t.filter-buttons {\n\t\t\t\tdisplay: flex;\n\t\t\t\tgap: 0.5rem;\n\t\t\t\tflex-wrap: wrap;\n\t\t\t}\n\n\t\t\t.filter-btn {\n\t\t\t\tpadding: 0.5rem 1rem;\n\t\t\t\tbackground: var(--bg-tertiary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 6px;\n\t\t\t\tcolor: var(--text-secondary);\n\t\t\t\tfont-size: 0.75rem;\n\t\t\t\tcursor: pointer;\n\t\t\t\ttransition: all 0.2s;\n\t\t\t}\n\n\t\t\t.filter-btn:hover {\n\t\t\t\tbackground: var(--bg-primary);\n\t\t\t\tborder-color: var(--primary);\n\t\t\t}\n\n\t\t\t.filter-btn.active {\n\t\t\t\tbackground: var(--primary);\n\t\t\t\tcolor: white;\n\t\t\t\tborder-color: var(--primary);\n\t\t\t}\n\n\t\t\t/* Cards */\n\t\t\t.card-grid {\n\t\t\t\tdisplay: grid;\n\t\t\t\tgrid-template-columns: repeat(auto-fill, minmax(350px, 1fr));\n\t\t\t\tgap: 1.5rem;\n\t\t\t\tmargin-bottom: 2rem;\n\t\t\t}\n\n\t\t\t.card {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tpadding: 1.5rem;\n\t\t\t\ttransition: all 0.2s;\n\t\t\t\tcursor: pointer;\n\t\t\t}\n\n\t\t\t.card:hover {\n\t\t\t\tborder-color: var(--primary);\n\t\t\t\tbox-shadow: 0 4px 12px var(--shadow);\n\t\t\t\ttransform: translateY(-2px);\n\t\t\t}\n\n\t\t\t.card-header {\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: space-between;\n\t\t\t\talign-items: start;\n\t\t\t\tmargin-bottom: 1rem;\n\t\t\t}\n\n\t\t\t.card-title {\n\t\t\t\tfont-size: 1.125rem;\n\t\t\t\tfont-weight: 600;\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t\tword-break: break-word;\n\t\t\t}\n\n\t\t\t.badge {\n\t\t\t\tpadding: 0.25rem 0.75rem;\n\t\t\t\tborder-radius: 12px;\n\t\t\t\tfont-size: 0.75rem;\n\t\t\t\tfont-weight: 600;\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\twhite-space: nowrap;\n\t\t\t}\n\n\t\t\t.badge-get { background: #10b981; color: white; }\n\t\t\t.badge-post { background: #3b82f6; color: white; }\n\t\t\t.badge-put { background: #f59e0b; color: white; }\n\t\t\t.badge-delete { background: #ef4444; color: white; }\n\t\t\t.badge-patch { background: #8b5cf6; color: white; }\n\t\t\t.badge-secure { background: #dc2626; color: white; }\n\t\t\t.badge-internal { background: #3b82f6; color: white; }\n\t\t\t.badge-external { background: #8b5cf6; color: white; }\n\n\t\t\t.card-description {\n\t\t\t\tcolor: var(--text-secondary);\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tmargin-bottom: 1rem;\n\t\t\t\tline-height: 1.5;\n\t\t\t}\n\n\t\t\t.card-meta {\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-wrap: wrap;\n\t\t\t\tgap: 1rem;\n\t\t\t\tfont-size: 0.75rem;\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t}\n\n\t\t\t.card-meta-item {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tgap: 0.5rem;\n\t\t\t}\n\n\t\t\t.card-path {\n\t\t\t\tbackground: var(--code-bg);\n\t\t\t\tpadding: 0.5rem;\n\t\t\t\tborder-radius: 4px;\n\t\t\t\tfont-family: 'Courier New', monospace;\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tword-break: break-all;\n\t\t\t\tmargin-top: 0.5rem;\n\t\t\t}\n\n\t\t\t/* Table */\n\t\t\t.table-container {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\toverflow: hidden;\n\t\t\t}\n\n\t\t\ttable {\n\t\t\t\twidth: 100%;\n\t\t\t\tborder-collapse: collapse;\n\t\t\t}\n\n\t\t\tthead {\n\t\t\t\tbackground: var(--bg-tertiary);\n\t\t\t}\n\n\t\t\tth {\n\t\t\t\tpadding: 1rem;\n\t\t\t\ttext-align: left;\n\t\t\t\tfont-weight: 600;\n\t\t\t\tfont-size: 0.75rem;\n\t\t\t\tcolor: var(--text-secondary);\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tletter-spacing: 0.05em;\n\t\t\t\tborder-bottom: 1px solid var(--border);\n\t\t\t}\n\n\t\t\ttd {\n\t\t\t\tpadding: 1rem;\n\t\t\t\tborder-bottom: 1px solid var(--border);\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t}\n\n\t\t\ttbody tr {\n\t\t\t\ttransition: background 0.2s;\n\t\t\t}\n\n\t\t\ttbody tr:hover {\n\t\t\t\tbackground: var(--bg-tertiary);\n\t\t\t}\n\n\t\t\t/* Code Block */\n\t\t\t.code-block {\n\t\t\t\tbackground: var(--code-bg);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tpadding: 1rem;\n\t\t\t\toverflow-x: auto;\n\t\t\t\tfont-family: 'Courier New', monospace;\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tline-height: 1.6;\n\t\t\t}\n\n\t\t\t/* Logs */\n\t\t\t.log-container {\n\t\t\t\tbackground: var(--code-bg);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tmax-height: 600px;\n\t\t\t\toverflow-y: auto;\n\t\t\t}\n\n\t\t\t.log-entry {\n\t\t\t\tpadding: 0.75rem 1rem;\n\t\t\t\tborder-bottom: 1px solid var(--border);\n\t\t\t\tfont-family: 'Courier New', monospace;\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\twhite-space: pre-wrap;\n\t\t\t\tword-break: break-word;\n\t\t\t}\n\n\t\t\t.log-entry:last-child {\n\t\t\t\tborder-bottom: none;\n\t\t\t}\n\n\t\t\t.log-error { background: rgba(239, 68, 68, 0.1); color: #fca5a5; }\n\t\t\t.log-warn { background: rgba(245, 158, 11, 0.1); color: #fcd34d; }\n\t\t\t.log-info { background: rgba(59, 130, 246, 0.1); color: #93c5fd; }\n\t\t\t.log-debug { background: rgba(156, 163, 175, 0.1); color: #d1d5db; }\n\n\t\t\t/* Empty State */\n\t\t\t.empty-state {\n\t\t\t\ttext-align: center;\n\t\t\t\tpadding: 4rem 2rem;\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t}\n\n\t\t\t.empty-icon {\n\t\t\t\tfont-size: 4rem;\n\t\t\t\tmargin-bottom: 1rem;\n\t\t\t\topacity: 0.3;\n\t\t\t}\n\n\t\t\t/* Detail View */\n\t\t\t.detail-section {\n\t\t\t\tbackground: var(--bg-secondary);\n\t\t\t\tborder: 1px solid var(--border);\n\t\t\t\tborder-radius: 8px;\n\t\t\t\tpadding: 1.5rem;\n\t\t\t\tmargin-bottom: 1.5rem;\n\t\t\t}\n\n\t\t\t.detail-title {\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tfont-weight: 600;\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t\ttext-transform: uppercase;\n\t\t\t\tletter-spacing: 0.05em;\n\t\t\t\tmargin-bottom: 1rem;\n\t\t\t}\n\n\t\t\t.property-list {\n\t\t\t\tdisplay: grid;\n\t\t\t\tgap: 0.75rem;\n\t\t\t}\n\n\t\t\t.property {\n\t\t\t\tdisplay: grid;\n\t\t\t\tgrid-template-columns: 150px 1fr;\n\t\t\t\tgap: 1rem;\n\t\t\t}\n\n\t\t\t.property-key {\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t}\n\n\t\t\t.property-value {\n\t\t\t\tcolor: var(--text-primary);\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t\tword-break: break-word;\n\t\t\t}\n\n\t\t\t.property-value code {\n\t\t\t\tbackground: var(--code-bg);\n\t\t\t\tpadding: 0.125rem 0.5rem;\n\t\t\t\tborder-radius: 4px;\n\t\t\t\tfont-family: 'Courier New', monospace;\n\t\t\t}\n\n\t\t\t/* Loading */\n\t\t\t.loading {\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: center;\n\t\t\t\talign-items: center;\n\t\t\t\tpadding: 4rem;\n\t\t\t}\n\n\t\t\t.spinner {\n\t\t\t\twidth: 40px;\n\t\t\t\theight: 40px;\n\t\t\t\tborder: 3px solid var(--border);\n\t\t\t\tborder-top-color: var(--primary);\n\t\t\t\tborder-radius: 50%;\n\t\t\t\tanimation: spin 0.8s linear infinite;\n\t\t\t}\n\n\t\t\t@keyframes spin {\n\t\t\t\tto { transform: rotate(360deg); }\n\t\t\t}\n\n\t\t\t/* Utility */\n\t\t\t.hidden {\n\t\t\t\tdisplay: none !important;\n\t\t\t}\n\n\t\t\t.text-muted {\n\t\t\t\tcolor: var(--text-muted);\n\t\t\t}\n\n\t\t\t.text-code {\n\t\t\t\tfont-family: 'Courier New', monospace;\n\t\t\t\tbackground: var(--code-bg);\n\t\t\t\tpadding: 0.125rem 0.5rem;\n\t\t\t\tborder-radius: 4px;\n\t\t\t\tfont-size: 0.875rem;\n\t\t\t}\n\n\t\t\t/* Scrollbar */\n\t\t\t::-webkit-scrollbar {\n\t\t\t\twidth: 8px;\n\t\t\t\theight: 8px;\n\t\t\t}\n\n\t\t\t::-webkit-scrollbar-track {\n\t\t\t\tbackground: var(--bg-primary);\n\t\t\t}\n\n\t\t\t::-webkit-scrollbar-thumb {\n\t\t\t\tbackground: var(--border);\n\t\t\t\tborder-radius: 4px;\n\t\t\t}\n\n\t\t\t::-webkit-scrollbar-thumb:hover {\n\t\t\t\tbackground: var(--text-muted);\n\t\t\t}\n\n\t\t\t/* Responsive */\n\t\t\t@media (max-width: 768px) {\n\t\t\t\t.header-stats {\n\t\t\t\t\tdisplay: none;\n\t\t\t\t}\n\n\t\t\t\t.card-grid {\n\t\t\t\t\tgrid-template-columns: 1fr;\n\t\t\t\t}\n\n\t\t\t\t.property {\n\t\t\t\t\tgrid-template-columns: 1fr;\n\t\t\t\t\tgap: 0.25rem;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n</head>\n<body>\n\t\t<!-- Header -->\n\t\t<div class=\"header\">\n\t\t\t<div class=\"header-content\">\n\t\t\t\t<div class=\"logo\">⚡ Alepha DevTools</div>\n\t\t\t\t<div class=\"header-stats\">\n\t\t\t\t\t<div class=\"stat\">\n\t\t\t\t\t\t<div class=\"stat-value\" id=\"stat-actions\">0</div>\n\t\t\t\t\t\t<div class=\"stat-label\">Actions</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"stat\">\n\t\t\t\t\t\t<div class=\"stat-value\" id=\"stat-pages\">0</div>\n\t\t\t\t\t\t<div class=\"stat-label\">Pages</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"stat\">\n\t\t\t\t\t\t<div class=\"stat-value\" id=\"stat-modules\">0</div>\n\t\t\t\t\t\t<div class=\"stat-label\">Modules</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"stat\">\n\t\t\t\t\t\t<div class=\"stat-value\" id=\"stat-providers\">0</div>\n\t\t\t\t\t\t<div class=\"stat-label\">Providers</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- Navigation -->\n\t\t<div class=\"nav\">\n\t\t\t<div class=\"nav-container\">\n\t\t\t\t<button class=\"nav-tab active\" data-tab=\"overview\">Overview</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"actions\">Actions</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"pages\">Pages</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"queues\">Queues</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"schedulers\">Schedulers</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"topics\">Topics</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"buckets\">Buckets</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"caches\">Caches</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"realms\">Realms</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"providers\">Providers</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"modules\">Modules</button>\n\t\t\t\t<button class=\"nav-tab\" data-tab=\"logs\">Logs</button>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- Main Container -->\n\t\t<div class=\"container\">\n\t\t\t<!-- Overview Tab -->\n\t\t\t<div class=\"tab-content active\" id=\"tab-overview\">\n\t\t\t\t<div class=\"detail-section\">\n\t\t\t\t\t<h2 class=\"detail-title\">System Overview</h2>\n\t\t\t\t\t<div id=\"overview-content\" class=\"loading\">\n\t\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Actions Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-actions\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-actions\" placeholder=\"Search actions by name, path, or group...\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"filter-buttons\" id=\"filter-actions-methods\"></div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"actions-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Pages Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-pages\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-pages\" placeholder=\"Search pages by name or path...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"pages-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Queues Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-queues\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-queues\" placeholder=\"Search queues...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"queues-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Schedulers Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-schedulers\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-schedulers\" placeholder=\"Search schedulers...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"schedulers-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Topics Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-topics\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-topics\" placeholder=\"Search topics...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"topics-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Buckets Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-buckets\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-buckets\" placeholder=\"Search buckets...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"buckets-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Caches Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-caches\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-caches\" placeholder=\"Search caches...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"caches-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Realms Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-realms\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-realms\" placeholder=\"Search realms...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"realms-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Providers Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-providers\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-providers\" placeholder=\"Search providers...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"providers-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Modules Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-modules\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-modules\" placeholder=\"Search modules...\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"modules-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Logs Tab -->\n\t\t\t<div class=\"tab-content\" id=\"tab-logs\">\n\t\t\t\t<div class=\"controls\">\n\t\t\t\t\t<div class=\"search-box\">\n\t\t\t\t\t\t<input type=\"text\" class=\"search-input\" id=\"search-logs\" placeholder=\"Search logs...\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"filter-buttons\">\n\t\t\t\t\t\t<button class=\"filter-btn active\" data-level=\"all\">All</button>\n\t\t\t\t\t\t<button class=\"filter-btn\" data-level=\"error\">Errors</button>\n\t\t\t\t\t\t<button class=\"filter-btn\" data-level=\"warn\">Warnings</button>\n\t\t\t\t\t\t<button class=\"filter-btn\" data-level=\"info\">Info</button>\n\t\t\t\t\t\t<button class=\"filter-btn\" data-level=\"debug\">Debug</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"logs-content\" class=\"loading\">\n\t\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<script>\n\t\t\tlet metadata = null;\n\t\t\tlet activeFilters = {\n\t\t\t\tactions: { methods: new Set() },\n\t\t\t\tlogs: { level: 'all' }\n\t\t\t};\n\n\t\t\t// Tab Navigation\n\t\t\tdocument.querySelectorAll('.nav-tab').forEach(tab => {\n\t\t\t\ttab.addEventListener('click', () => {\n\t\t\t\t\tconst tabName = tab.dataset.tab;\n\t\t\t\t\tdocument.querySelectorAll('.nav-tab').forEach(t => t.classList.remove('active'));\n\t\t\t\t\tdocument.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));\n\t\t\t\t\ttab.classList.add('active');\n\t\t\t\t\tdocument.getElementById(\\`tab-\\${tabName}\\`).classList.add('active');\n\t\t\t\t\trenderTab(tabName);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// Utility Functions\n\t\t\tfunction escapeHtml(text) {\n\t\t\t\tconst div = document.createElement('div');\n\t\t\t\tdiv.textContent = text;\n\t\t\t\treturn div.innerHTML;\n\t\t\t}\n\n\t\t\tfunction formatJson(obj) {\n\t\t\t\treturn JSON.stringify(obj, null, 2);\n\t\t\t}\n\n\t\t\tfunction getLogLevel(formatted) {\n\t\t\t\tconst lower = formatted.toLowerCase();\n\t\t\t\tif (lower.includes('error')) return 'error';\n\t\t\t\tif (lower.includes('warn')) return 'warn';\n\t\t\t\tif (lower.includes('info')) return 'info';\n\t\t\t\treturn 'debug';\n\t\t\t}\n\n\t\t\t// Search Functions\n\t\t\tfunction setupSearch(inputId, renderFn) {\n\t\t\t\tconst input = document.getElementById(inputId);\n\t\t\t\tif (!input) return;\n\n\t\t\t\tlet debounceTimer;\n\t\t\t\tinput.addEventListener('input', () => {\n\t\t\t\t\tclearTimeout(debounceTimer);\n\t\t\t\t\tdebounceTimer = setTimeout(renderFn, 300);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction matchesSearch(item, searchTerm, fields) {\n\t\t\t\tif (!searchTerm) return true;\n\t\t\t\tconst term = searchTerm.toLowerCase();\n\t\t\t\treturn fields.some(field => {\n\t\t\t\t\tconst value = field.split('.').reduce((obj, key) => obj?.[key], item);\n\t\t\t\t\treturn value && String(value).toLowerCase().includes(term);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Render Functions\n\t\t\tfunction renderOverview() {\n\t\t\t\tif (!metadata) return;\n\n\t\t\t\tconst content = document.getElementById('overview-content');\n\t\t\t\tconst stats = {\n\t\t\t\t\t'Total Actions': metadata.actions?.length || 0,\n\t\t\t\t\t'Total Pages': metadata.pages?.length || 0,\n\t\t\t\t\t'Total Queues': metadata.queues?.length || 0,\n\t\t\t\t\t'Total Schedulers': metadata.schedulers?.length || 0,\n\t\t\t\t\t'Total Topics': metadata.topics?.length || 0,\n\t\t\t\t\t'Total Buckets': metadata.buckets?.length || 0,\n\t\t\t\t\t'Total Caches': metadata.caches?.length || 0,\n\t\t\t\t\t'Total Realms': metadata.realms?.length || 0,\n\t\t\t\t\t'Total Providers': metadata.providers?.length || 0,\n\t\t\t\t\t'Total Modules': metadata.modules?.length || 0,\n\t\t\t\t\t'Log Entries': metadata.logs?.length || 0,\n\t\t\t\t};\n\n\t\t\t\tconst methodCounts = {};\n\t\t\t\tmetadata.actions?.forEach(action => {\n\t\t\t\t\tmethodCounts[action.method] = (methodCounts[action.method] || 0) + 1;\n\t\t\t\t});\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div style=\"display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 2rem;\">\n\t\t\t\t\t\t\\${Object.entries(stats).map(([key, value]) => \\`\n\t\t\t\t\t\t\t<div style=\"background: var(--bg-tertiary); padding: 1.5rem; border-radius: 8px; text-align: center;\">\n\t\t\t\t\t\t\t\t<div style=\"font-size: 2rem; font-weight: 700; color: var(--primary);\">\\${value}</div>\n\t\t\t\t\t\t\t\t<div style=\"font-size: 0.875rem; color: var(--text-muted); margin-top: 0.5rem;\">\\${escapeHtml(key)}</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t\\${Object.keys(methodCounts).length > 0 ? \\`\n\t\t\t\t\t\t<div class=\"detail-section\">\n\t\t\t\t\t\t\t<h3 class=\"detail-title\">HTTP Methods Distribution</h3>\n\t\t\t\t\t\t\t<div style=\"display: flex; gap: 1rem; flex-wrap: wrap;\">\n\t\t\t\t\t\t\t\t\\${Object.entries(methodCounts).map(([method, count]) => \\`\n\t\t\t\t\t\t\t\t\t<div class=\"badge badge-\\${method.toLowerCase()}\">\\${method}: \\${count}</div>\n\t\t\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\\` : ''}\n\n\t\t\t\t\t<div class=\"detail-section\">\n\t\t\t\t\t\t<h3 class=\"detail-title\">Raw Metadata</h3>\n\t\t\t\t\t\t<div class=\"code-block\">\\${escapeHtml(formatJson(metadata))}</div>\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderActions() {\n\t\t\t\tif (!metadata?.actions) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-actions')?.value || '';\n\t\t\t\tconst filteredActions = metadata.actions.filter(action => {\n\t\t\t\t\tconst matchesMethod = activeFilters.actions.methods.size === 0 ||\n\t\t\t\t\t\tactiveFilters.actions.methods.has(action.method);\n\t\t\t\t\tconst matchesSearchTerm = matchesSearch(action, searchTerm, ['name', 'path', 'group', 'fullPath']);\n\t\t\t\t\treturn matchesMethod && matchesSearchTerm;\n\t\t\t\t});\n\n\t\t\t\tconst content = document.getElementById('actions-content');\n\n\t\t\t\tif (filteredActions.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t\t<div class=\"empty-state\">\n\t\t\t\t\t\t\t<div class=\"empty-icon\">🔍</div>\n\t\t\t\t\t\t\t<div>No actions found</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredActions.map(action => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(action.name)}</div>\n\t\t\t\t\t\t\t\t\t<div style=\"display: flex; gap: 0.5rem; flex-wrap: wrap;\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"badge badge-\\${action.method.toLowerCase()}\">\\${action.method}</span>\n\t\t\t\t\t\t\t\t\t\t\\${action.secure ? '<span class=\"badge badge-secure\">🔒 Secure</span>' : ''}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${action.description ? \\`<div class=\"card-description\">\\${escapeHtml(action.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t<div class=\"card-path\">\\${escapeHtml(action.fullPath)}</div>\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-meta-item\">\n\t\t\t\t\t\t\t\t\t\t<span>📁</span>\n\t\t\t\t\t\t\t\t\t\t<span>\\${escapeHtml(action.group)}</span>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\\${action.disabled ? '<div class=\"card-meta-item\"><span>⚠️</span><span>Disabled</span></div>' : ''}\n\t\t\t\t\t\t\t\t\t\\${action.hide ? '<div class=\"card-meta-item\"><span>👁️</span><span>Hidden</span></div>' : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderPages() {\n\t\t\t\tif (!metadata?.pages) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-pages')?.value || '';\n\t\t\t\tconst filteredPages = metadata.pages.filter(page =>\n\t\t\t\t\tmatchesSearch(page, searchTerm, ['name', 'path'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('pages-content');\n\n\t\t\t\tif (filteredPages.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No pages found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredPages.map(page => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(page.name)}</div>\n\t\t\t\t\t\t\t\t\t\\${page.static ? '<span class=\"badge\" style=\"background: var(--success);\">Static</span>' : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${page.description ? \\`<div class=\"card-description\">\\${escapeHtml(page.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t\\${page.path ? \\`<div class=\"card-path\">\\${escapeHtml(page.path)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t\\${page.hasComponent ? '<div class=\"card-meta-item\"><span>✓</span><span>Component</span></div>' : ''}\n\t\t\t\t\t\t\t\t\t\\${page.hasLazy ? '<div class=\"card-meta-item\"><span>⚡</span><span>Lazy</span></div>' : ''}\n\t\t\t\t\t\t\t\t\t\\${page.hasResolve ? '<div class=\"card-meta-item\"><span>🔄</span><span>Resolve</span></div>' : ''}\n\t\t\t\t\t\t\t\t\t\\${page.hasChildren ? '<div class=\"card-meta-item\"><span>👶</span><span>Children</span></div>' : ''}\n\t\t\t\t\t\t\t\t\t\\${page.hasErrorHandler ? '<div class=\"card-meta-item\"><span>⚠️</span><span>Error Handler</span></div>' : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderQueues() {\n\t\t\t\tif (!metadata?.queues) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-queues')?.value || '';\n\t\t\t\tconst filteredQueues = metadata.queues.filter(queue =>\n\t\t\t\t\tmatchesSearch(queue, searchTerm, ['name', 'provider'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('queues-content');\n\n\t\t\t\tif (filteredQueues.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No queues found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredQueues.map(queue => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(queue.name)}</div>\n\t\t\t\t\t\t\t\t\t<span class=\"badge\" style=\"background: var(--primary);\">\\${escapeHtml(queue.provider)}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${queue.description ? \\`<div class=\"card-description\">\\${escapeHtml(queue.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t\\${queue.schema ? \\`<div class=\"detail-section\" style=\"margin-top: 1rem;\"><div class=\"detail-title\">Schema</div><div class=\"code-block\">\\${escapeHtml(formatJson(queue.schema))}</div></div>\\` : ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderSchedulers() {\n\t\t\t\tif (!metadata?.schedulers) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-schedulers')?.value || '';\n\t\t\t\tconst filteredSchedulers = metadata.schedulers.filter(scheduler =>\n\t\t\t\t\tmatchesSearch(scheduler, searchTerm, ['name', 'cron'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('schedulers-content');\n\n\t\t\t\tif (filteredSchedulers.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No schedulers found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredSchedulers.map(scheduler => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(scheduler.name)}</div>\n\t\t\t\t\t\t\t\t\t\\${scheduler.lock ? '<span class=\"badge\" style=\"background: var(--warning);\">🔒 Locked</span>' : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${scheduler.description ? \\`<div class=\"card-description\">\\${escapeHtml(scheduler.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t\\${scheduler.cron ? \\`<div class=\"card-meta-item\"><span>⏰</span><span class=\"text-code\">\\${escapeHtml(scheduler.cron)}</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\\${scheduler.interval ? \\`<div class=\"card-meta-item\"><span>🔄</span><span>\\${JSON.stringify(scheduler.interval)}</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderTopics() {\n\t\t\t\tif (!metadata?.topics) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-topics')?.value || '';\n\t\t\t\tconst filteredTopics = metadata.topics.filter(topic =>\n\t\t\t\t\tmatchesSearch(topic, searchTerm, ['name', 'provider'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('topics-content');\n\n\t\t\t\tif (filteredTopics.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No topics found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredTopics.map(topic => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(topic.name)}</div>\n\t\t\t\t\t\t\t\t\t<span class=\"badge\" style=\"background: var(--primary);\">\\${escapeHtml(topic.provider)}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${topic.description ? \\`<div class=\"card-description\">\\${escapeHtml(topic.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t\\${topic.schema ? \\`<div class=\"detail-section\" style=\"margin-top: 1rem;\"><div class=\"detail-title\">Schema</div><div class=\"code-block\">\\${escapeHtml(formatJson(topic.schema))}</div></div>\\` : ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderBuckets() {\n\t\t\t\tif (!metadata?.buckets) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-buckets')?.value || '';\n\t\t\t\tconst filteredBuckets = metadata.buckets.filter(bucket =>\n\t\t\t\t\tmatchesSearch(bucket, searchTerm, ['name', 'provider'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('buckets-content');\n\n\t\t\t\tif (filteredBuckets.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No buckets found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredBuckets.map(bucket => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(bucket.name)}</div>\n\t\t\t\t\t\t\t\t\t<span class=\"badge\" style=\"background: var(--primary);\">\\${escapeHtml(bucket.provider)}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${bucket.description ? \\`<div class=\"card-description\">\\${escapeHtml(bucket.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t\\${bucket.maxSize ? \\`<div class=\"card-meta-item\"><span>📦</span><span>Max: \\${bucket.maxSize} bytes</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\\${bucket.mimeTypes?.length ? \\`<div class=\"card-meta-item\"><span>📄</span><span>\\${bucket.mimeTypes.length} mime types</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderCaches() {\n\t\t\t\tif (!metadata?.caches) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-caches')?.value || '';\n\t\t\t\tconst filteredCaches = metadata.caches.filter(cache =>\n\t\t\t\t\tmatchesSearch(cache, searchTerm, ['name', 'provider'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('caches-content');\n\n\t\t\t\tif (filteredCaches.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No caches found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredCaches.map(cache => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(cache.name)}</div>\n\t\t\t\t\t\t\t\t\t<div style=\"display: flex; gap: 0.5rem;\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"badge\" style=\"background: var(--primary);\">\\${escapeHtml(cache.provider)}</span>\n\t\t\t\t\t\t\t\t\t\t\\${cache.disabled ? '<span class=\"badge\" style=\"background: var(--danger);\">Disabled</span>' : ''}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t\\${cache.ttl ? \\`<div class=\"card-meta-item\"><span>⏱️</span><span>TTL: \\${JSON.stringify(cache.ttl)}</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderRealms() {\n\t\t\t\tif (!metadata?.realms) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-realms')?.value || '';\n\t\t\t\tconst filteredRealms = metadata.realms.filter(realm =>\n\t\t\t\t\tmatchesSearch(realm, searchTerm, ['name', 'type'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('realms-content');\n\n\t\t\t\tif (filteredRealms.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No realms found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredRealms.map(realm => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(realm.name)}</div>\n\t\t\t\t\t\t\t\t\t<span class=\"badge badge-\\${realm.type}\">\\${escapeHtml(realm.type)}</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${realm.description ? \\`<div class=\"card-description\">\\${escapeHtml(realm.description)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t\\${realm.roles?.length ? \\`<div class=\"card-meta\"><div class=\"card-meta-item\"><span>👥</span><span>\\${realm.roles.length} roles</span></div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\\${realm.settings ? \\`\n\t\t\t\t\t\t\t\t\t<div class=\"detail-section\" style=\"margin-top: 1rem;\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"detail-title\">Settings</div>\n\t\t\t\t\t\t\t\t\t\t<div class=\"property-list\">\n\t\t\t\t\t\t\t\t\t\t\t\\${realm.settings.accessTokenExpiration ? \\`<div class=\"property\"><div class=\"property-key\">Access Token</div><div class=\"property-value\">\\${JSON.stringify(realm.settings.accessTokenExpiration)}</div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\t\t\\${realm.settings.refreshTokenExpiration ? \\`<div class=\"property\"><div class=\"property-key\">Refresh Token</div><div class=\"property-value\">\\${JSON.stringify(realm.settings.refreshTokenExpiration)}</div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\t\t\\${realm.settings.hasOnCreateSession ? \\`<div class=\"property\"><div class=\"property-key\">On Create</div><div class=\"property-value\">✓</div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\t\t\\${realm.settings.hasOnRefreshSession ? \\`<div class=\"property\"><div class=\"property-key\">On Refresh</div><div class=\"property-value\">✓</div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\t\t\\${realm.settings.hasOnDeleteSession ? \\`<div class=\"property\"><div class=\"property-key\">On Delete</div><div class=\"property-value\">✓</div></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\` : ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderProviders() {\n\t\t\t\tif (!metadata?.providers) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-providers')?.value || '';\n\t\t\t\tconst filteredProviders = metadata.providers.filter(provider =>\n\t\t\t\t\tmatchesSearch(provider, searchTerm, ['name', 'module'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('providers-content');\n\n\t\t\t\tif (filteredProviders.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No providers found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredProviders.map(provider => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(provider.name)}</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${provider.module ? \\`<div class=\"card-description\">📦 \\${escapeHtml(provider.module)}</div>\\` : ''}\n\t\t\t\t\t\t\t\t<div class=\"card-meta\">\n\t\t\t\t\t\t\t\t\t\\${provider.dependencies?.length ? \\`<div class=\"card-meta-item\"><span>🔗</span><span>\\${provider.dependencies.length} dependencies</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t\t\\${provider.aliases?.length ? \\`<div class=\"card-meta-item\"><span>🏷️</span><span>\\${provider.aliases.length} aliases</span></div>\\` : ''}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${provider.dependencies?.length ? \\`\n\t\t\t\t\t\t\t\t\t<div class=\"detail-section\" style=\"margin-top: 1rem;\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"detail-title\">Dependencies</div>\n\t\t\t\t\t\t\t\t\t\t<div style=\"display: flex; flex-wrap: wrap; gap: 0.5rem;\">\n\t\t\t\t\t\t\t\t\t\t\t\\${provider.dependencies.map(dep => \\`<span class=\"text-code\">\\${escapeHtml(dep)}</span>\\`).join('')}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\` : ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderModules() {\n\t\t\t\tif (!metadata?.modules) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-modules')?.value || '';\n\t\t\t\tconst filteredModules = metadata.modules.filter(module =>\n\t\t\t\t\tmatchesSearch(module, searchTerm, ['name'])\n\t\t\t\t);\n\n\t\t\t\tconst content = document.getElementById('modules-content');\n\n\t\t\t\tif (filteredModules.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No modules found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"card-grid\">\n\t\t\t\t\t\t\\${filteredModules.map(module => \\`\n\t\t\t\t\t\t\t<div class=\"card\">\n\t\t\t\t\t\t\t\t<div class=\"card-header\">\n\t\t\t\t\t\t\t\t\t<div class=\"card-title\">\\${escapeHtml(module.name)}</div>\n\t\t\t\t\t\t\t\t\t<span class=\"badge\" style=\"background: var(--success);\">\\${module.providers?.length || 0} providers</span>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\${module.providers?.length ? \\`\n\t\t\t\t\t\t\t\t\t<div class=\"detail-section\" style=\"margin-top: 1rem;\">\n\t\t\t\t\t\t\t\t\t\t<div class=\"detail-title\">Providers</div>\n\t\t\t\t\t\t\t\t\t\t<div style=\"display: flex; flex-wrap: wrap; gap: 0.5rem;\">\n\t\t\t\t\t\t\t\t\t\t\t\\${module.providers.map(prov => \\`<span class=\"text-code\">\\${escapeHtml(prov)}</span>\\`).join('')}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\\` : ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderLogs() {\n\t\t\t\tif (!metadata?.logs) return;\n\n\t\t\t\tconst searchTerm = document.getElementById('search-logs')?.value || '';\n\t\t\t\tconst level = activeFilters.logs.level;\n\n\t\t\t\tconst filteredLogs = metadata.logs.filter(log => {\n\t\t\t\t\tconst matchesLevel = level === 'all' || getLogLevel(log.formatted) === level;\n\t\t\t\t\tconst matchesSearchTerm = !searchTerm || log.formatted.toLowerCase().includes(searchTerm.toLowerCase());\n\t\t\t\t\treturn matchesLevel && matchesSearchTerm;\n\t\t\t\t});\n\n\t\t\t\tconst content = document.getElementById('logs-content');\n\n\t\t\t\tif (filteredLogs.length === 0) {\n\t\t\t\t\tcontent.innerHTML = \\`<div class=\"empty-state\"><div class=\"empty-icon\">📋</div><div>No logs found</div></div>\\`;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tcontent.innerHTML = \\`\n\t\t\t\t\t<div class=\"log-container\">\n\t\t\t\t\t\t\\${filteredLogs.map(log => {\n\t\t\t\t\t\t\tconst level = getLogLevel(log.formatted);\n\t\t\t\t\t\t\treturn \\`<div class=\"log-entry log-\\${level}\">\\${escapeHtml(log.formatted)}</div>\\`;\n\t\t\t\t\t\t}).join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\\`;\n\t\t\t}\n\n\t\t\tfunction renderTab(tabName) {\n\t\t\t\tif (!metadata) return;\n\n\t\t\t\tswitch(tabName) {\n\t\t\t\t\tcase 'overview': renderOverview(); break;\n\t\t\t\t\tcase 'actions': renderActions(); break;\n\t\t\t\t\tcase 'pages': renderPages(); break;\n\t\t\t\t\tcase 'queues': renderQueues(); break;\n\t\t\t\t\tcase 'schedulers': renderSchedulers(); break;\n\t\t\t\t\tcase 'topics': renderTopics(); break;\n\t\t\t\t\tcase 'buckets': renderBuckets(); break;\n\t\t\t\t\tcase 'caches': renderCaches(); break;\n\t\t\t\t\tcase 'realms': renderRealms(); break;\n\t\t\t\t\tcase 'providers': renderProviders(); break;\n\t\t\t\t\tcase 'modules': renderModules(); break;\n\t\t\t\t\tcase 'logs': renderLogs(); break;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Initialize\n\t\t\tasync function init() {\n\t\t\t\ttry {\n\t\t\t\t\tconst res = await fetch('/_devtools/metadata');\n\t\t\t\t\tmetadata = await res.json();\n\n\t\t\t\t\t// Update header stats\n\t\t\t\t\tdocument.getElementById('stat-actions').textContent = metadata.actions?.length || 0;\n\t\t\t\t\tdocument.getElementById('stat-pages').textContent = metadata.pages?.length || 0;\n\t\t\t\t\tdocument.getElementById('stat-modules').textContent = metadata.modules?.length || 0;\n\t\t\t\t\tdocument.getElementById('stat-providers').textContent = metadata.providers?.length || 0;\n\n\t\t\t\t\t// Setup method filters for actions\n\t\t\t\t\tconst methods = [...new Set(metadata.actions?.map(a => a.method) || [])];\n\t\t\t\t\tconst filterContainer = document.getElementById('filter-actions-methods');\n\t\t\t\t\tfilterContainer.innerHTML = methods.map(method =>\n\t\t\t\t\t\t\\`<button class=\"filter-btn\" data-method=\"\\${method}\">\\${method}</button>\\`\n\t\t\t\t\t).join('');\n\n\t\t\t\t\tfilterContainer.querySelectorAll('.filter-btn').forEach(btn => {\n\t\t\t\t\t\tbtn.addEventListener('click', () => {\n\t\t\t\t\t\t\tconst method = btn.dataset.method;\n\t\t\t\t\t\t\tif (activeFilters.actions.methods.has(method)) {\n\t\t\t\t\t\t\t\tactiveFilters.actions.methods.delete(method);\n\t\t\t\t\t\t\t\tbtn.classList.remove('active');\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tactiveFilters.actions.methods.add(method);\n\t\t\t\t\t\t\t\tbtn.classList.add('active');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trenderActions();\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\n\t\t\t\t\t// Setup log level filters\n\t\t\t\t\tdocument.querySelectorAll('[data-level]').forEach(btn => {\n\t\t\t\t\t\tbtn.addEventListener('click', () => {\n\t\t\t\t\t\t\tdocument.querySelectorAll('[data-level]').forEach(b => b.classList.remove('active'));\n\t\t\t\t\t\t\tbtn.classList.add('active');\n\t\t\t\t\t\t\tactiveFilters.logs.level = btn.dataset.level;\n\t\t\t\t\t\t\trenderLogs();\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\n\t\t\t\t\t// Setup search handlers\n\t\t\t\t\tsetupSearch('search-actions', renderActions);\n\t\t\t\t\tsetupSearch('search-pages', renderPages);\n\t\t\t\t\tsetupSearch('search-queues', renderQueues);\n\t\t\t\t\tsetupSearch('search-schedulers', renderSchedulers);\n\t\t\t\t\tsetupSearch('search-topics', renderTopics);\n\t\t\t\t\tsetupSearch('search-buckets', renderBuckets);\n\t\t\t\t\tsetupSearch('search-caches', renderCaches);\n\t\t\t\t\tsetupSearch('search-realms', renderRealms);\n\t\t\t\t\tsetupSearch('search-providers', renderProviders);\n\t\t\t\t\tsetupSearch('search-modules', renderModules);\n\t\t\t\t\tsetupSearch('search-logs', renderLogs);\n\n\t\t\t\t\t// Render initial tab\n\t\t\t\t\trenderTab('overview');\n\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('Failed to load metadata:', error);\n\t\t\t\t\tdocument.querySelectorAll('.loading').forEach(el => {\n\t\t\t\t\t\tel.innerHTML = \\`\n\t\t\t\t\t\t\t<div class=\"empty-state\">\n\t\t\t\t\t\t\t\t<div class=\"empty-icon\">⚠️</div>\n\t\t\t\t\t\t\t\t<div>Failed to load metadata</div>\n\t\t\t\t\t\t\t\t<div style=\"margin-top: 0.5rem; color: var(--text-muted);\">\\${escapeHtml(error.message)}</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\\`;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinit();\n\t\t</script>\n</body>\n</html>`;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devActionMetadataSchema = t.object({\n\tname: t.text(),\n\tgroup: t.text(),\n\tmethod: t.text(),\n\tpath: t.text(),\n\tprefix: t.text(),\n\tfullPath: t.text(),\n\tdescription: t.optional(t.text()),\n\tsummary: t.optional(t.text()),\n\tdisabled: t.optional(t.boolean()),\n\tsecure: t.optional(t.boolean()),\n\thide: t.optional(t.boolean()),\n\tbody: t.optional(t.any()),\n\tparams: t.optional(t.any()),\n\tquery: t.optional(t.any()),\n\tresponse: t.optional(t.any()),\n\tbodyContentType: t.optional(t.text()),\n});\n\nexport type DevActionMetadata = Static<typeof devActionMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devBucketMetadataSchema = t.object({\n\tname: t.text(),\n\tdescription: t.optional(t.text()),\n\tmimeTypes: t.optional(t.array(t.text())),\n\tmaxSize: t.optional(t.number()),\n\tprovider: t.text(),\n});\n\nexport type DevBucketMetadata = Static<typeof devBucketMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devCacheMetadataSchema = t.object({\n\tname: t.text(),\n\tttl: t.optional(t.any()),\n\tdisabled: t.optional(t.boolean()),\n\tprovider: t.text(),\n});\n\nexport type DevCacheMetadata = Static<typeof devCacheMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devModuleMetadataSchema = t.object({\n\tname: t.text(),\n\tproviders: t.array(t.text()),\n});\n\nexport type DevModuleMetadata = Static<typeof devModuleMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devPageMetadataSchema = t.object({\n\tname: t.text(),\n\tdescription: t.optional(t.text()),\n\tpath: t.optional(t.text()),\n\tparams: t.optional(t.any()),\n\tquery: t.optional(t.any()),\n\thasComponent: t.boolean(),\n\thasLazy: t.boolean(),\n\thasResolve: t.boolean(),\n\thasChildren: t.boolean(),\n\thasParent: t.boolean(),\n\thasErrorHandler: t.boolean(),\n\tstatic: t.optional(t.boolean()),\n\tcache: t.optional(t.any()),\n\tclient: t.optional(t.any()),\n\tanimation: t.optional(t.any()),\n});\n\nexport type DevPageMetadata = Static<typeof devPageMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devProviderMetadataSchema = t.object({\n\tname: t.text(),\n\tmodule: t.optional(t.text()),\n\tdependencies: t.array(t.text()),\n\taliases: t.optional(t.array(t.text())),\n});\n\nexport type DevProviderMetadata = Static<typeof devProviderMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devQueueMetadataSchema = t.object({\n\tname: t.text(),\n\tdescription: t.optional(t.text()),\n\tschema: t.optional(t.any()),\n\tprovider: t.text(),\n});\n\nexport type DevQueueMetadata = Static<typeof devQueueMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devRealmMetadataSchema = t.object({\n\tname: t.text(),\n\tdescription: t.optional(t.text()),\n\troles: t.optional(t.array(t.any())),\n\ttype: t.enum([\"internal\", \"external\"]),\n\tsettings: t.optional(\n\t\tt.object({\n\t\t\taccessTokenExpiration: t.optional(t.any()),\n\t\t\trefreshTokenExpiration: t.optional(t.any()),\n\t\t\thasOnCreateSession: t.boolean(),\n\t\t\thasOnRefreshSession: t.boolean(),\n\t\t\thasOnDeleteSession: t.boolean(),\n\t\t}),\n\t),\n});\n\nexport type DevRealmMetadata = Static<typeof devRealmMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devSchedulerMetadataSchema = t.object({\n\tname: t.text(),\n\tdescription: t.optional(t.text()),\n\tcron: t.optional(t.text()),\n\tinterval: t.optional(t.any()),\n\tlock: t.optional(t.boolean()),\n});\n\nexport type DevSchedulerMetadata = Static<typeof devSchedulerMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\n\nexport const devTopicMetadataSchema = t.object({\n\tname: t.text(),\n\tdescription: t.optional(t.text()),\n\tschema: t.optional(t.any()),\n\tprovider: t.text(),\n});\n\nexport type DevTopicMetadata = Static<typeof devTopicMetadataSchema>;\n","import { type Static, t } from \"@alepha/core\";\nimport { devActionMetadataSchema } from \"./DevActionMetadata.ts\";\nimport { devBucketMetadataSchema } from \"./DevBucketMetadata.ts\";\nimport { devCacheMetadataSchema } from \"./DevCacheMetadata.ts\";\nimport { devModuleMetadataSchema } from \"./DevModuleMetadata.ts\";\nimport { devPageMetadataSchema } from \"./DevPageMetadata.ts\";\nimport { devProviderMetadataSchema } from \"./DevProviderMetadata.ts\";\nimport { devQueueMetadataSchema } from \"./DevQueueMetadata.ts\";\nimport { devRealmMetadataSchema } from \"./DevRealmMetadata.ts\";\nimport { devSchedulerMetadataSchema } from \"./DevSchedulerMetadata.ts\";\nimport { devTopicMetadataSchema } from \"./DevTopicMetadata.ts\";\n\nexport const devMetadataSchema = t.object({\n\tactions: t.array(devActionMetadataSchema),\n\tqueues: t.array(devQueueMetadataSchema),\n\tschedulers: t.array(devSchedulerMetadataSchema),\n\ttopics: t.array(devTopicMetadataSchema),\n\tbuckets: t.array(devBucketMetadataSchema),\n\trealms: t.array(devRealmMetadataSchema),\n\tcaches: t.array(devCacheMetadataSchema),\n\tpages: t.array(devPageMetadataSchema),\n\tproviders: t.array(devProviderMetadataSchema),\n\tmodules: t.array(devModuleMetadataSchema),\n\t// More metadata will be added here later\n});\n\nexport type DevMetadata = Static<typeof devMetadataSchema>;\n","import { $bucket } from \"@alepha/bucket\";\nimport { $cache } from \"@alepha/cache\";\nimport { $hook, $inject, Alepha, t } from \"@alepha/core\";\nimport type { LogEntry } from \"@alepha/logger\";\nimport { $queue } from \"@alepha/queue\";\nimport { $page } from \"@alepha/react\";\nimport { $scheduler } from \"@alepha/scheduler\";\nimport { $realm } from \"@alepha/security\";\nimport { $action, $route } from \"@alepha/server\";\nimport { $topic } from \"@alepha/topic\";\nimport { ui } from \"./constants/ui.ts\";\nimport type { DevActionMetadata } from \"./schemas/DevActionMetadata.ts\";\nimport type { DevBucketMetadata } from \"./schemas/DevBucketMetadata.ts\";\nimport type { DevCacheMetadata } from \"./schemas/DevCacheMetadata.ts\";\nimport type { DevLogEntry } from \"./schemas/DevLogEntry.ts\";\nimport { type DevMetadata, devMetadataSchema } from \"./schemas/DevMetadata.ts\";\nimport type { DevModuleMetadata } from \"./schemas/DevModuleMetadata.ts\";\nimport type { DevPageMetadata } from \"./schemas/DevPageMetadata.ts\";\nimport type { DevProviderMetadata } from \"./schemas/DevProviderMetadata.ts\";\nimport type { DevQueueMetadata } from \"./schemas/DevQueueMetadata.ts\";\nimport type { DevRealmMetadata } from \"./schemas/DevRealmMetadata.ts\";\nimport type { DevSchedulerMetadata } from \"./schemas/DevSchedulerMetadata.ts\";\nimport type { DevTopicMetadata } from \"./schemas/DevTopicMetadata.ts\";\n\nexport class DevCollectorProvider {\n\tprotected readonly alepha = $inject(Alepha);\n\tprotected readonly logs: DevLogEntry[] = [];\n\tprotected readonly maxLogs = 10000;\n\n\tprotected readonly onLog = $hook({\n\t\ton: \"log\",\n\t\thandler: (ev: { message: string; entry: LogEntry }) => {\n\t\t\tthis.logs.push({\n\t\t\t\tformatted: ev.message,\n\t\t\t\tentry: ev.entry,\n\t\t\t});\n\n\t\t\t// Keep only the last 10000 logs\n\t\t\tif (this.logs.length > this.maxLogs) {\n\t\t\t\tthis.logs.shift();\n\t\t\t}\n\t\t},\n\t});\n\n\tprotected readonly uiRoute = $route({\n\t\tmethod: \"GET\",\n\t\tpath: \"/devtools\",\n\t\tschema: {\n\t\t\tresponse: t.text(),\n\t\t},\n\t\thandler: () => {\n\t\t\treturn ui;\n\t\t},\n\t});\n\n\tprotected readonly metadataRoute = $route({\n\t\tmethod: \"GET\",\n\t\tpath: \"/devtools/metadata\",\n\t\tschema: {\n\t\t\tresponse: devMetadataSchema,\n\t\t},\n\t\thandler: () => {\n\t\t\treturn this.getMetadata();\n\t\t},\n\t});\n\n\tprotected readonly logsRoute = $route({\n\t\tmethod: \"GET\",\n\t\tpath: \"/devtools/logs\",\n\t\tschema: {\n\t\t\tresponse: t.array(\n\t\t\t\tt.object({\n\t\t\t\t\tformatted: t.text(),\n\t\t\t\t\tentry: t.any(),\n\t\t\t\t}),\n\t\t\t),\n\t\t},\n\t\thandler: () => {\n\t\t\treturn this.getLogs();\n\t\t},\n\t});\n\n\tpublic getLogs(): DevLogEntry[] {\n\t\treturn this.logs;\n\t}\n\n\tpublic getActions(): DevActionMetadata[] {\n\t\tconst actionDescriptors = this.alepha.descriptors($action);\n\n\t\treturn actionDescriptors.map((action) => {\n\t\t\tconst schema = action.schema;\n\t\t\tconst options = action.options as any; // Allow accessing augmented properties\n\n\t\t\treturn {\n\t\t\t\tname: action.name,\n\t\t\t\tgroup: action.group,\n\t\t\t\tmethod: action.method,\n\t\t\t\tpath: action.path,\n\t\t\t\tprefix: action.prefix,\n\t\t\t\tfullPath: action.route.path,\n\t\t\t\tdescription: action.options.description,\n\t\t\t\tsummary: options.summary,\n\t\t\t\tdisabled: action.options.disabled,\n\t\t\t\tsecure: options.secure,\n\t\t\t\thide: options.hide,\n\t\t\t\tbody: schema?.body,\n\t\t\t\tparams: schema?.params,\n\t\t\t\tquery: schema?.query,\n\t\t\t\tresponse: schema?.response,\n\t\t\t\tbodyContentType: action.getBodyContentType(),\n\t\t\t};\n\t\t});\n\t}\n\n\tpublic getQueues(): DevQueueMetadata[] {\n\t\tconst queueDescriptors = this.alepha.descriptors($queue);\n\n\t\treturn queueDescriptors.map((queue) => ({\n\t\t\tname: queue.name,\n\t\t\tdescription: queue.options.description,\n\t\t\tschema: queue.options.schema,\n\t\t\tprovider: this.getProviderName(queue.options.provider),\n\t\t}));\n\t}\n\n\tpublic getSchedulers(): DevSchedulerMetadata[] {\n\t\tconst schedulerDescriptors = this.alepha.descriptors($scheduler);\n\n\t\treturn schedulerDescriptors.map((scheduler) => ({\n\t\t\tname: scheduler.name,\n\t\t\tdescription: scheduler.options.description,\n\t\t\tcron: scheduler.options.cron,\n\t\t\tinterval: scheduler.options.interval,\n\t\t\tlock: scheduler.options.lock,\n\t\t}));\n\t}\n\n\tpublic getTopics(): DevTopicMetadata[] {\n\t\tconst topicDescriptors = this.alepha.descriptors($topic);\n\n\t\treturn topicDescriptors.map((topic) => ({\n\t\t\tname: topic.name,\n\t\t\tdescription: topic.options.description,\n\t\t\tschema: topic.options.schema,\n\t\t\tprovider: this.getProviderName(topic.options.provider),\n\t\t}));\n\t}\n\n\tpublic getBuckets(): DevBucketMetadata[] {\n\t\tconst bucketDescriptors = this.alepha.descriptors($bucket);\n\n\t\treturn bucketDescriptors.map((bucket) => ({\n\t\t\tname: bucket.name,\n\t\t\tdescription: bucket.options.description,\n\t\t\tmimeTypes: bucket.options.mimeTypes,\n\t\t\tmaxSize: bucket.options.maxSize,\n\t\t\tprovider: this.getProviderName(bucket.options.provider),\n\t\t}));\n\t}\n\n\tpublic getRealms(): DevRealmMetadata[] {\n\t\tconst realmDescriptors = this.alepha.descriptors($realm);\n\n\t\treturn realmDescriptors.map((realm) => ({\n\t\t\tname: realm.name,\n\t\t\tdescription: realm.options.description,\n\t\t\troles: realm.options.roles,\n\t\t\ttype: \"secret\" in realm.options ? \"internal\" : \"external\",\n\t\t\tsettings: {\n\t\t\t\taccessTokenExpiration: realm.options.settings?.accessToken?.expiration,\n\t\t\t\trefreshTokenExpiration:\n\t\t\t\t\trealm.options.settings?.refreshToken?.expiration,\n\t\t\t\thasOnCreateSession: !!realm.options.settings?.onCreateSession,\n\t\t\t\thasOnRefreshSession: !!realm.options.settings?.onRefreshSession,\n\t\t\t\thasOnDeleteSession: !!realm.options.settings?.onDeleteSession,\n\t\t\t},\n\t\t}));\n\t}\n\n\tpublic getCaches(): DevCacheMetadata[] {\n\t\tconst cacheDescriptors = this.alepha.descriptors($cache);\n\n\t\treturn cacheDescriptors.map((cache) => ({\n\t\t\tname: cache.container,\n\t\t\tttl: cache.options.ttl,\n\t\t\tdisabled: cache.options.disabled,\n\t\t\tprovider: this.getProviderName(cache.options.provider),\n\t\t}));\n\t}\n\n\tpublic getPages(): DevPageMetadata[] {\n\t\tconst pageDescriptors = this.alepha.descriptors($page);\n\n\t\treturn pageDescriptors.map((page) => ({\n\t\t\tname: page.name,\n\t\t\tdescription: page.options.description,\n\t\t\tpath: page.options.path,\n\t\t\tparams: page.options.schema?.params,\n\t\t\tquery: page.options.schema?.query,\n\t\t\thasComponent: !!page.options.component,\n\t\t\thasLazy: !!page.options.lazy,\n\t\t\thasResolve: !!page.options.resolve,\n\t\t\thasChildren: !!page.options.children,\n\t\t\thasParent: !!page.options.parent,\n\t\t\thasErrorHandler: !!page.options.errorHandler,\n\t\t\tstatic:\n\t\t\t\ttypeof page.options.static === \"boolean\"\n\t\t\t\t\t? page.options.static\n\t\t\t\t\t: !!page.options.static,\n\t\t\tcache: page.options.cache,\n\t\t\tclient: page.options.client,\n\t\t\tanimation: page.options.animation,\n\t\t}));\n\t}\n\n\tpublic getProviders(): DevProviderMetadata[] {\n\t\tconst graph = this.alepha.graph();\n\n\t\treturn Object.entries(graph).map(([name, info]) => ({\n\t\t\tname,\n\t\t\tmodule: info.module,\n\t\t\tdependencies: info.from,\n\t\t\taliases: info.as,\n\t\t}));\n\t}\n\n\tpublic getModules(): DevModuleMetadata[] {\n\t\tconst graph = this.alepha.graph();\n\t\tconst moduleMap = new Map<string, Set<string>>();\n\n\t\t// Group providers by module\n\t\tfor (const [providerName, info] of Object.entries(graph)) {\n\t\t\tif (info.module) {\n\t\t\t\tif (!moduleMap.has(info.module)) {\n\t\t\t\t\tmoduleMap.set(info.module, new Set());\n\t\t\t\t}\n\t\t\t\tmoduleMap.get(info.module)!.add(providerName);\n\t\t\t}\n\t\t}\n\n\t\treturn Array.from(moduleMap.entries()).map(([name, providers]) => ({\n\t\t\tname,\n\t\t\tproviders: Array.from(providers),\n\t\t}));\n\t}\n\n\tpublic getMetadata(): DevMetadata {\n\t\treturn {\n\t\t\tactions: this.getActions(),\n\t\t\tqueues: this.getQueues(),\n\t\t\tschedulers: this.getSchedulers(),\n\t\t\ttopics: this.getTopics(),\n\t\t\tbuckets: this.getBuckets(),\n\t\t\trealms: this.getRealms(),\n\t\t\tcaches: this.getCaches(),\n\t\t\tpages: this.getPages(),\n\t\t\tproviders: this.getProviders(),\n\t\t\tmodules: this.getModules(),\n\t\t};\n\t}\n\n\tprotected getProviderName(provider?: \"memory\" | any): string {\n\t\tif (!provider) {\n\t\t\treturn \"default\";\n\t\t}\n\t\tif (provider === \"memory\") {\n\t\t\treturn \"memory\";\n\t\t}\n\t\treturn provider.name || \"custom\";\n\t}\n}\n","import { type Static, t } from \"@alepha/core\";\nimport type { LogEntry } from \"@alepha/logger\";\n\nexport const devLogEntrySchema = t.object({\n\tformatted: t.text(),\n\tentry: t.any(), // Use any since LogEntry has Date instead of string for timestamp\n});\n\nexport type DevLogEntry = Static<typeof devLogEntrySchema> & {\n\tentry: LogEntry;\n};\n","import { $module } from \"@alepha/core\";\nimport { DevCollectorProvider } from \"./DevCollectorProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./DevCollectorProvider.ts\";\nexport * from \"./schemas/DevActionMetadata.ts\";\nexport * from \"./schemas/DevBucketMetadata.ts\";\nexport * from \"./schemas/DevCacheMetadata.ts\";\nexport * from \"./schemas/DevLogEntry.ts\";\nexport * from \"./schemas/DevMetadata.ts\";\nexport * from \"./schemas/DevModuleMetadata.ts\";\nexport * from \"./schemas/DevPageMetadata.ts\";\nexport * from \"./schemas/DevProviderMetadata.ts\";\nexport * from \"./schemas/DevQueueMetadata.ts\";\nexport * from \"./schemas/DevRealmMetadata.ts\";\nexport * from \"./schemas/DevSchedulerMetadata.ts\";\nexport * from \"./schemas/DevTopicMetadata.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Developer tools module for monitoring and debugging Alepha applications.\n *\n * This module provides comprehensive data collection capabilities for tracking application behavior,\n * performance metrics, and debugging information in real-time.\n *\n * @see {@link DevCollectorProvider}\n * @module alepha.devtools\n */\nexport const AlephaDevtools = $module({\n\tname: \"alepha.devtools\",\n\tdescriptors: [],\n\tservices: [DevCollectorProvider],\n});\n"],"mappings":";;;;;;;;;;;AACA,MAAa,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@alepha/devtools",
3
3
  "description": "Developer tools for monitoring and debugging Alepha applications.",
4
- "version": "0.10.3",
4
+ "version": "0.10.4",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=22.0.0"
@@ -14,16 +14,16 @@
14
14
  "src"
15
15
  ],
16
16
  "dependencies": {
17
- "@alepha/bucket": "0.10.3",
18
- "@alepha/cache": "0.10.3",
19
- "@alepha/core": "0.10.3",
20
- "@alepha/logger": "0.10.3",
21
- "@alepha/queue": "0.10.3",
22
- "@alepha/react": "0.10.3",
23
- "@alepha/scheduler": "0.10.3",
24
- "@alepha/security": "0.10.3",
25
- "@alepha/server": "0.10.3",
26
- "@alepha/topic": "0.10.3"
17
+ "@alepha/bucket": "0.10.4",
18
+ "@alepha/cache": "0.10.4",
19
+ "@alepha/core": "0.10.4",
20
+ "@alepha/logger": "0.10.4",
21
+ "@alepha/queue": "0.10.4",
22
+ "@alepha/react": "0.10.4",
23
+ "@alepha/scheduler": "0.10.4",
24
+ "@alepha/security": "0.10.4",
25
+ "@alepha/server": "0.10.4",
26
+ "@alepha/topic": "0.10.4"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@biomejs/biome": "^2.2.5",
@@ -25,7 +25,7 @@ import type { DevTopicMetadata } from "./schemas/DevTopicMetadata.ts";
25
25
  export class DevCollectorProvider {
26
26
  protected readonly alepha = $inject(Alepha);
27
27
  protected readonly logs: DevLogEntry[] = [];
28
- protected readonly maxLogs = 1000;
28
+ protected readonly maxLogs = 10000;
29
29
 
30
30
  protected readonly onLog = $hook({
31
31
  on: "log",
@@ -35,7 +35,7 @@ export class DevCollectorProvider {
35
35
  entry: ev.entry,
36
36
  });
37
37
 
38
- // Keep only the last 1000 logs
38
+ // Keep only the last 10000 logs
39
39
  if (this.logs.length > this.maxLogs) {
40
40
  this.logs.shift();
41
41
  }
@@ -46,7 +46,7 @@ export class DevCollectorProvider {
46
46
  method: "GET",
47
47
  path: "/devtools",
48
48
  schema: {
49
- response: t.string(),
49
+ response: t.text(),
50
50
  },
51
51
  handler: () => {
52
52
  return ui;
@@ -64,6 +64,22 @@ export class DevCollectorProvider {
64
64
  },
65
65
  });
66
66
 
67
+ protected readonly logsRoute = $route({
68
+ method: "GET",
69
+ path: "/devtools/logs",
70
+ schema: {
71
+ response: t.array(
72
+ t.object({
73
+ formatted: t.text(),
74
+ entry: t.any(),
75
+ }),
76
+ ),
77
+ },
78
+ handler: () => {
79
+ return this.getLogs();
80
+ },
81
+ });
82
+
67
83
  public getLogs(): DevLogEntry[] {
68
84
  return this.logs;
69
85
  }
@@ -230,7 +246,6 @@ export class DevCollectorProvider {
230
246
 
231
247
  public getMetadata(): DevMetadata {
232
248
  return {
233
- logs: this.getLogs(),
234
249
  actions: this.getActions(),
235
250
  queues: this.getQueues(),
236
251
  schedulers: this.getSchedulers(),
@@ -1,14 +1,14 @@
1
1
  import { type Static, t } from "@alepha/core";
2
2
 
3
3
  export const devActionMetadataSchema = t.object({
4
- name: t.string(),
5
- group: t.string(),
6
- method: t.string(),
7
- path: t.string(),
8
- prefix: t.string(),
9
- fullPath: t.string(),
10
- description: t.optional(t.string()),
11
- summary: t.optional(t.string()),
4
+ name: t.text(),
5
+ group: t.text(),
6
+ method: t.text(),
7
+ path: t.text(),
8
+ prefix: t.text(),
9
+ fullPath: t.text(),
10
+ description: t.optional(t.text()),
11
+ summary: t.optional(t.text()),
12
12
  disabled: t.optional(t.boolean()),
13
13
  secure: t.optional(t.boolean()),
14
14
  hide: t.optional(t.boolean()),
@@ -16,7 +16,7 @@ export const devActionMetadataSchema = t.object({
16
16
  params: t.optional(t.any()),
17
17
  query: t.optional(t.any()),
18
18
  response: t.optional(t.any()),
19
- bodyContentType: t.optional(t.string()),
19
+ bodyContentType: t.optional(t.text()),
20
20
  });
21
21
 
22
22
  export type DevActionMetadata = Static<typeof devActionMetadataSchema>;
@@ -1,11 +1,11 @@
1
1
  import { type Static, t } from "@alepha/core";
2
2
 
3
3
  export const devBucketMetadataSchema = t.object({
4
- name: t.string(),
5
- description: t.optional(t.string()),
6
- mimeTypes: t.optional(t.array(t.string())),
4
+ name: t.text(),
5
+ description: t.optional(t.text()),
6
+ mimeTypes: t.optional(t.array(t.text())),
7
7
  maxSize: t.optional(t.number()),
8
- provider: t.string(),
8
+ provider: t.text(),
9
9
  });
10
10
 
11
11
  export type DevBucketMetadata = Static<typeof devBucketMetadataSchema>;
@@ -1,10 +1,10 @@
1
1
  import { type Static, t } from "@alepha/core";
2
2
 
3
3
  export const devCacheMetadataSchema = t.object({
4
- name: t.string(),
4
+ name: t.text(),
5
5
  ttl: t.optional(t.any()),
6
6
  disabled: t.optional(t.boolean()),
7
- provider: t.string(),
7
+ provider: t.text(),
8
8
  });
9
9
 
10
10
  export type DevCacheMetadata = Static<typeof devCacheMetadataSchema>;
@@ -2,7 +2,7 @@ import { type Static, t } from "@alepha/core";
2
2
  import type { LogEntry } from "@alepha/logger";
3
3
 
4
4
  export const devLogEntrySchema = t.object({
5
- formatted: t.string(),
5
+ formatted: t.text(),
6
6
  entry: t.any(), // Use any since LogEntry has Date instead of string for timestamp
7
7
  });
8
8
 
@@ -2,7 +2,6 @@ import { type Static, t } from "@alepha/core";
2
2
  import { devActionMetadataSchema } from "./DevActionMetadata.ts";
3
3
  import { devBucketMetadataSchema } from "./DevBucketMetadata.ts";
4
4
  import { devCacheMetadataSchema } from "./DevCacheMetadata.ts";
5
- import { devLogEntrySchema } from "./DevLogEntry.ts";
6
5
  import { devModuleMetadataSchema } from "./DevModuleMetadata.ts";
7
6
  import { devPageMetadataSchema } from "./DevPageMetadata.ts";
8
7
  import { devProviderMetadataSchema } from "./DevProviderMetadata.ts";
@@ -12,7 +11,6 @@ import { devSchedulerMetadataSchema } from "./DevSchedulerMetadata.ts";
12
11
  import { devTopicMetadataSchema } from "./DevTopicMetadata.ts";
13
12
 
14
13
  export const devMetadataSchema = t.object({
15
- logs: t.array(devLogEntrySchema),
16
14
  actions: t.array(devActionMetadataSchema),
17
15
  queues: t.array(devQueueMetadataSchema),
18
16
  schedulers: t.array(devSchedulerMetadataSchema),
@@ -1,8 +1,8 @@
1
1
  import { type Static, t } from "@alepha/core";
2
2
 
3
3
  export const devModuleMetadataSchema = t.object({
4
- name: t.string(),
5
- providers: t.array(t.string()),
4
+ name: t.text(),
5
+ providers: t.array(t.text()),
6
6
  });
7
7
 
8
8
  export type DevModuleMetadata = Static<typeof devModuleMetadataSchema>;
@@ -1,9 +1,9 @@
1
1
  import { type Static, t } from "@alepha/core";
2
2
 
3
3
  export const devPageMetadataSchema = t.object({
4
- name: t.string(),
5
- description: t.optional(t.string()),
6
- path: t.optional(t.string()),
4
+ name: t.text(),
5
+ description: t.optional(t.text()),
6
+ path: t.optional(t.text()),
7
7
  params: t.optional(t.any()),
8
8
  query: t.optional(t.any()),
9
9
  hasComponent: t.boolean(),
@@ -1,10 +1,10 @@
1
1
  import { type Static, t } from "@alepha/core";
2
2
 
3
3
  export const devProviderMetadataSchema = t.object({
4
- name: t.string(),
5
- module: t.optional(t.string()),
6
- dependencies: t.array(t.string()),
7
- aliases: t.optional(t.array(t.string())),
4
+ name: t.text(),
5
+ module: t.optional(t.text()),
6
+ dependencies: t.array(t.text()),
7
+ aliases: t.optional(t.array(t.text())),
8
8
  });
9
9
 
10
10
  export type DevProviderMetadata = Static<typeof devProviderMetadataSchema>;
@@ -1,10 +1,10 @@
1
1
  import { type Static, t } from "@alepha/core";
2
2
 
3
3
  export const devQueueMetadataSchema = t.object({
4
- name: t.string(),
5
- description: t.optional(t.string()),
4
+ name: t.text(),
5
+ description: t.optional(t.text()),
6
6
  schema: t.optional(t.any()),
7
- provider: t.string(),
7
+ provider: t.text(),
8
8
  });
9
9
 
10
10
  export type DevQueueMetadata = Static<typeof devQueueMetadataSchema>;
@@ -1,8 +1,8 @@
1
1
  import { type Static, t } from "@alepha/core";
2
2
 
3
3
  export const devRealmMetadataSchema = t.object({
4
- name: t.string(),
5
- description: t.optional(t.string()),
4
+ name: t.text(),
5
+ description: t.optional(t.text()),
6
6
  roles: t.optional(t.array(t.any())),
7
7
  type: t.enum(["internal", "external"]),
8
8
  settings: t.optional(
@@ -1,9 +1,9 @@
1
1
  import { type Static, t } from "@alepha/core";
2
2
 
3
3
  export const devSchedulerMetadataSchema = t.object({
4
- name: t.string(),
5
- description: t.optional(t.string()),
6
- cron: t.optional(t.string()),
4
+ name: t.text(),
5
+ description: t.optional(t.text()),
6
+ cron: t.optional(t.text()),
7
7
  interval: t.optional(t.any()),
8
8
  lock: t.optional(t.boolean()),
9
9
  });
@@ -1,10 +1,10 @@
1
1
  import { type Static, t } from "@alepha/core";
2
2
 
3
3
  export const devTopicMetadataSchema = t.object({
4
- name: t.string(),
5
- description: t.optional(t.string()),
4
+ name: t.text(),
5
+ description: t.optional(t.text()),
6
6
  schema: t.optional(t.any()),
7
- provider: t.string(),
7
+ provider: t.text(),
8
8
  });
9
9
 
10
10
  export type DevTopicMetadata = Static<typeof devTopicMetadataSchema>;