viberadar 0.3.175 → 0.3.176

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.
@@ -1641,7 +1641,6 @@
1641
1641
  <div class="view-tab" data-view="features">Features</div>
1642
1642
  <div class="view-tab" data-view="files">Files</div>
1643
1643
  <div class="view-tab" data-view="tests">Tests</div>
1644
- <div class="view-tab" data-view="probe">Probe</div>
1645
1644
  </div>
1646
1645
  <input class="search-input" id="searchInput" type="text" placeholder="Search…" />
1647
1646
  <div id="sidebarExtra"></div>
@@ -1808,13 +1807,14 @@ function switchMode(nextMode) {
1808
1807
  saveModeState(contextMode);
1809
1808
  contextMode = nextMode;
1810
1809
  restoreModeState(contextMode);
1811
- if (contextMode === 'observability' || contextMode === 'docs' || contextMode === 'services' || contextMode === 'load') {
1810
+ if (contextMode === 'observability' || contextMode === 'docs' || contextMode === 'services' || contextMode === 'load' || contextMode === 'probe') {
1812
1811
  view = 'features';
1813
1812
  drillFeatureKey = null;
1814
1813
  drillTestType = null;
1815
1814
  activePanelKey = null;
1816
1815
  clearFeatureHash();
1817
1816
  }
1817
+ if (contextMode === 'probe') { loadProbeData(); }
1818
1818
  if (contextMode === 'load' && loadK6Available === null) { checkK6(); }
1819
1819
  if (contextMode === 'load') {
1820
1820
  loadRefreshScripts();
@@ -3183,6 +3183,7 @@ function renderModeSwitch() {
3183
3183
  { key: 'scenarios', label: 'Сценарии', hint: 'Пользовательские сценарии, user journeys' },
3184
3184
  { key: 'services', label: 'Карта сервисов', hint: 'Зависимости, пайплайны, мониторинг' },
3185
3185
  { key: 'load', label: 'Нагрузка', hint: 'k6: метрики, сценарии, AI-анализ' },
3186
+ { key: 'probe', label: 'Probe', hint: 'Synthetic monitoring, E2E на стенде' },
3186
3187
  ];
3187
3188
  root.innerHTML = modes.map(m => `
3188
3189
  <button class="mode-switch-btn ${contextMode === m.key ? 'active' : ''}" data-mode="${m.key}">
@@ -3201,6 +3202,16 @@ function renderSidebar() {
3201
3202
  const tabs = document.getElementById('viewTabs');
3202
3203
  const extra = document.getElementById('sidebarExtra');
3203
3204
 
3205
+ if (contextMode === 'probe') {
3206
+ tabs.style.display = 'none';
3207
+ extra.innerHTML = `
3208
+ <div class="sidebar-label">Probe</div>
3209
+ <div style="font-size:12px;color:var(--muted);padding:0 6px;line-height:1.45">
3210
+ Запуск E2E-проверок на стенде. Домен задаётся в Настройках.
3211
+ </div>`;
3212
+ return;
3213
+ }
3214
+
3204
3215
  if (contextMode === 'observability') {
3205
3216
  tabs.style.display = 'none';
3206
3217
  extra.innerHTML = `
@@ -3346,7 +3357,7 @@ function renderContent() {
3346
3357
  return;
3347
3358
  }
3348
3359
 
3349
- if (view === 'probe') {
3360
+ if (contextMode === 'probe') {
3350
3361
  renderProbePanel(c);
3351
3362
  return;
3352
3363
  }
@@ -3412,10 +3423,10 @@ function renderProbePanel(c) {
3412
3423
  <div class="probe-header">
3413
3424
  <div>
3414
3425
  <div class="probe-title">🔭 Probe monitoring</div>
3415
- ${d && d.configFound ? `<div style="color:var(--muted);font-size:12px">${escapeHtml((d.checks || []).length)} checks · <span style="color:${statusColor}">${statusLabel}</span></div>`
3416
- : `<div style="color:var(--yellow);font-size:12px">⚠️ probe.config.yml не найден в рабочей директории</div>`}
3426
+ ${d && d.effectiveTarget ? `<div style="color:var(--muted);font-size:12px">${escapeHtml(d.effectiveTarget)} · ${escapeHtml((d.checks || []).length)} checks · <span style="color:${statusColor}">${statusLabel}</span></div>`
3427
+ : `<div style="color:var(--yellow);font-size:12px">⚠️ Задайте домен стенда в Настройках</div>`}
3417
3428
  </div>
3418
- <button class="probe-btn" onclick="openProbeNotifyModal()">⚙️ Уведомления</button>
3429
+ <button class="probe-btn" onclick="openProbeSettingsModal()">⚙️ Настройки</button>
3419
3430
  </div>
3420
3431
 
3421
3432
  <div class="probe-section">
@@ -3460,42 +3471,57 @@ async function probeScheduleStop() {
3460
3471
  renderContent();
3461
3472
  }
3462
3473
 
3463
- function openProbeNotifyModal() {
3464
- fetch('/api/probe/notify-config').then(r => r.json()).then(saved => {
3474
+ function openProbeSettingsModal() {
3475
+ fetch('/api/probe/settings').then(r => r.json()).then(saved => {
3465
3476
  const tg = saved.telegram || {};
3466
- let overlay = document.getElementById('probeNotifyOverlay');
3477
+ const inp = s => `style="width:100%;box-sizing:border-box;padding:8px 12px;border-radius:6px;border:1px solid var(--border);background:var(--bg);color:var(--text);font-size:13px"`;
3478
+ const lbl = t => `<label style="font-size:12px;color:var(--muted);display:block;margin:12px 0 4px">${t}</label>`;
3479
+ let overlay = document.getElementById('probeSettingsOverlay');
3467
3480
  if (overlay) overlay.remove();
3468
3481
  overlay = document.createElement('div');
3469
- overlay.id = 'probeNotifyOverlay';
3482
+ overlay.id = 'probeSettingsOverlay';
3470
3483
  overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;z-index:9999';
3471
3484
  overlay.innerHTML = `
3472
- <div style="background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:24px 28px;width:400px;max-width:90vw">
3473
- <h3 style="margin:0 0 16px;font-size:16px;color:var(--text)">⚙️ Telegram уведомления</h3>
3474
- <label style="font-size:12px;color:var(--muted);display:block;margin-bottom:4px">Bot Token</label>
3475
- <input id="probeBotToken" type="password" placeholder="1234567890:AAF..." value="${escapeHtml(tg.botToken || '')}"
3476
- style="width:100%;box-sizing:border-box;padding:8px 12px;border-radius:6px;border:1px solid var(--border);background:var(--bg);color:var(--text);font-size:13px;margin-bottom:12px">
3477
- <label style="font-size:12px;color:var(--muted);display:block;margin-bottom:4px">Chat ID</label>
3478
- <input id="probeChatId" type="text" placeholder="-1001234567890" value="${escapeHtml(tg.chatId || '')}"
3479
- style="width:100%;box-sizing:border-box;padding:8px 12px;border-radius:6px;border:1px solid var(--border);background:var(--bg);color:var(--text);font-size:13px;margin-bottom:4px">
3480
- <div style="font-size:11px;color:var(--muted);margin-bottom:16px">Получить токен у @BotFather · Chat ID через @userinfobot</div>
3481
- <div id="probeNotifyErr" style="display:none;margin-bottom:12px;padding:8px 12px;border-radius:6px;background:rgba(248,81,73,0.1);color:var(--red);font-size:12px"></div>
3482
- <div style="display:flex;gap:10px;justify-content:flex-end">
3483
- <button onclick="document.getElementById('probeNotifyOverlay').remove()" style="padding:6px 16px;border-radius:6px;border:1px solid var(--border);background:var(--bg);color:var(--text);cursor:pointer;font-size:13px">Отмена</button>
3484
- <button id="probeNotifySave" style="padding:6px 16px;border-radius:6px;border:1px solid var(--blue);background:var(--blue);color:#fff;cursor:pointer;font-size:13px">Сохранить</button>
3485
+ <div style="background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:24px 28px;width:440px;max-width:90vw">
3486
+ <h3 style="margin:0 0 4px;font-size:16px;color:var(--text)">⚙️ Настройки Probe</h3>
3487
+ <div style="font-size:12px;color:var(--muted);margin-bottom:16px">Настройки сохраняются локально, не попадают в git</div>
3488
+
3489
+ <div style="border-bottom:1px solid var(--border);padding-bottom:16px;margin-bottom:4px">
3490
+ ${lbl('Домен стенда')}
3491
+ <input id="probeTarget" type="text" placeholder="https://staging.myapp.com" value="${escapeHtml(saved.target || '')}" ${inp()}>
3492
+ <div style="font-size:11px;color:var(--muted);margin-top:4px">Все проверки будут запускаться на этом домене. Переопределяет target из probe.config.yml</div>
3493
+ </div>
3494
+
3495
+ <div style="margin-top:16px">
3496
+ <div style="font-size:12px;font-weight:600;color:var(--text);margin-bottom:8px">Telegram уведомления</div>
3497
+ ${lbl('Bot Token')}
3498
+ <input id="probeBotToken" type="password" placeholder="1234567890:AAF..." value="${escapeHtml(tg.botToken || '')}" ${inp()}>
3499
+ ${lbl('Chat ID')}
3500
+ <input id="probeChatId" type="text" placeholder="-1001234567890" value="${escapeHtml(tg.chatId || '')}" ${inp()}>
3501
+ <div style="font-size:11px;color:var(--muted);margin-top:4px">Токен у @BotFather · Chat ID через @userinfobot</div>
3502
+ </div>
3503
+
3504
+ <div id="probeSettingsErr" style="display:none;margin-top:12px;padding:8px 12px;border-radius:6px;background:rgba(248,81,73,0.1);color:var(--red);font-size:12px"></div>
3505
+ <div style="display:flex;gap:10px;justify-content:flex-end;margin-top:20px">
3506
+ <button onclick="document.getElementById('probeSettingsOverlay').remove()" style="padding:6px 16px;border-radius:6px;border:1px solid var(--border);background:var(--bg);color:var(--text);cursor:pointer;font-size:13px">Отмена</button>
3507
+ <button id="probeSettingsSave" style="padding:6px 16px;border-radius:6px;border:1px solid var(--blue);background:var(--blue);color:#fff;cursor:pointer;font-size:13px">Сохранить</button>
3485
3508
  </div>
3486
3509
  </div>`;
3487
3510
  document.body.appendChild(overlay);
3488
3511
  overlay.addEventListener('click', e => { if (e.target === overlay) overlay.remove(); });
3489
- document.getElementById('probeNotifySave').addEventListener('click', async () => {
3512
+ document.getElementById('probeSettingsSave').addEventListener('click', async () => {
3513
+ const target = document.getElementById('probeTarget').value.trim();
3490
3514
  const botToken = document.getElementById('probeBotToken').value.trim();
3491
3515
  const chatId = document.getElementById('probeChatId').value.trim();
3492
- const err = document.getElementById('probeNotifyErr');
3493
- if (!botToken || !chatId) { err.style.display = 'block'; err.textContent = 'Введите Bot Token и Chat ID'; return; }
3494
- const btn = document.getElementById('probeNotifySave');
3516
+ const err = document.getElementById('probeSettingsErr');
3517
+ const btn = document.getElementById('probeSettingsSave');
3495
3518
  btn.disabled = true; btn.textContent = 'Сохраняю…';
3496
3519
  try {
3497
- const res = await fetch('/api/probe/notify-config', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ botToken, chatId }) });
3520
+ const res = await fetch('/api/probe/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ target, botToken, chatId }) });
3498
3521
  if (!res.ok) { const d = await res.json(); throw new Error(d.error || 'Ошибка сохранения'); }
3522
+ // Refresh probe data to show new target
3523
+ await loadProbeData();
3524
+ renderContent();
3499
3525
  overlay.remove();
3500
3526
  } catch (e) { err.style.display = 'block'; err.textContent = e.message; btn.disabled = false; btn.textContent = 'Сохранить'; }
3501
3527
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viberadar",
3
- "version": "0.3.175",
3
+ "version": "0.3.176",
4
4
  "description": "Live module map with test coverage for vibecoding projects",
5
5
  "main": "./dist/cli.js",
6
6
  "bin": {