faultmesh 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +61 -19
  2. package/dist/dashboard/app.js +1906 -139
  3. package/dist/dashboard/index.html +393 -99
  4. package/dist/dashboard/styles.css +1191 -23
  5. package/dist/engine/ControlApi.d.ts +13 -1
  6. package/dist/engine/ControlApi.js +304 -14
  7. package/dist/engine/FaultMeshProxy.d.ts +2 -0
  8. package/dist/engine/FaultMeshProxy.js +41 -5
  9. package/dist/engine/TelemetryHub.d.ts +1 -0
  10. package/dist/engine/TelemetryHub.js +3 -0
  11. package/dist/engine/ToxicPipeline.d.ts +5 -4
  12. package/dist/engine/ToxicPipeline.js +17 -4
  13. package/dist/healer/AiHealer.d.ts +30 -0
  14. package/dist/healer/AiHealer.js +188 -0
  15. package/dist/healer/AutoHealer.d.ts +24 -0
  16. package/dist/healer/AutoHealer.js +503 -0
  17. package/dist/healer/DiffGenerator.d.ts +10 -0
  18. package/dist/healer/DiffGenerator.js +63 -0
  19. package/dist/healer/DiffUtil.d.ts +6 -0
  20. package/dist/healer/DiffUtil.js +67 -0
  21. package/dist/healer/transformers/ExpressTransformers.d.ts +43 -0
  22. package/dist/healer/transformers/ExpressTransformers.js +228 -0
  23. package/dist/healer/transformers/FastApiTransformers.d.ts +19 -0
  24. package/dist/healer/transformers/FastApiTransformers.js +93 -0
  25. package/dist/healer/transformers/GoTransformers.d.ts +19 -0
  26. package/dist/healer/transformers/GoTransformers.js +106 -0
  27. package/dist/healer/types.d.ts +59 -0
  28. package/dist/healer/types.js +1 -0
  29. package/dist/redteam/EccAgentBridge.d.ts +20 -0
  30. package/dist/redteam/EccAgentBridge.js +303 -0
  31. package/dist/redteam/RedTeamEngine.d.ts +56 -0
  32. package/dist/redteam/RedTeamEngine.js +709 -0
  33. package/dist/redteam/types.d.ts +117 -0
  34. package/dist/redteam/types.js +5 -0
  35. package/dist/scorer/ResilienceScorer.d.ts +5 -0
  36. package/dist/scorer/ResilienceScorer.js +323 -7
  37. package/dist/scorer/SecurityAuditor.d.ts +8 -0
  38. package/dist/scorer/SecurityAuditor.js +471 -69
  39. package/dist/scorer/TrafficStormAuditor.d.ts +5 -0
  40. package/dist/scorer/TrafficStormAuditor.js +328 -69
  41. package/dist/server.js +17 -10
  42. package/dist/types.d.ts +7 -3
  43. package/package.json +2 -1
@@ -11,6 +11,7 @@
11
11
  --bg-subtle: #f4f4f5;
12
12
  --bg-hover: #e4e4e7;
13
13
  --bg-input: #ffffff;
14
+ --bg-card: #ffffff;
14
15
 
15
16
  --border-subtle: #f4f4f5;
16
17
  --border-default: #e4e4e7;
@@ -48,6 +49,7 @@
48
49
  --bg-subtle: #18181b;
49
50
  --bg-hover: #27272a;
50
51
  --bg-input: #18181b;
52
+ --bg-card: #18181d;
51
53
 
52
54
  --border-subtle: #1f1f23;
53
55
  --border-default: #27272a;
@@ -199,9 +201,8 @@ body {
199
201
  display: flex;
200
202
  justify-content: space-between;
201
203
  align-items: center;
202
- flex-wrap: wrap;
203
- gap: 14px;
204
- padding-bottom: 14px;
204
+ gap: 20px;
205
+ padding-bottom: 16px;
205
206
  border-bottom: 1px solid var(--border-default);
206
207
  }
207
208
 
@@ -209,6 +210,8 @@ body {
209
210
  display: flex;
210
211
  flex-direction: column;
211
212
  gap: 4px;
213
+ flex: 1 1 auto;
214
+ min-width: 0;
212
215
  }
213
216
 
214
217
  .badge-row {
@@ -235,27 +238,31 @@ body {
235
238
  font-weight: 700;
236
239
  letter-spacing: -0.3px;
237
240
  color: var(--text-main);
241
+ line-height: 1.3;
238
242
  }
239
243
 
240
244
  .audit-header-bar p {
241
245
  font-size: 12px;
242
246
  color: var(--text-muted);
243
- max-width: 650px;
247
+ line-height: 1.4;
248
+ margin: 0;
244
249
  }
245
250
 
246
251
  .diag-tabs {
247
252
  display: flex;
253
+ align-items: center;
248
254
  gap: 4px;
249
255
  background: var(--bg-subtle);
250
256
  padding: 3px;
251
257
  border-radius: var(--radius);
252
258
  border: 1px solid var(--border-default);
259
+ flex-shrink: 0;
253
260
  }
254
261
 
255
262
  .diag-tab {
256
263
  background: transparent;
257
264
  border: none;
258
- padding: 7px 16px;
265
+ padding: 7px 13px;
259
266
  font-size: 12px;
260
267
  font-weight: 600;
261
268
  color: var(--text-muted);
@@ -263,6 +270,7 @@ body {
263
270
  cursor: pointer;
264
271
  transition: all 0.15s ease;
265
272
  white-space: nowrap;
273
+ text-align: center;
266
274
  }
267
275
 
268
276
  .diag-tab:hover {
@@ -275,6 +283,32 @@ body {
275
283
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
276
284
  }
277
285
 
286
+ @media (max-width: 1200px) {
287
+ .diag-tabs {
288
+ display: grid;
289
+ grid-template-columns: repeat(2, minmax(0, 1fr));
290
+ gap: 3px;
291
+ padding: 3px;
292
+ }
293
+ .diag-tab {
294
+ padding: 6px 10px;
295
+ font-size: 11px;
296
+ text-align: center;
297
+ }
298
+ }
299
+
300
+ @media (max-width: 768px) {
301
+ .audit-header-bar {
302
+ flex-direction: column;
303
+ align-items: stretch;
304
+ gap: 12px;
305
+ }
306
+ .diag-tabs {
307
+ display: flex;
308
+ flex-direction: column;
309
+ }
310
+ }
311
+
278
312
  /* Banner: Score & Action Runner */
279
313
  .audit-banner {
280
314
  display: flex;
@@ -650,16 +684,48 @@ body {
650
684
 
651
685
  .columns-grid {
652
686
  display: grid;
653
- grid-template-columns: 1fr 1fr;
687
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
654
688
  gap: 16px;
655
689
  align-items: start;
656
690
  margin-bottom: 16px;
691
+ width: 100%;
692
+ box-sizing: border-box;
657
693
  }
658
694
 
659
- .column {
695
+ #leftWorkbenchCol,
696
+ #rightWorkbenchCol {
660
697
  display: flex;
661
698
  flex-direction: column;
662
699
  gap: 16px;
700
+ min-width: 0;
701
+ }
702
+
703
+ .presets-card,
704
+ .custom-rule-card,
705
+ .active-rules-card {
706
+ display: flex;
707
+ flex-direction: column;
708
+ box-sizing: border-box;
709
+ }
710
+
711
+ .response-inspector-card {
712
+ display: flex;
713
+ flex-direction: column;
714
+ gap: 10px;
715
+ min-width: 0;
716
+ max-width: 100%;
717
+ box-sizing: border-box;
718
+ overflow: hidden;
719
+ }
720
+
721
+ .live-log-card {
722
+ display: flex;
723
+ flex-direction: column;
724
+ gap: 10px;
725
+ min-width: 0;
726
+ max-width: 100%;
727
+ box-sizing: border-box;
728
+ overflow: hidden;
663
729
  }
664
730
 
665
731
  .adder-subgroup {
@@ -740,22 +806,36 @@ body {
740
806
  display: flex;
741
807
  justify-content: space-between;
742
808
  align-items: center;
809
+ gap: 8px;
743
810
  padding: 8px 12px;
744
811
  background: var(--bg-subtle);
745
812
  border: 1px solid var(--border-default);
746
813
  border-radius: var(--radius);
814
+ min-width: 0;
815
+ }
816
+
817
+ .rule-item > div:first-child {
818
+ min-width: 0;
819
+ flex: 1;
820
+ overflow: hidden;
747
821
  }
748
822
 
749
823
  .rule-title {
750
824
  font-size: 12px;
751
825
  font-weight: 600;
752
826
  color: var(--text-main);
827
+ overflow: hidden;
828
+ text-overflow: ellipsis;
829
+ white-space: nowrap;
753
830
  }
754
831
 
755
832
  .rule-subtitle {
756
833
  font-size: 11px;
757
834
  color: var(--text-muted);
758
835
  font-family: var(--font-mono);
836
+ overflow: hidden;
837
+ text-overflow: ellipsis;
838
+ white-space: nowrap;
759
839
  }
760
840
 
761
841
  .empty-state {
@@ -776,6 +856,9 @@ body {
776
856
  display: flex;
777
857
  flex-direction: column;
778
858
  gap: 10px;
859
+ min-width: 0;
860
+ max-width: 100%;
861
+ overflow: hidden;
779
862
  }
780
863
 
781
864
  .inspector-controls {
@@ -783,11 +866,13 @@ body {
783
866
  align-items: center;
784
867
  gap: 8px;
785
868
  flex-wrap: wrap;
869
+ min-width: 0;
786
870
  }
787
871
 
788
872
  .inspector-select {
789
873
  flex: 1;
790
- min-width: 200px;
874
+ min-width: 180px;
875
+ max-width: 100%;
791
876
  padding: 6px 10px;
792
877
  font-size: 12px;
793
878
  }
@@ -795,25 +880,34 @@ body {
795
880
  .response-meta-bar {
796
881
  display: flex;
797
882
  align-items: center;
798
- gap: 10px;
799
- flex-wrap: wrap;
883
+ gap: 10px 14px;
800
884
  background: var(--bg-subtle);
801
885
  border: 1px solid var(--border-default);
802
886
  border-radius: var(--radius);
803
- padding: 7px 12px;
887
+ padding: 8px 12px;
804
888
  font-family: var(--font-mono);
805
889
  font-size: 11px;
890
+ min-width: 0;
891
+ width: 100%;
892
+ box-sizing: border-box;
806
893
  }
807
894
 
808
895
  .meta-item {
809
- display: flex;
896
+ display: inline-flex;
810
897
  align-items: center;
811
- gap: 5px;
898
+ gap: 6px;
899
+ min-width: 0;
900
+ }
901
+
902
+ .meta-item.meta-item-applied {
903
+ flex: 1;
904
+ min-width: 0;
812
905
  }
813
906
 
814
907
  .meta-label {
815
908
  color: var(--text-muted);
816
909
  font-size: 11px;
910
+ flex-shrink: 0;
817
911
  }
818
912
 
819
913
  .status-pill {
@@ -825,12 +919,16 @@ body {
825
919
  background: var(--bg-surface);
826
920
  border: 1px solid var(--border-default);
827
921
  color: var(--text-main);
922
+ white-space: nowrap;
923
+ flex-shrink: 0;
828
924
  }
829
925
 
830
926
  .response-meta {
831
927
  color: var(--text-main);
832
928
  font-weight: 600;
833
929
  font-variant-numeric: tabular-nums;
930
+ white-space: nowrap;
931
+ flex-shrink: 0;
834
932
  }
835
933
 
836
934
  .response-meta-rule {
@@ -841,6 +939,12 @@ body {
841
939
  border-radius: 4px;
842
940
  font-size: 11px;
843
941
  font-weight: 600;
942
+ max-width: 100%;
943
+ overflow: hidden;
944
+ text-overflow: ellipsis;
945
+ white-space: nowrap;
946
+ display: inline-block;
947
+ vertical-align: middle;
844
948
  }
845
949
 
846
950
  .active-rules-pill {
@@ -851,7 +955,12 @@ body {
851
955
  background: var(--bg-surface);
852
956
  color: var(--text-muted);
853
957
  border: 1px solid var(--border-default);
958
+ max-width: 220px;
959
+ overflow: hidden;
960
+ text-overflow: ellipsis;
854
961
  white-space: nowrap;
962
+ display: inline-block;
963
+ vertical-align: middle;
855
964
  }
856
965
 
857
966
  .active-rules-pill.active {
@@ -870,22 +979,29 @@ body {
870
979
 
871
980
  .response-body-wrapper {
872
981
  width: 100%;
982
+ flex: 1;
983
+ display: flex;
984
+ flex-direction: column;
985
+ min-height: 0;
873
986
  }
874
987
 
875
988
  .response-body-pre {
989
+ flex: 1;
876
990
  background: var(--bg-subtle);
877
991
  border: 1px solid var(--border-default);
878
992
  border-radius: var(--radius);
879
993
  padding: 12px 14px;
880
994
  font-family: var(--font-mono);
881
995
  font-size: 11px;
882
- min-height: 140px;
883
- max-height: 220px;
996
+ min-height: 0;
997
+ max-height: none;
884
998
  overflow-y: auto;
885
999
  color: var(--text-main);
886
1000
  white-space: pre-wrap;
887
- word-break: break-word;
1001
+ word-break: break-all;
1002
+ overflow-wrap: anywhere;
888
1003
  line-height: 1.45;
1004
+ box-sizing: border-box;
889
1005
  }
890
1006
 
891
1007
  .inspector-footer {
@@ -905,18 +1021,16 @@ body {
905
1021
  }
906
1022
 
907
1023
  /* ==========================================================================
908
- LIVE TRAFFIC LOG (Full Width Across Bottom)
1024
+ LIVE TRAFFIC LOG (Card in Column 2, Rows 2-3)
909
1025
  ========================================================================== */
910
1026
 
911
- .full-width-log-section {
912
- margin-top: 0;
913
- }
914
-
915
- .full-width-table-container {
916
- max-height: 200px;
1027
+ .log-table-container {
1028
+ flex: 1;
1029
+ min-height: 0;
917
1030
  overflow-y: auto;
918
1031
  border: 1px solid var(--border-default);
919
1032
  border-radius: var(--radius);
1033
+ box-sizing: border-box;
920
1034
  }
921
1035
 
922
1036
  .log-table {
@@ -1118,3 +1232,1057 @@ button {
1118
1232
  grid-template-columns: 1fr;
1119
1233
  }
1120
1234
  }
1235
+
1236
+ /* ==========================================================================
1237
+ TARGET URL CONTROLLER (HEADER)
1238
+ ========================================================================== */
1239
+ .target-url-control {
1240
+ display: flex;
1241
+ align-items: center;
1242
+ gap: 6px;
1243
+ background: var(--bg-subtle);
1244
+ border: 1px solid var(--border-default);
1245
+ padding: 3px 8px;
1246
+ border-radius: var(--radius);
1247
+ }
1248
+
1249
+ .target-label {
1250
+ font-size: 11px;
1251
+ font-weight: 600;
1252
+ color: var(--text-muted);
1253
+ white-space: nowrap;
1254
+ }
1255
+
1256
+ .input-target-url {
1257
+ background: var(--bg-surface);
1258
+ border: 1px solid var(--border-default);
1259
+ color: var(--text-main);
1260
+ font-family: var(--font-mono);
1261
+ font-size: 11px;
1262
+ padding: 3px 6px;
1263
+ border-radius: 4px;
1264
+ width: 170px;
1265
+ }
1266
+
1267
+ .input-target-url:focus {
1268
+ outline: none;
1269
+ border-color: var(--border-focus);
1270
+ }
1271
+
1272
+ .btn-target-apply {
1273
+ background: var(--btn-primary-bg);
1274
+ color: var(--btn-primary-fg);
1275
+ border: none;
1276
+ font-size: 11px;
1277
+ font-weight: 600;
1278
+ padding: 3px 8px;
1279
+ border-radius: 4px;
1280
+ cursor: pointer;
1281
+ white-space: nowrap;
1282
+ }
1283
+
1284
+ .btn-target-apply:hover {
1285
+ background: var(--text-main);
1286
+ }
1287
+
1288
+ /* ==========================================================================
1289
+ SCORECARD EXPORT CONTROLS
1290
+ ========================================================================== */
1291
+ .export-btn-group {
1292
+ display: flex;
1293
+ align-items: center;
1294
+ gap: 6px;
1295
+ }
1296
+
1297
+ .btn-export {
1298
+ font-size: 11px;
1299
+ padding: 7px 12px;
1300
+ }
1301
+
1302
+ /* ==========================================================================
1303
+ CODE FIX REMEDIATION BOXES
1304
+ ========================================================================== */
1305
+ .btn-toggle-snippet {
1306
+ background: transparent;
1307
+ border: 1px solid var(--border-default);
1308
+ color: var(--text-muted);
1309
+ font-size: 11px;
1310
+ font-family: var(--font-mono);
1311
+ padding: 4px 10px;
1312
+ border-radius: 4px;
1313
+ cursor: pointer;
1314
+ display: inline-flex;
1315
+ align-items: center;
1316
+ gap: 6px;
1317
+ margin-top: 8px;
1318
+ }
1319
+
1320
+ .btn-toggle-snippet:hover {
1321
+ color: var(--text-main);
1322
+ border-color: var(--border-focus);
1323
+ }
1324
+
1325
+ .snippet-container {
1326
+ margin-top: 10px;
1327
+ border: 1px solid var(--border-default);
1328
+ border-radius: var(--radius);
1329
+ background: var(--bg-subtle);
1330
+ overflow: hidden;
1331
+ }
1332
+
1333
+ .snippet-header {
1334
+ display: flex;
1335
+ justify-content: space-between;
1336
+ align-items: center;
1337
+ background: var(--bg-surface);
1338
+ border-bottom: 1px solid var(--border-subtle);
1339
+ padding: 6px 10px;
1340
+ }
1341
+
1342
+ .snippet-tabs {
1343
+ display: flex;
1344
+ gap: 4px;
1345
+ }
1346
+
1347
+ .snippet-tab-btn {
1348
+ background: transparent;
1349
+ border: 1px solid transparent;
1350
+ color: var(--text-muted);
1351
+ font-size: 11px;
1352
+ font-weight: 600;
1353
+ padding: 3px 8px;
1354
+ border-radius: 4px;
1355
+ cursor: pointer;
1356
+ }
1357
+
1358
+ .snippet-tab-btn.active {
1359
+ background: var(--bg-subtle);
1360
+ border-color: var(--border-default);
1361
+ color: var(--text-main);
1362
+ }
1363
+
1364
+ .btn-copy-snippet {
1365
+ background: var(--bg-subtle);
1366
+ border: 1px solid var(--border-default);
1367
+ color: var(--text-muted);
1368
+ font-size: 10px;
1369
+ font-family: var(--font-mono);
1370
+ padding: 2px 8px;
1371
+ border-radius: 4px;
1372
+ cursor: pointer;
1373
+ }
1374
+
1375
+ .btn-copy-snippet:hover {
1376
+ color: var(--text-main);
1377
+ border-color: var(--border-focus);
1378
+ }
1379
+
1380
+ .snippet-code-content {
1381
+ margin: 0;
1382
+ padding: 12px 14px;
1383
+ font-family: var(--font-mono);
1384
+ font-size: 11px;
1385
+ line-height: 1.5;
1386
+ color: var(--text-main);
1387
+ background: var(--bg-subtle);
1388
+ overflow-x: auto;
1389
+ white-space: pre;
1390
+ }
1391
+
1392
+ /* ==========================================================================
1393
+ AUTO-HEALER MODAL & UNIFIED DIFF VIEWER
1394
+ ========================================================================== */
1395
+
1396
+ .btn-healer-trigger {
1397
+ border-color: var(--tag-green-fg) !important;
1398
+ color: var(--tag-green-fg) !important;
1399
+ font-weight: 600;
1400
+ }
1401
+
1402
+ .btn-healer-trigger:hover {
1403
+ background: var(--tag-green-bg) !important;
1404
+ }
1405
+
1406
+ .modal-backdrop {
1407
+ position: fixed;
1408
+ inset: 0;
1409
+ background: rgba(0, 0, 0, 0.88);
1410
+ backdrop-filter: blur(12px);
1411
+ -webkit-backdrop-filter: blur(12px);
1412
+ z-index: 1000;
1413
+ display: flex;
1414
+ align-items: center;
1415
+ justify-content: center;
1416
+ padding: 24px;
1417
+ }
1418
+
1419
+ .modal-dialog {
1420
+ background: #ffffff;
1421
+ border: 2px solid var(--border-strong);
1422
+ border-radius: 12px;
1423
+ width: 100%;
1424
+ max-width: 860px;
1425
+ max-height: 90vh;
1426
+ display: flex;
1427
+ flex-direction: column;
1428
+ box-shadow: 0 32px 64px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(0, 0, 0, 0.2);
1429
+ overflow: hidden;
1430
+ opacity: 1;
1431
+ }
1432
+
1433
+ [data-theme="dark"] .modal-dialog {
1434
+ background: #151518;
1435
+ border: 2px solid rgba(255, 255, 255, 0.22);
1436
+ box-shadow: 0 36px 72px rgba(0, 0, 0, 0.95), 0 0 0 1px rgba(255, 255, 255, 0.12);
1437
+ }
1438
+
1439
+ .modal-header {
1440
+ display: flex;
1441
+ align-items: center;
1442
+ justify-content: space-between;
1443
+ padding: 16px 20px;
1444
+ border-bottom: 1px solid var(--border-default);
1445
+ background: #f8f8fa;
1446
+ }
1447
+
1448
+ [data-theme="dark"] .modal-header {
1449
+ background: #1a1a1f;
1450
+ }
1451
+
1452
+ .modal-title-group {
1453
+ display: flex;
1454
+ align-items: center;
1455
+ gap: 10px;
1456
+ }
1457
+
1458
+ .modal-badge {
1459
+ font-family: var(--font-mono);
1460
+ font-size: 10px;
1461
+ font-weight: 700;
1462
+ letter-spacing: 0.5px;
1463
+ padding: 2px 6px;
1464
+ background: var(--tag-green-bg);
1465
+ color: var(--tag-green-fg);
1466
+ border-radius: 4px;
1467
+ }
1468
+
1469
+ .modal-header h3 {
1470
+ font-size: 15px;
1471
+ font-weight: 700;
1472
+ color: var(--text-main);
1473
+ margin: 0;
1474
+ }
1475
+
1476
+ .btn-modal-close {
1477
+ font-size: 20px;
1478
+ line-height: 1;
1479
+ color: var(--text-muted);
1480
+ cursor: pointer;
1481
+ padding: 4px 8px;
1482
+ }
1483
+
1484
+ .btn-modal-close:hover {
1485
+ color: var(--text-main);
1486
+ }
1487
+
1488
+ .modal-body {
1489
+ padding: 20px;
1490
+ overflow-y: auto;
1491
+ display: flex;
1492
+ flex-direction: column;
1493
+ gap: 16px;
1494
+ }
1495
+
1496
+ .modal-intro {
1497
+ font-size: 13px;
1498
+ color: var(--text-muted);
1499
+ line-height: 1.5;
1500
+ margin: 0;
1501
+ }
1502
+
1503
+ .healer-config-row {
1504
+ display: flex;
1505
+ flex-direction: column;
1506
+ gap: 6px;
1507
+ }
1508
+
1509
+ .healer-config-row label {
1510
+ font-size: 12px;
1511
+ font-weight: 600;
1512
+ color: var(--text-main);
1513
+ }
1514
+
1515
+ .healer-input-group {
1516
+ display: flex;
1517
+ gap: 8px;
1518
+ }
1519
+
1520
+ .healer-input-group input {
1521
+ flex: 1;
1522
+ }
1523
+
1524
+ .healer-engine-bar {
1525
+ display: flex;
1526
+ align-items: center;
1527
+ justify-content: space-between;
1528
+ font-size: 11px;
1529
+ }
1530
+
1531
+ .btn-engine-toggle {
1532
+ color: var(--accent);
1533
+ font-size: 11px;
1534
+ cursor: pointer;
1535
+ text-decoration: underline;
1536
+ padding: 0;
1537
+ background: none;
1538
+ border: none;
1539
+ }
1540
+
1541
+ .btn-engine-toggle:hover {
1542
+ color: var(--accent-hover);
1543
+ }
1544
+
1545
+ .engine-badge {
1546
+ font-family: var(--font-mono);
1547
+ font-size: 10px;
1548
+ padding: 2px 6px;
1549
+ border-radius: 4px;
1550
+ font-weight: 600;
1551
+ }
1552
+
1553
+ .engine-badge.codemod {
1554
+ background: rgba(59, 130, 246, 0.15);
1555
+ color: #3b82f6;
1556
+ border: 1px solid rgba(59, 130, 246, 0.3);
1557
+ }
1558
+
1559
+ .engine-badge.ai-agent {
1560
+ background: rgba(168, 85, 247, 0.15);
1561
+ color: #a855f7;
1562
+ border: 1px solid rgba(168, 85, 247, 0.3);
1563
+ }
1564
+
1565
+ .healer-ai-panel {
1566
+ padding: 12px;
1567
+ background: var(--bg-subtle);
1568
+ border: 1px solid var(--border-default);
1569
+ border-radius: 6px;
1570
+ }
1571
+
1572
+ .ai-config-grid {
1573
+ display: grid;
1574
+ grid-template-columns: 1fr 1fr;
1575
+ gap: 10px;
1576
+ }
1577
+
1578
+ .ai-config-item {
1579
+ display: flex;
1580
+ flex-direction: column;
1581
+ gap: 4px;
1582
+ }
1583
+
1584
+ .ai-config-item label {
1585
+ font-size: 11px;
1586
+ font-weight: 600;
1587
+ color: var(--text-muted);
1588
+ }
1589
+
1590
+ .ai-config-item select,
1591
+ .ai-config-item input {
1592
+ font-size: 11px;
1593
+ padding: 6px 8px;
1594
+ }
1595
+
1596
+ .healer-status-bar {
1597
+ padding: 10px 14px;
1598
+ border-radius: 6px;
1599
+ font-size: 12px;
1600
+ line-height: 1.4;
1601
+ background: var(--bg-subtle);
1602
+ border: 1px solid var(--border-default);
1603
+ }
1604
+
1605
+ .healer-diff-wrapper {
1606
+ display: flex;
1607
+ flex-direction: column;
1608
+ gap: 14px;
1609
+ max-height: 440px;
1610
+ overflow-y: auto;
1611
+ padding-right: 6px;
1612
+ }
1613
+
1614
+ .diff-card {
1615
+ flex-shrink: 0;
1616
+ border: 1.5px solid var(--border-strong);
1617
+ border-radius: 8px;
1618
+ overflow: hidden;
1619
+ background: var(--bg-card);
1620
+ box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
1621
+ }
1622
+
1623
+ [data-theme="dark"] .diff-card {
1624
+ background: #18181d;
1625
+ border-color: rgba(255, 255, 255, 0.14);
1626
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
1627
+ }
1628
+
1629
+ .diff-card-header {
1630
+ display: flex;
1631
+ align-items: center;
1632
+ justify-content: space-between;
1633
+ padding: 8px 12px;
1634
+ background: var(--bg-subtle);
1635
+ border-bottom: 1px solid var(--border-default);
1636
+ font-size: 12px;
1637
+ }
1638
+
1639
+ .diff-card-title {
1640
+ font-weight: 600;
1641
+ color: var(--text-main);
1642
+ }
1643
+
1644
+ .diff-card-file {
1645
+ font-family: var(--font-mono);
1646
+ font-size: 11px;
1647
+ color: var(--text-muted);
1648
+ }
1649
+
1650
+ .diff-pre {
1651
+ margin: 0;
1652
+ padding: 8px 0;
1653
+ font-family: var(--font-mono);
1654
+ font-size: 11px;
1655
+ line-height: 1.5;
1656
+ background: var(--bg-subtle);
1657
+ color: var(--text-main);
1658
+ overflow-x: auto;
1659
+ white-space: pre;
1660
+ }
1661
+
1662
+ .diff-line {
1663
+ display: block;
1664
+ padding: 1px 12px;
1665
+ min-height: 18px;
1666
+ }
1667
+
1668
+ .diff-line.add {
1669
+ color: #10b981;
1670
+ background: rgba(16, 185, 129, 0.15);
1671
+ }
1672
+
1673
+ .diff-line.del {
1674
+ color: #ef4444;
1675
+ background: rgba(239, 68, 68, 0.15);
1676
+ }
1677
+
1678
+ .diff-line.info {
1679
+ color: #3b82f6;
1680
+ font-weight: 600;
1681
+ background: rgba(59, 130, 246, 0.08);
1682
+ border-top: 1px solid rgba(59, 130, 246, 0.15);
1683
+ border-bottom: 1px solid rgba(59, 130, 246, 0.15);
1684
+ }
1685
+
1686
+ .diff-line.file-header {
1687
+ color: var(--text-muted);
1688
+ font-weight: 600;
1689
+ }
1690
+
1691
+ .diff-line.context {
1692
+ color: var(--text-muted);
1693
+ }
1694
+
1695
+ .healer-actions-bar {
1696
+ display: flex;
1697
+ align-items: center;
1698
+ justify-content: space-between;
1699
+ padding-top: 12px;
1700
+ border-top: 1px solid var(--border-default);
1701
+ }
1702
+
1703
+ .backup-checkbox-label {
1704
+ display: flex;
1705
+ align-items: center;
1706
+ gap: 6px;
1707
+ font-size: 12px;
1708
+ color: var(--text-muted);
1709
+ cursor: pointer;
1710
+ }
1711
+
1712
+ .healer-btn-group {
1713
+ display: flex;
1714
+ gap: 8px;
1715
+ }
1716
+
1717
+ /* ==========================================================================
1718
+ AUTONOMOUS RED CHAOS TEAM ENGINE STYLES
1719
+ ========================================================================== */
1720
+
1721
+ .diag-tab-redteam {
1722
+ border-left: 2px solid var(--tag-red-fg) !important;
1723
+ }
1724
+
1725
+ .diag-tab-redteam.active {
1726
+ background: var(--tag-red-bg) !important;
1727
+ color: var(--tag-red-fg) !important;
1728
+ border-color: var(--tag-red-border) !important;
1729
+ }
1730
+
1731
+ .redteam-panel {
1732
+ display: flex;
1733
+ flex-direction: column;
1734
+ gap: 16px;
1735
+ margin-top: 8px;
1736
+ }
1737
+
1738
+ .redteam-squadron-header {
1739
+ display: flex;
1740
+ justify-content: space-between;
1741
+ align-items: center;
1742
+ padding-bottom: 8px;
1743
+ border-bottom: 1px solid var(--border-subtle);
1744
+ }
1745
+
1746
+ .squadron-title-group {
1747
+ display: flex;
1748
+ align-items: center;
1749
+ gap: 8px;
1750
+ }
1751
+
1752
+ .squadron-badge {
1753
+ font-family: var(--font-mono);
1754
+ font-size: 10px;
1755
+ font-weight: 700;
1756
+ letter-spacing: 0.6px;
1757
+ text-transform: uppercase;
1758
+ color: var(--tag-red-fg);
1759
+ background: var(--tag-red-bg);
1760
+ border: 1px solid var(--tag-red-border);
1761
+ padding: 2px 6px;
1762
+ border-radius: 4px;
1763
+ }
1764
+
1765
+ .squadron-title-group h4 {
1766
+ font-size: 13px;
1767
+ font-weight: 700;
1768
+ color: var(--text-main);
1769
+ }
1770
+
1771
+ .squadron-status-tag {
1772
+ font-family: var(--font-mono);
1773
+ font-size: 11px;
1774
+ font-weight: 600;
1775
+ color: var(--text-muted);
1776
+ }
1777
+
1778
+ .redteam-personas-grid {
1779
+ display: grid;
1780
+ grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
1781
+ gap: 10px;
1782
+ }
1783
+
1784
+ .persona-card {
1785
+ display: flex;
1786
+ flex-direction: column;
1787
+ gap: 6px;
1788
+ padding: 12px 14px;
1789
+ background: var(--bg-surface);
1790
+ border: 1px solid var(--border-default);
1791
+ border-radius: var(--radius);
1792
+ transition: border-color 0.15s ease, transform 0.15s ease;
1793
+ }
1794
+
1795
+ .persona-card:hover {
1796
+ border-color: var(--border-strong);
1797
+ }
1798
+
1799
+ .persona-card.persona-active {
1800
+ border-color: var(--tag-red-fg);
1801
+ background: var(--tag-red-bg);
1802
+ }
1803
+
1804
+ .persona-top {
1805
+ display: flex;
1806
+ justify-content: space-between;
1807
+ align-items: center;
1808
+ }
1809
+
1810
+ .persona-callsign {
1811
+ font-family: var(--font-mono);
1812
+ font-size: 10px;
1813
+ font-weight: 700;
1814
+ letter-spacing: 0.5px;
1815
+ color: var(--text-main);
1816
+ background: var(--bg-subtle);
1817
+ border: 1px solid var(--border-default);
1818
+ padding: 1px 6px;
1819
+ border-radius: 4px;
1820
+ }
1821
+
1822
+ .persona-role-tag {
1823
+ font-size: 10px;
1824
+ font-family: var(--font-mono);
1825
+ color: var(--text-muted);
1826
+ }
1827
+
1828
+ .persona-name {
1829
+ font-size: 12px;
1830
+ font-weight: 600;
1831
+ color: var(--text-main);
1832
+ }
1833
+
1834
+ .persona-desc {
1835
+ font-size: 11px;
1836
+ color: var(--text-muted);
1837
+ line-height: 1.35;
1838
+ }
1839
+
1840
+ /* Control Bar */
1841
+ .redteam-control-bar {
1842
+ display: flex;
1843
+ justify-content: space-between;
1844
+ align-items: center;
1845
+ flex-wrap: wrap;
1846
+ gap: 12px;
1847
+ padding: 12px 16px;
1848
+ background: var(--bg-subtle);
1849
+ border: 1px solid var(--border-default);
1850
+ border-radius: var(--radius);
1851
+ }
1852
+
1853
+ .redteam-config-group {
1854
+ display: flex;
1855
+ align-items: center;
1856
+ gap: 10px;
1857
+ }
1858
+
1859
+ .redteam-config-group label {
1860
+ font-size: 12px;
1861
+ font-weight: 600;
1862
+ color: var(--text-muted);
1863
+ }
1864
+
1865
+ .redteam-select {
1866
+ min-width: 280px;
1867
+ font-size: 12px;
1868
+ }
1869
+
1870
+ .redteam-btn-group {
1871
+ display: flex;
1872
+ align-items: center;
1873
+ gap: 8px;
1874
+ }
1875
+
1876
+ .btn-redteam-launch {
1877
+ background: var(--tag-red-fg) !important;
1878
+ color: #fff !important;
1879
+ border: 1px solid transparent !important;
1880
+ }
1881
+
1882
+ .btn-redteam-launch:hover {
1883
+ filter: brightness(1.1);
1884
+ }
1885
+
1886
+ .btn-redteam-abort {
1887
+ color: var(--tag-red-fg) !important;
1888
+ border-color: var(--tag-red-border) !important;
1889
+ }
1890
+
1891
+ /* Real-time Tactical HUD */
1892
+ .redteam-hud {
1893
+ display: flex;
1894
+ flex-direction: column;
1895
+ gap: 12px;
1896
+ padding: 16px 18px;
1897
+ background: var(--bg-surface);
1898
+ border: 1px solid var(--border-strong);
1899
+ border-radius: var(--radius);
1900
+ }
1901
+
1902
+ .redteam-phase-pipeline {
1903
+ display: flex;
1904
+ justify-content: space-between;
1905
+ align-items: center;
1906
+ flex-wrap: wrap;
1907
+ gap: 8px;
1908
+ padding-bottom: 12px;
1909
+ border-bottom: 1px solid var(--border-default);
1910
+ }
1911
+
1912
+ .phase-step {
1913
+ display: inline-flex;
1914
+ align-items: center;
1915
+ gap: 6px;
1916
+ font-family: var(--font-mono);
1917
+ font-size: 11px;
1918
+ font-weight: 600;
1919
+ color: var(--text-subtle);
1920
+ padding: 4px 8px;
1921
+ border-radius: 4px;
1922
+ }
1923
+
1924
+ .phase-dot {
1925
+ width: 7px;
1926
+ height: 7px;
1927
+ border-radius: 50%;
1928
+ background: var(--border-default);
1929
+ }
1930
+
1931
+ .phase-step.active {
1932
+ color: var(--tag-red-fg);
1933
+ background: var(--tag-red-bg);
1934
+ border: 1px solid var(--tag-red-border);
1935
+ }
1936
+
1937
+ .phase-step.active .phase-dot {
1938
+ background: var(--tag-red-fg);
1939
+ box-shadow: 0 0 6px var(--tag-red-fg);
1940
+ }
1941
+
1942
+ .phase-step.completed {
1943
+ color: var(--tag-green-fg);
1944
+ }
1945
+
1946
+ .phase-step.completed .phase-dot {
1947
+ background: var(--tag-green-fg);
1948
+ }
1949
+
1950
+ /* Progress Bar */
1951
+ .redteam-progress-bar-wrapper {
1952
+ display: flex;
1953
+ flex-direction: column;
1954
+ gap: 6px;
1955
+ }
1956
+
1957
+ .redteam-progress-info {
1958
+ display: flex;
1959
+ justify-content: space-between;
1960
+ align-items: center;
1961
+ font-size: 12px;
1962
+ }
1963
+
1964
+ .redteam-track {
1965
+ width: 100%;
1966
+ height: 8px;
1967
+ background: var(--bg-subtle);
1968
+ border: 1px solid var(--border-default);
1969
+ border-radius: 4px;
1970
+ overflow: hidden;
1971
+ }
1972
+
1973
+ .redteam-bar {
1974
+ height: 100%;
1975
+ background: var(--tag-red-fg);
1976
+ transition: width 0.25s ease;
1977
+ }
1978
+
1979
+ /* Telemetry Strip */
1980
+ .redteam-telemetry-strip {
1981
+ display: flex;
1982
+ align-items: center;
1983
+ flex-wrap: wrap;
1984
+ gap: 10px;
1985
+ }
1986
+
1987
+ .telemetry-pill {
1988
+ display: inline-flex;
1989
+ align-items: center;
1990
+ gap: 6px;
1991
+ padding: 4px 10px;
1992
+ background: var(--bg-subtle);
1993
+ border: 1px solid var(--border-default);
1994
+ border-radius: 4px;
1995
+ font-family: var(--font-mono);
1996
+ font-size: 11px;
1997
+ }
1998
+
1999
+ .telemetry-label {
2000
+ color: var(--text-muted);
2001
+ }
2002
+
2003
+ .telemetry-val {
2004
+ font-weight: 700;
2005
+ color: var(--text-main);
2006
+ font-variant-numeric: tabular-nums;
2007
+ }
2008
+
2009
+ .pill-critical .telemetry-val {
2010
+ color: var(--tag-red-fg);
2011
+ }
2012
+
2013
+ .pill-high .telemetry-val {
2014
+ color: var(--tag-amber-fg);
2015
+ }
2016
+
2017
+ /* Tactical Console */
2018
+ .redteam-console-wrapper {
2019
+ display: flex;
2020
+ flex-direction: column;
2021
+ border: 1px solid var(--border-default);
2022
+ border-radius: var(--radius);
2023
+ overflow: hidden;
2024
+ }
2025
+
2026
+ .console-header {
2027
+ display: flex;
2028
+ justify-content: space-between;
2029
+ align-items: center;
2030
+ padding: 6px 12px;
2031
+ background: var(--bg-subtle);
2032
+ border-bottom: 1px solid var(--border-default);
2033
+ font-family: var(--font-mono);
2034
+ font-size: 10px;
2035
+ font-weight: 700;
2036
+ letter-spacing: 0.5px;
2037
+ color: var(--text-muted);
2038
+ }
2039
+
2040
+ .active-persona-pill {
2041
+ font-size: 10px;
2042
+ padding: 2px 6px;
2043
+ border-radius: 4px;
2044
+ background: var(--bg-surface);
2045
+ border: 1px solid var(--border-default);
2046
+ color: var(--text-main);
2047
+ }
2048
+
2049
+ .redteam-terminal-log {
2050
+ height: 160px;
2051
+ overflow-y: auto;
2052
+ padding: 10px 14px;
2053
+ background: #0d1117;
2054
+ color: #c9d1d9;
2055
+ font-family: var(--font-mono);
2056
+ font-size: 11px;
2057
+ line-height: 1.5;
2058
+ }
2059
+
2060
+ [data-theme="light"] .redteam-terminal-log {
2061
+ background: #1e1e24;
2062
+ color: #f0f6fc;
2063
+ }
2064
+
2065
+ .terminal-line {
2066
+ white-space: pre-wrap;
2067
+ word-break: break-word;
2068
+ }
2069
+
2070
+ .terminal-line.log-info { color: #8b949e; }
2071
+ .terminal-line.log-pass { color: #3fb950; font-weight: 600; }
2072
+ .terminal-line.log-warn { color: #d29922; }
2073
+ .terminal-line.log-breach { color: #f85149; font-weight: 700; }
2074
+
2075
+ /* Post-Campaign Debrief Dossier */
2076
+ .redteam-dossier {
2077
+ display: flex;
2078
+ flex-direction: column;
2079
+ gap: 16px;
2080
+ padding: 20px;
2081
+ background: var(--bg-surface);
2082
+ border: 1px solid var(--border-strong);
2083
+ border-left: 4px solid var(--tag-red-fg);
2084
+ border-radius: var(--radius);
2085
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
2086
+ }
2087
+
2088
+ .dossier-header-bar {
2089
+ display: flex;
2090
+ justify-content: space-between;
2091
+ align-items: center;
2092
+ flex-wrap: wrap;
2093
+ gap: 16px;
2094
+ padding-bottom: 16px;
2095
+ border-bottom: 1px solid var(--border-default);
2096
+ }
2097
+
2098
+ .dossier-score-badge {
2099
+ display: flex;
2100
+ flex-direction: column;
2101
+ align-items: center;
2102
+ justify-content: center;
2103
+ min-width: 80px;
2104
+ padding: 8px 14px;
2105
+ background: var(--bg-subtle);
2106
+ border: 1px solid var(--border-default);
2107
+ border-radius: var(--radius);
2108
+ }
2109
+
2110
+ .dossier-score-num {
2111
+ font-family: var(--font-mono);
2112
+ font-size: 26px;
2113
+ font-weight: 800;
2114
+ color: var(--text-main);
2115
+ line-height: 1;
2116
+ }
2117
+
2118
+ .dossier-grade-tag {
2119
+ font-family: var(--font-mono);
2120
+ font-size: 11px;
2121
+ font-weight: 700;
2122
+ color: var(--text-muted);
2123
+ margin-top: 4px;
2124
+ }
2125
+
2126
+ .dossier-summary-col {
2127
+ flex: 1;
2128
+ display: flex;
2129
+ flex-direction: column;
2130
+ gap: 4px;
2131
+ min-width: 220px;
2132
+ }
2133
+
2134
+ .dossier-summary-col h3 {
2135
+ font-size: 15px;
2136
+ font-weight: 700;
2137
+ color: var(--text-main);
2138
+ }
2139
+
2140
+ .dossier-summary-col p {
2141
+ font-size: 12px;
2142
+ color: var(--text-muted);
2143
+ line-height: 1.4;
2144
+ }
2145
+
2146
+ .dossier-action-col {
2147
+ display: flex;
2148
+ flex-direction: column;
2149
+ align-items: flex-end;
2150
+ gap: 8px;
2151
+ }
2152
+
2153
+ .dossier-export-group {
2154
+ display: flex;
2155
+ gap: 6px;
2156
+ }
2157
+
2158
+ .dossier-findings-section {
2159
+ display: flex;
2160
+ flex-direction: column;
2161
+ gap: 10px;
2162
+ }
2163
+
2164
+ .findings-header {
2165
+ display: flex;
2166
+ justify-content: space-between;
2167
+ align-items: center;
2168
+ }
2169
+
2170
+ .findings-title {
2171
+ font-size: 12px;
2172
+ font-weight: 700;
2173
+ color: var(--text-main);
2174
+ text-transform: uppercase;
2175
+ letter-spacing: 0.5px;
2176
+ }
2177
+
2178
+ .dossier-findings-list {
2179
+ display: flex;
2180
+ flex-direction: column;
2181
+ gap: 10px;
2182
+ }
2183
+
2184
+ .breach-card {
2185
+ display: flex;
2186
+ flex-direction: column;
2187
+ gap: 8px;
2188
+ padding: 14px 18px;
2189
+ background: var(--bg-card);
2190
+ border: 1.5px solid var(--border-default);
2191
+ border-radius: 8px;
2192
+ font-size: 12px;
2193
+ box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06);
2194
+ }
2195
+
2196
+ [data-theme="dark"] .breach-card {
2197
+ background: #18181d;
2198
+ border-color: rgba(255, 255, 255, 0.12);
2199
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
2200
+ }
2201
+
2202
+ .breach-card.severity-critical {
2203
+ border-left: 4px solid var(--tag-red-fg);
2204
+ }
2205
+
2206
+ .breach-card.severity-high {
2207
+ border-left: 4px solid var(--tag-amber-fg);
2208
+ }
2209
+
2210
+ .breach-card.severity-medium {
2211
+ border-left: 4px solid var(--text-main);
2212
+ }
2213
+
2214
+ .breach-card-top {
2215
+ display: flex;
2216
+ justify-content: space-between;
2217
+ align-items: center;
2218
+ }
2219
+
2220
+ .breach-title-wrap {
2221
+ display: flex;
2222
+ align-items: center;
2223
+ gap: 8px;
2224
+ }
2225
+
2226
+ .breach-title {
2227
+ font-weight: 700;
2228
+ color: var(--text-main);
2229
+ font-size: 13px;
2230
+ }
2231
+
2232
+ .breach-endpoint {
2233
+ font-family: var(--font-mono);
2234
+ font-size: 11px;
2235
+ color: var(--text-subtle);
2236
+ }
2237
+
2238
+ .breach-desc {
2239
+ font-size: 12px;
2240
+ color: var(--text-muted);
2241
+ line-height: 1.4;
2242
+ }
2243
+
2244
+ .breach-proof-box {
2245
+ padding: 8px 12px;
2246
+ background: var(--bg-surface);
2247
+ border: 1px solid var(--border-default);
2248
+ border-radius: 4px;
2249
+ font-family: var(--font-mono);
2250
+ font-size: 11px;
2251
+ color: var(--text-muted);
2252
+ overflow-x: auto;
2253
+ }
2254
+
2255
+ .breach-remedy {
2256
+ font-size: 11px;
2257
+ color: var(--tag-green-fg);
2258
+ background: var(--tag-green-bg);
2259
+ border: 1px solid var(--tag-green-border);
2260
+ padding: 4px 8px;
2261
+ border-radius: 4px;
2262
+ display: inline-block;
2263
+ }
2264
+
2265
+ @media (max-width: 1024px) {
2266
+ .columns-grid {
2267
+ grid-template-columns: minmax(0, 1fr);
2268
+ }
2269
+
2270
+ .presets-card,
2271
+ .response-inspector-card,
2272
+ .custom-rule-card,
2273
+ .active-rules-card,
2274
+ .live-log-card {
2275
+ grid-column: 1 !important;
2276
+ grid-row: auto !important;
2277
+ height: auto !important;
2278
+ }
2279
+
2280
+ .response-body-pre {
2281
+ max-height: 240px;
2282
+ }
2283
+
2284
+ .log-table-container {
2285
+ max-height: 260px;
2286
+ }
2287
+ }
2288
+