@rulebricks/cli 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,632 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Throughput Benchmark Report - Rulebricks</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
10
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
11
+ <style>
12
+ :root {
13
+ --bg-primary: #0a0a0a;
14
+ --bg-secondary: #141414;
15
+ --bg-tertiary: #1f1f1f;
16
+ --bg-hover: #2a2a2a;
17
+ --text-primary: #fafafa;
18
+ --text-secondary: #a1a1a1;
19
+ --text-muted: #6b6b6b;
20
+ --border: #2a2a2a;
21
+ --border-light: #333;
22
+ --accent: #a78bfa;
23
+ --accent-cyan: #22d3ee;
24
+ --accent-green: #4ade80;
25
+ --accent-yellow: #fbbf24;
26
+ --accent-red: #f87171;
27
+ --accent-pink: #f472b6;
28
+ }
29
+
30
+ * {
31
+ margin: 0;
32
+ padding: 0;
33
+ box-sizing: border-box;
34
+ }
35
+
36
+ body {
37
+ font-family: 'Archivo', -apple-system, BlinkMacSystemFont, sans-serif;
38
+ background: var(--bg-primary);
39
+ color: var(--text-primary);
40
+ line-height: 1.6;
41
+ min-height: 100vh;
42
+ }
43
+
44
+ .container {
45
+ max-width: 1280px;
46
+ margin: 0 auto;
47
+ padding: 2.5rem;
48
+ }
49
+
50
+ header {
51
+ margin-bottom: 2.5rem;
52
+ padding-bottom: 2rem;
53
+ border-bottom: 1px solid var(--border);
54
+ }
55
+
56
+ .header-top {
57
+ display: flex;
58
+ align-items: center;
59
+ justify-content: space-between;
60
+ margin-bottom: 1.5rem;
61
+ }
62
+
63
+ .logo {
64
+ font-size: 0.75rem;
65
+ font-weight: 600;
66
+ letter-spacing: 0.15em;
67
+ text-transform: uppercase;
68
+ color: var(--text-muted);
69
+ }
70
+
71
+ .timestamp {
72
+ font-size: 0.8rem;
73
+ color: var(--text-muted);
74
+ font-family: 'JetBrains Mono', monospace;
75
+ }
76
+
77
+ h1 {
78
+ font-size: 2rem;
79
+ font-weight: 700;
80
+ margin-bottom: 0.5rem;
81
+ letter-spacing: -0.02em;
82
+ }
83
+
84
+ .subtitle {
85
+ color: var(--text-secondary);
86
+ font-size: 1rem;
87
+ }
88
+
89
+ .grid {
90
+ display: grid;
91
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
92
+ gap: 1rem;
93
+ margin-bottom: 1.5rem;
94
+ }
95
+
96
+ .grid-6 {
97
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
98
+ }
99
+
100
+ .card {
101
+ background: var(--bg-secondary);
102
+ border-radius: 4px;
103
+ padding: 1.25rem;
104
+ border: 1px solid var(--border);
105
+ transition: border-color 0.15s ease;
106
+ }
107
+
108
+ .card:hover {
109
+ border-color: var(--border-light);
110
+ }
111
+
112
+ .card-header {
113
+ display: flex;
114
+ align-items: center;
115
+ justify-content: space-between;
116
+ margin-bottom: 0.75rem;
117
+ }
118
+
119
+ .card-title {
120
+ font-size: 0.7rem;
121
+ font-weight: 600;
122
+ text-transform: uppercase;
123
+ letter-spacing: 0.08em;
124
+ color: var(--text-muted);
125
+ }
126
+
127
+ .card-value {
128
+ font-size: 2rem;
129
+ font-weight: 700;
130
+ line-height: 1.1;
131
+ letter-spacing: -0.02em;
132
+ }
133
+
134
+ .card-value-sm {
135
+ font-size: 1.5rem;
136
+ }
137
+
138
+ .card-subtitle {
139
+ color: var(--text-muted);
140
+ font-size: 0.8rem;
141
+ margin-top: 0.5rem;
142
+ }
143
+
144
+ .status-indicator {
145
+ width: 8px;
146
+ height: 8px;
147
+ border-radius: 2px;
148
+ display: inline-block;
149
+ }
150
+
151
+ .section {
152
+ margin-bottom: 1.5rem;
153
+ }
154
+
155
+ .section-title {
156
+ font-size: 0.7rem;
157
+ font-weight: 600;
158
+ text-transform: uppercase;
159
+ letter-spacing: 0.1em;
160
+ color: var(--text-muted);
161
+ margin-bottom: 1rem;
162
+ padding-bottom: 0.5rem;
163
+ border-bottom: 1px solid var(--border);
164
+ }
165
+
166
+ .chart-container {
167
+ background: var(--bg-secondary);
168
+ border-radius: 4px;
169
+ padding: 1.5rem;
170
+ border: 1px solid var(--border);
171
+ margin-bottom: 1.5rem;
172
+ }
173
+
174
+ .chart-header {
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: space-between;
178
+ margin-bottom: 1rem;
179
+ }
180
+
181
+ .chart-title {
182
+ font-size: 0.9rem;
183
+ font-weight: 600;
184
+ }
185
+
186
+ .chart-wrapper {
187
+ position: relative;
188
+ height: 280px;
189
+ }
190
+
191
+ .two-col {
192
+ display: grid;
193
+ grid-template-columns: 1fr 1fr;
194
+ gap: 1.5rem;
195
+ }
196
+
197
+ @media (max-width: 768px) {
198
+ .two-col {
199
+ grid-template-columns: 1fr;
200
+ }
201
+ }
202
+
203
+ .metrics-table {
204
+ width: 100%;
205
+ border-collapse: collapse;
206
+ font-size: 0.85rem;
207
+ }
208
+
209
+ .metrics-table th,
210
+ .metrics-table td {
211
+ padding: 0.75rem 1rem;
212
+ text-align: left;
213
+ border-bottom: 1px solid var(--border);
214
+ }
215
+
216
+ .metrics-table th {
217
+ color: var(--text-muted);
218
+ font-weight: 500;
219
+ font-size: 0.7rem;
220
+ text-transform: uppercase;
221
+ letter-spacing: 0.08em;
222
+ }
223
+
224
+ .metrics-table td {
225
+ font-family: 'JetBrains Mono', monospace;
226
+ font-size: 0.8rem;
227
+ }
228
+
229
+ .metrics-table tr:last-child td {
230
+ border-bottom: none;
231
+ }
232
+
233
+ .config-grid {
234
+ display: grid;
235
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
236
+ gap: 0.75rem;
237
+ }
238
+
239
+ .config-item {
240
+ display: flex;
241
+ flex-direction: column;
242
+ gap: 0.25rem;
243
+ padding: 0.75rem;
244
+ background: var(--bg-tertiary);
245
+ border-radius: 3px;
246
+ }
247
+
248
+ .config-key {
249
+ font-size: 0.7rem;
250
+ font-weight: 500;
251
+ text-transform: uppercase;
252
+ letter-spacing: 0.08em;
253
+ color: var(--text-muted);
254
+ }
255
+
256
+ .config-value {
257
+ font-family: 'JetBrains Mono', monospace;
258
+ font-size: 0.8rem;
259
+ color: var(--accent-cyan);
260
+ word-break: break-all;
261
+ }
262
+
263
+ footer {
264
+ text-align: center;
265
+ padding-top: 2rem;
266
+ margin-top: 1rem;
267
+ border-top: 1px solid var(--border);
268
+ color: var(--text-muted);
269
+ font-size: 0.75rem;
270
+ }
271
+
272
+ .tag {
273
+ display: inline-block;
274
+ padding: 0.2rem 0.5rem;
275
+ border-radius: 2px;
276
+ font-size: 0.65rem;
277
+ font-weight: 600;
278
+ text-transform: uppercase;
279
+ letter-spacing: 0.05em;
280
+ }
281
+
282
+ .tag-success { background: rgba(74, 222, 128, 0.15); color: var(--accent-green); }
283
+ .tag-warning { background: rgba(251, 191, 36, 0.15); color: var(--accent-yellow); }
284
+ .tag-error { background: rgba(248, 113, 113, 0.15); color: var(--accent-red); }
285
+
286
+ .highlight { color: var(--accent-cyan); }
287
+ .highlight-pink { color: var(--accent-pink); }
288
+ .highlight-purple { color: var(--accent); }
289
+ </style>
290
+ </head>
291
+ <body>
292
+ <div class="container">
293
+ <header>
294
+ <div class="header-top">
295
+ <div class="logo">Rulebricks Benchmark</div>
296
+ <div class="timestamp">12/12/2025, 13:45:56</div>
297
+ </div>
298
+ <h1>Throughput Benchmark Report</h1>
299
+ <p class="subtitle">Throughput (Solutions/Second) · Measures rule engine capacity with bulk payload requests</p>
300
+ </header>
301
+
302
+ <div class="section">
303
+ <div class="section-title">Performance Overview</div>
304
+ <div class="grid">
305
+ <div class="card">
306
+ <div class="card-header">
307
+ <span class="card-title">Total Requests</span>
308
+ </div>
309
+ <div class="card-value">30001</div>
310
+ <div class="card-subtitle">Over 5.00 min</div>
311
+ </div>
312
+
313
+ <div class="card">
314
+ <div class="card-header">
315
+ <span class="card-title">Success Rate</span>
316
+ <span class="status-indicator" style="background: #4ade80"></span>
317
+ </div>
318
+ <div class="card-value" style="color: #4ade80">100.0%</div>
319
+ <div class="card-subtitle">0 failed</div>
320
+ </div>
321
+
322
+ <div class="card">
323
+ <div class="card-header">
324
+ <span class="card-title">Actual RPS</span>
325
+ </div>
326
+ <div class="card-value"><span class="highlight">99.9</span></div>
327
+ <div class="card-subtitle">100% of target (100)</div>
328
+ </div>
329
+
330
+ <div class="card">
331
+ <div class="card-header">
332
+ <span class="card-title">P95 Latency</span>
333
+ <span class="status-indicator" style="background: #4ade80"></span>
334
+ </div>
335
+ <div class="card-value" style="color: #4ade80">316<span style="font-size: 1rem; opacity: 0.7">ms</span></div>
336
+ <div class="card-subtitle">P99: 0ms</div>
337
+ </div>
338
+
339
+
340
+ <div class="card">
341
+ <div class="card-header">
342
+ <span class="card-title">Throughput</span>
343
+ </div>
344
+ <div class="card-value"><span class="highlight-pink">4996</span></div>
345
+ <div class="card-subtitle">Solutions/sec (50/req)</div>
346
+ </div>
347
+
348
+ <div class="card">
349
+ <div class="card-header">
350
+ <span class="card-title">Total Payloads</span>
351
+ </div>
352
+ <div class="card-value">1200000</div>
353
+ <div class="card-subtitle">1200000 processed</div>
354
+ </div>
355
+
356
+ </div>
357
+ </div>
358
+
359
+ <div class="two-col">
360
+ <div class="chart-container">
361
+ <div class="chart-header">
362
+ <h3 class="chart-title">Response Time Distribution</h3>
363
+ </div>
364
+ <div class="chart-wrapper">
365
+ <canvas id="latencyChart"></canvas>
366
+ </div>
367
+ </div>
368
+
369
+ <div class="chart-container">
370
+ <div class="chart-header">
371
+ <h3 class="chart-title">Request Timing Breakdown</h3>
372
+ </div>
373
+ <div class="chart-wrapper">
374
+ <canvas id="timingChart"></canvas>
375
+ </div>
376
+ </div>
377
+ </div>
378
+
379
+ <div class="section">
380
+ <div class="section-title">Detailed Metrics</div>
381
+ <div class="two-col">
382
+ <div class="card">
383
+ <table class="metrics-table">
384
+ <thead>
385
+ <tr>
386
+ <th>Latency Metric</th>
387
+ <th>Value</th>
388
+ </tr>
389
+ </thead>
390
+ <tbody>
391
+ <tr>
392
+ <td>Minimum</td>
393
+ <td>97.82 ms</td>
394
+ </tr>
395
+ <tr>
396
+ <td>Average</td>
397
+ <td>204.29 ms</td>
398
+ </tr>
399
+ <tr>
400
+ <td>Median (P50)</td>
401
+ <td>193.16 ms</td>
402
+ </tr>
403
+ <tr>
404
+ <td>P90</td>
405
+ <td>283.41 ms</td>
406
+ </tr>
407
+ <tr>
408
+ <td>P95</td>
409
+ <td>316.35 ms</td>
410
+ </tr>
411
+ <tr>
412
+ <td>P99</td>
413
+ <td>0.00 ms</td>
414
+ </tr>
415
+ <tr>
416
+ <td>Maximum</td>
417
+ <td>990.43 ms</td>
418
+ </tr>
419
+ </tbody>
420
+ </table>
421
+ </div>
422
+
423
+ <div class="card">
424
+ <table class="metrics-table">
425
+ <thead>
426
+ <tr>
427
+ <th>Transfer Metric</th>
428
+ <th>Value</th>
429
+ </tr>
430
+ </thead>
431
+ <tbody>
432
+ <tr>
433
+ <td>Data Sent</td>
434
+ <td>99.36 MB</td>
435
+ </tr>
436
+ <tr>
437
+ <td>Data Received</td>
438
+ <td>390.79 MB</td>
439
+ </tr>
440
+ <tr>
441
+ <td>Avg Request Size</td>
442
+ <td>3.39 KB</td>
443
+ </tr>
444
+ <tr>
445
+ <td>Avg Response Size</td>
446
+ <td>13.34 KB</td>
447
+ </tr>
448
+ <tr>
449
+ <td>Avg Connecting</td>
450
+ <td>0.76 ms</td>
451
+ </tr>
452
+ <tr>
453
+ <td>Avg TLS Handshake</td>
454
+ <td>0.91 ms</td>
455
+ </tr>
456
+ <tr>
457
+ <td>Avg Waiting (TTFB)</td>
458
+ <td>201.83 ms</td>
459
+ </tr>
460
+ </tbody>
461
+ </table>
462
+ </div>
463
+ </div>
464
+ </div>
465
+
466
+ <div class="section">
467
+ <div class="section-title">Test Configuration</div>
468
+ <div class="config-grid">
469
+ <div class="config-item">
470
+ <span class="config-key">API URL</span>
471
+ <span class="config-value">https://bench.rulebricks.com/api/v1/flows/ds_f3LwY7c</span>
472
+ </div>
473
+ <div class="config-item">
474
+ <span class="config-key">Test Duration</span>
475
+ <span class="config-value">4m</span>
476
+ </div>
477
+ <div class="config-item">
478
+ <span class="config-key">Target RPS</span>
479
+ <span class="config-value">100</span>
480
+ </div>
481
+
482
+ <div class="config-item">
483
+ <span class="config-key">Bulk Size</span>
484
+ <span class="config-value">50 payloads</span>
485
+ </div>
486
+
487
+ <div class="config-item">
488
+ <span class="config-key">Peak Virtual Users</span>
489
+ <span class="config-value">200</span>
490
+ </div>
491
+ </div>
492
+ </div>
493
+
494
+ <footer>
495
+ <p>Generated by Rulebricks Benchmarking Toolkit</p>
496
+ </footer>
497
+ </div>
498
+
499
+ <script>
500
+ Chart.defaults.font.family = "'Archivo', sans-serif";
501
+ Chart.defaults.color = '#a1a1a1';
502
+
503
+ // Latency Distribution Chart
504
+ const latencyCtx = document.getElementById('latencyChart').getContext('2d');
505
+ new Chart(latencyCtx, {
506
+ type: 'bar',
507
+ data: {
508
+ labels: ['Min', 'P50', 'P90', 'P95', 'P99', 'Max'],
509
+ datasets: [{
510
+ label: 'Response Time (ms)',
511
+ data: [
512
+ 97.82,
513
+ 193.16,
514
+ 283.41,
515
+ 316.35,
516
+ 0.00,
517
+ 990.43
518
+ ],
519
+ backgroundColor: [
520
+ 'rgba(74, 222, 128, 0.7)',
521
+ 'rgba(74, 222, 128, 0.7)',
522
+ 'rgba(251, 191, 36, 0.7)',
523
+ 'rgba(251, 191, 36, 0.7)',
524
+ 'rgba(248, 113, 113, 0.7)',
525
+ 'rgba(248, 113, 113, 0.7)'
526
+ ],
527
+ borderColor: [
528
+ 'rgb(74, 222, 128)',
529
+ 'rgb(74, 222, 128)',
530
+ 'rgb(251, 191, 36)',
531
+ 'rgb(251, 191, 36)',
532
+ 'rgb(248, 113, 113)',
533
+ 'rgb(248, 113, 113)'
534
+ ],
535
+ borderWidth: 1,
536
+ borderRadius: 2,
537
+ }]
538
+ },
539
+ options: {
540
+ responsive: true,
541
+ maintainAspectRatio: false,
542
+ plugins: {
543
+ legend: { display: false },
544
+ tooltip: {
545
+ backgroundColor: '#1f1f1f',
546
+ titleColor: '#fafafa',
547
+ bodyColor: '#a1a1a1',
548
+ borderColor: '#2a2a2a',
549
+ borderWidth: 1,
550
+ padding: 10,
551
+ cornerRadius: 3,
552
+ displayColors: false,
553
+ callbacks: {
554
+ label: function(context) {
555
+ return context.parsed.y.toFixed(2) + ' ms';
556
+ }
557
+ }
558
+ }
559
+ },
560
+ scales: {
561
+ y: {
562
+ beginAtZero: true,
563
+ grid: { color: '#2a2a2a', drawBorder: false },
564
+ ticks: {
565
+ callback: function(value) { return value + ' ms'; }
566
+ }
567
+ },
568
+ x: {
569
+ grid: { display: false }
570
+ }
571
+ }
572
+ }
573
+ });
574
+
575
+ // Timing Breakdown Chart
576
+ const timingCtx = document.getElementById('timingChart').getContext('2d');
577
+ new Chart(timingCtx, {
578
+ type: 'doughnut',
579
+ data: {
580
+ labels: ['Connecting', 'TLS Handshake', 'Sending', 'Waiting (TTFB)', 'Receiving'],
581
+ datasets: [{
582
+ data: [
583
+ 0.76,
584
+ 0.91,
585
+ 0.35,
586
+ 201.83,
587
+ 2.11
588
+ ],
589
+ backgroundColor: [
590
+ 'rgba(167, 139, 250, 0.8)',
591
+ 'rgba(34, 211, 238, 0.8)',
592
+ 'rgba(244, 114, 182, 0.8)',
593
+ 'rgba(74, 222, 128, 0.8)',
594
+ 'rgba(251, 191, 36, 0.8)'
595
+ ],
596
+ borderColor: '#0a0a0a',
597
+ borderWidth: 2,
598
+ }]
599
+ },
600
+ options: {
601
+ responsive: true,
602
+ maintainAspectRatio: false,
603
+ cutout: '60%',
604
+ plugins: {
605
+ legend: {
606
+ position: 'right',
607
+ labels: {
608
+ padding: 15,
609
+ usePointStyle: true,
610
+ pointStyle: 'rect'
611
+ }
612
+ },
613
+ tooltip: {
614
+ backgroundColor: '#1f1f1f',
615
+ titleColor: '#fafafa',
616
+ bodyColor: '#a1a1a1',
617
+ borderColor: '#2a2a2a',
618
+ borderWidth: 1,
619
+ padding: 10,
620
+ cornerRadius: 3,
621
+ callbacks: {
622
+ label: function(context) {
623
+ return context.label + ': ' + context.parsed.toFixed(2) + ' ms';
624
+ }
625
+ }
626
+ }
627
+ }
628
+ }
629
+ });
630
+ </script>
631
+ </body>
632
+ </html>