viberadar 0.3.39 → 0.3.40

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.
@@ -234,7 +234,8 @@
234
234
  .type-count { margin-left: auto; font-size: 11px; color: var(--dim); }
235
235
 
236
236
  /* ── Content area ────────────────────────────────────────────────────────── */
237
- .content { flex: 1; overflow-y: auto; padding: 18px 20px; }
237
+ .content { flex: 1; overflow-y: auto; padding: 18px 20px; transition: padding-bottom 0.25s ease; }
238
+ .content.panel-open { padding-bottom: 300px; }
238
239
 
239
240
  /* ── Feature cards ───────────────────────────────────────────────────────── */
240
241
  .features-grid {
@@ -481,59 +482,56 @@
481
482
 
482
483
  /* ── Test-type cards inside feature detail ───────────────────────────────── */
483
484
  .test-type-grid {
484
- display: grid;
485
- grid-template-columns: repeat(4, 1fr);
486
- gap: 10px;
487
- margin-bottom: 20px;
485
+ display: flex;
486
+ gap: 8px;
487
+ margin-bottom: 14px;
488
+ flex-wrap: wrap;
489
+ align-items: center;
488
490
  }
489
491
  .test-type-card {
492
+ display: flex;
493
+ align-items: center;
494
+ gap: 8px;
490
495
  background: var(--bg-card);
491
496
  border: 1px solid var(--border);
497
+ border-left: 3px solid transparent;
492
498
  border-radius: 8px;
493
- padding: 14px 16px;
499
+ padding: 7px 12px;
494
500
  cursor: pointer;
495
501
  transition: background 0.15s, border-color 0.15s;
496
- position: relative;
497
- overflow: hidden;
498
- }
499
- .test-type-card:hover { background: var(--bg-hover); border-color: var(--dim); }
500
- .test-type-card .tt-accent {
501
- position: absolute; top: 0; left: 0; right: 0; height: 3px;
502
+ flex-shrink: 0;
502
503
  }
504
+ .test-type-card:hover { background: var(--bg-hover); }
505
+ .test-type-card .tt-accent { display: none; } /* replaced by border-left */
503
506
  .test-type-card .tt-label {
504
507
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;
505
- color: var(--muted); margin-bottom: 6px; margin-top: 2px;
508
+ color: var(--muted); white-space: nowrap;
506
509
  }
507
510
  .test-type-card .tt-count {
508
- font-size: 26px; font-weight: 700; line-height: 1;
509
- margin-bottom: 4px;
511
+ font-size: 18px; font-weight: 700; line-height: 1;
510
512
  }
511
513
  .test-type-card .tt-sub {
512
- font-size: 11px; color: var(--dim);
513
- }
514
- .test-type-card.tt-empty .tt-count { color: var(--dim); }
515
- .test-type-card.tt-empty { opacity: 0.7; }
516
- .test-type-card.tt-active {
517
- background: var(--bg-hover);
518
- border-width: 2px;
514
+ font-size: 11px; color: var(--dim); white-space: nowrap;
519
515
  }
516
+ .test-type-card.tt-empty { opacity: 0.65; }
517
+ .test-type-card.tt-active { background: var(--bg-hover); }
520
518
  .test-type-card.tt-failed {
521
519
  border-color: var(--red) !important;
522
- border-width: 2px;
523
520
  background: rgba(248, 81, 73, 0.06);
524
521
  }
522
+ .tt-chip-actions { display: flex; gap: 4px; margin-left: 4px; }
525
523
  .tt-run-btn {
526
- display: block; width: 100%; margin-top: 8px;
527
- padding: 3px 0;
524
+ display: inline-block; margin: 0;
525
+ padding: 3px 9px;
528
526
  background: transparent; border: 1px solid var(--border);
529
527
  border-radius: 4px; color: var(--muted); font-size: 10px;
530
- cursor: pointer; text-align: center;
528
+ cursor: pointer; white-space: nowrap;
531
529
  transition: background 0.1s, color 0.1s, border-color 0.1s;
532
530
  }
533
531
  .tt-run-btn:hover { background: var(--bg-hover); color: var(--text); border-color: var(--dim); }
534
532
  .tt-run-btn:disabled { opacity: 0.4; cursor: not-allowed; }
535
- .tt-fix-btn { border-color: var(--red); color: var(--red); font-weight: 600; }
536
- .tt-fix-btn:hover { background: rgba(248, 81, 73, 0.15); color: var(--red); border-color: var(--red); }
533
+ .tt-fix-btn { border-color: var(--yellow); color: var(--yellow); font-weight: 600; }
534
+ .tt-fix-btn:hover { background: rgba(255,200,0,0.1); color: var(--yellow); border-color: var(--yellow); }
537
535
  .file-rows { display: flex; flex-direction: column; gap: 2px; }
538
536
  .file-row {
539
537
  display: flex;
@@ -1510,27 +1508,29 @@ function renderFeatureCards(c) {
1510
1508
  function testTypeCard(type, label, icon, color, count, active, featureKey, failedCount = 0) {
1511
1509
  const empty = count === 0 && type !== 'source';
1512
1510
  const hasFailed = failedCount > 0 && type !== 'source';
1513
- const subLabel = empty ? 'нет тестов' : (type === 'source' ? 'код приложения' : pluralFiles(count));
1511
+ const subLabel = type === 'source' ? 'файлов' : (empty ? 'нет тестов' : pluralFiles(count));
1512
+ const accentColor = hasFailed ? 'var(--red)' : color;
1513
+ const countColor = hasFailed ? 'var(--red)' : (active || !empty ? color : 'var(--dim)');
1514
+
1514
1515
  const runBtn = !empty && type !== 'source' && featureKey
1515
1516
  ? `<button class="tt-run-btn" onclick="event.stopPropagation();runTests('${featureKey}','${type}')">▶ запустить</button>`
1516
1517
  : '';
1517
1518
  const fixAllBtn = hasFailed && D.agent && featureKey
1518
- ? `<button class="tt-run-btn tt-fix-btn" onclick="event.stopPropagation();runAgentTask('fix-tests-all','${featureKey}','${type}')">🔧 починить всё</button>`
1519
+ ? `<button class="tt-run-btn tt-fix-btn" onclick="event.stopPropagation();runAgentTask('fix-tests-all','${featureKey}','${type}')">🔧 починить</button>`
1519
1520
  : '';
1520
- const accentColor = hasFailed && !active ? 'var(--red)' : color;
1521
- const countColor = hasFailed ? 'var(--red)' : (active || !empty ? color : 'var(--dim)');
1522
- const failedNote = hasFailed
1523
- ? `<div style="font-size:11px;color:var(--red);margin-top:2px;font-weight:600">❌ ${failedCount} упало</div>`
1521
+ const failedBadge = hasFailed
1522
+ ? `<span style="font-size:10px;color:var(--red);font-weight:700;white-space:nowrap">❌ ${failedCount}</span>`
1524
1523
  : '';
1524
+ const actions = (runBtn || fixAllBtn) ? `<div class="tt-chip-actions">${runBtn}${fixAllBtn}</div>` : '';
1525
+
1525
1526
  return `
1526
1527
  <div class="test-type-card${empty ? ' tt-empty' : ''}${active ? ' tt-active' : ''}${hasFailed ? ' tt-failed' : ''}"
1527
- data-testtype="${type}" style="${active ? 'border-color:' + color : ''}">
1528
- <div class="tt-accent" style="background:${accentColor}"></div>
1529
- <div class="tt-label">${icon} ${label}</div>
1530
- <div class="tt-count" style="color:${countColor}">${count}</div>
1531
- <div class="tt-sub">${subLabel}</div>
1532
- ${failedNote}
1533
- ${fixAllBtn || runBtn}
1528
+ data-testtype="${type}" style="border-left-color:${accentColor}${active ? ';border-color:' + color : ''}">
1529
+ <span class="tt-label">${icon} ${label}</span>
1530
+ <span class="tt-count" style="color:${countColor}">${count}</span>
1531
+ <span class="tt-sub">${subLabel}</span>
1532
+ ${failedBadge}
1533
+ ${actions}
1534
1534
  </div>`;
1535
1535
  }
1536
1536
 
@@ -2309,7 +2309,15 @@ function connectSSE() {
2309
2309
  };
2310
2310
  }
2311
2311
 
2312
- init().then(() => { restoreSessions(); connectSSE(); });
2312
+ init().then(() => {
2313
+ restoreSessions();
2314
+ connectSSE();
2315
+ // Sync content padding with terminal panel open state automatically
2316
+ new MutationObserver(() => {
2317
+ const isOpen = document.getElementById('agentPanel').classList.contains('open');
2318
+ document.getElementById('content').classList.toggle('panel-open', isOpen);
2319
+ }).observe(document.getElementById('agentPanel'), { attributes: true, attributeFilter: ['class'] });
2320
+ });
2313
2321
  </script>
2314
2322
  </body>
2315
2323
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viberadar",
3
- "version": "0.3.39",
3
+ "version": "0.3.40",
4
4
  "description": "Live module map with test coverage for vibecoding projects",
5
5
  "main": "./dist/cli.js",
6
6
  "bin": {