@yemi33/minions 0.1.2056 → 0.1.2057

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.
@@ -86,13 +86,25 @@ function prRow(pr) {
86
86
  var observeBtn = '';
87
87
  var idMatch = typeof pr.id === 'string' ? pr.id.match(/^([^:]+):(.+)#(\d+)$/) : null;
88
88
  if (idMatch) {
89
- observeBtn = '<button class="pr-observe-toggle ' + observeClass + '" '
89
+ // Real toggle-switch (W-mpof8qam000h62fb). Semantic <input type=checkbox>
90
+ // inside a <label> gives free keyboard + screen-reader support; clicks on
91
+ // the track or knob flip the state via the wrapping label. Data-attrs stay
92
+ // on the input so togglePrObserve(this) keeps working unchanged.
93
+ observeBtn = '<label class="pr-observe-switch ' + observeClass + '" '
94
+ + 'title="' + escapeHtml(observeTitle) + '" '
95
+ + 'onclick="event.stopPropagation()">'
96
+ + '<input type="checkbox" class="pr-observe-switch__input"'
97
+ + (observe ? ' checked' : '') + ' '
98
+ + 'aria-label="' + escapeHtml('Auto-observe: ' + observeLabel) + '" '
90
99
  + 'data-pr-host="' + escapeHtml(idMatch[1]) + '" '
91
100
  + 'data-pr-slug="' + escapeHtml(idMatch[2]) + '" '
92
101
  + 'data-pr-number="' + escapeHtml(idMatch[3]) + '" '
93
102
  + 'data-pr-observe="' + (observe ? '1' : '0') + '" '
94
- + 'title="' + escapeHtml(observeTitle) + '" '
95
- + 'onclick="event.stopPropagation();togglePrObserve(this)">' + observeLabel + '</button> ';
103
+ + 'onchange="togglePrObserve(this)">'
104
+ + '<span class="pr-observe-switch__track" aria-hidden="true">'
105
+ + '<span class="pr-observe-switch__knob"></span>'
106
+ + '</span>'
107
+ + '</label> ';
96
108
  }
97
109
  // Title attrs live on the inner element (link/span/badge) so hovering the
98
110
  // ellipsis-truncated content reveals the full text. Cell tags stay bare so
@@ -288,10 +300,15 @@ async function unlinkPr(id) {
288
300
  } catch (e) { clearDeleted('pr:' + id); showToast('pr-toast', 'Error: ' + e.message, false); refresh(); }
289
301
  }
290
302
 
291
- // Per-row auto-observe toggle (W-mpmwxkzm0009ba0b). Optimistic UI: flip
292
- // the button immediately, only revert on API error. The engine consumes
293
- // `_contextOnly` to gate review/fix dispatch (engine/shared.js
294
- // isAutoManagedPrRecord + discoverFromPrs).
303
+ // Per-row auto-observe toggle (W-mpmwxkzm0009ba0b; toggle-switch UX in
304
+ // W-mpof8qam000h62fb). Optimistic UI: flip the switch immediately, only
305
+ // revert on API error. The engine consumes `_contextOnly` to gate review/fix
306
+ // dispatch (engine/shared.js isAutoManagedPrRecord + discoverFromPrs).
307
+ //
308
+ // `btn` is the <input type=checkbox> inside .pr-observe-switch. Data-attrs
309
+ // live on the input so this handler keeps reading them directly; visual
310
+ // state is mirrored onto the wrapping <label> via the pr-observe-on/off
311
+ // class so CSS can paint the track and slide the knob.
295
312
  async function togglePrObserve(btn) {
296
313
  if (!btn || btn.disabled) return;
297
314
  const host = btn.dataset.prHost;
@@ -300,11 +317,15 @@ async function togglePrObserve(btn) {
300
317
  if (!host || !slug || !Number.isFinite(number)) return;
301
318
  const wasObserve = btn.dataset.prObserve === '1';
302
319
  const next = !wasObserve;
320
+ const wrapper = btn.closest('.pr-observe-switch');
303
321
  // Optimistic flip
304
322
  btn.dataset.prObserve = next ? '1' : '0';
305
- btn.classList.toggle('pr-observe-on', next);
306
- btn.classList.toggle('pr-observe-off', !next);
307
- btn.textContent = next ? 'observed' : 'context';
323
+ btn.checked = next;
324
+ btn.setAttribute('aria-label', 'Auto-observe: ' + (next ? 'observed' : 'context'));
325
+ if (wrapper) {
326
+ wrapper.classList.toggle('pr-observe-on', next);
327
+ wrapper.classList.toggle('pr-observe-off', !next);
328
+ }
308
329
  btn.disabled = true;
309
330
  try {
310
331
  const res = await fetch('/api/pull-requests/observe', {
@@ -315,18 +336,24 @@ async function togglePrObserve(btn) {
315
336
  const d = await res.json().catch(() => ({}));
316
337
  // Revert
317
338
  btn.dataset.prObserve = wasObserve ? '1' : '0';
318
- btn.classList.toggle('pr-observe-on', wasObserve);
319
- btn.classList.toggle('pr-observe-off', !wasObserve);
320
- btn.textContent = wasObserve ? 'observed' : 'context';
339
+ btn.checked = wasObserve;
340
+ btn.setAttribute('aria-label', 'Auto-observe: ' + (wasObserve ? 'observed' : 'context'));
341
+ if (wrapper) {
342
+ wrapper.classList.toggle('pr-observe-on', wasObserve);
343
+ wrapper.classList.toggle('pr-observe-off', !wasObserve);
344
+ }
321
345
  showToast('pr-toast', 'Failed: ' + (d.error || 'unknown'), false);
322
346
  return;
323
347
  }
324
348
  showToast('pr-toast', next ? 'Auto-observe enabled' : 'Switched to context only', true);
325
349
  } catch (e) {
326
350
  btn.dataset.prObserve = wasObserve ? '1' : '0';
327
- btn.classList.toggle('pr-observe-on', wasObserve);
328
- btn.classList.toggle('pr-observe-off', !wasObserve);
329
- btn.textContent = wasObserve ? 'observed' : 'context';
351
+ btn.checked = wasObserve;
352
+ btn.setAttribute('aria-label', 'Auto-observe: ' + (wasObserve ? 'observed' : 'context'));
353
+ if (wrapper) {
354
+ wrapper.classList.toggle('pr-observe-on', wasObserve);
355
+ wrapper.classList.toggle('pr-observe-off', !wasObserve);
356
+ }
330
357
  showToast('pr-toast', 'Error: ' + e.message, false);
331
358
  } finally {
332
359
  btn.disabled = false;
@@ -338,16 +338,42 @@
338
338
  .pr-page-info { font-size: var(--text-base); color: var(--muted); }
339
339
  .pr-date { font-size: var(--text-base); color: var(--muted); }
340
340
 
341
- .pr-observe-toggle {
342
- font-size: 9px; padding: 1px 6px; border-radius: var(--radius-sm); cursor: pointer;
343
- text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600;
344
- background: var(--surface2); transition: all var(--transition-base);
345
- }
346
- .pr-observe-toggle:disabled { opacity: 0.6; cursor: wait; }
347
- .pr-observe-toggle.pr-observe-on { color: var(--green); border: 1px solid var(--green); background: rgba(63,185,80,0.12); }
348
- .pr-observe-toggle.pr-observe-on:hover:not(:disabled) { background: rgba(63,185,80,0.22); }
349
- .pr-observe-toggle.pr-observe-off { color: var(--muted); border: 1px dashed var(--border); }
350
- .pr-observe-toggle.pr-observe-off:hover:not(:disabled) { color: var(--text); border-color: var(--text); }
341
+ /* PR row auto-observe toggle switch (W-mpof8qam000h62fb).
342
+ Semantic <input type=checkbox> hidden but focusable; the visible track
343
+ is a sibling span styled via the .pr-observe-on/off class on the
344
+ wrapping <label>. Knob slides via left position + transition. */
345
+ .pr-observe-switch {
346
+ display: inline-flex; align-items: center; cursor: pointer;
347
+ position: relative; user-select: none; vertical-align: middle;
348
+ }
349
+ .pr-observe-switch:has(.pr-observe-switch__input:disabled) { cursor: wait; opacity: 0.6; }
350
+ .pr-observe-switch__input {
351
+ position: absolute; opacity: 0; pointer-events: none;
352
+ width: 1px; height: 1px; margin: 0; padding: 0;
353
+ }
354
+ .pr-observe-switch__track {
355
+ display: inline-block; position: relative;
356
+ width: 26px; height: 14px; border-radius: 999px;
357
+ background: var(--surface2); border: 1px dashed var(--border);
358
+ box-sizing: border-box; transition: all var(--transition-base);
359
+ }
360
+ .pr-observe-switch__knob {
361
+ position: absolute; top: 1px; left: 1px;
362
+ width: 10px; height: 10px; border-radius: 50%;
363
+ background: var(--muted); transition: all var(--transition-base);
364
+ }
365
+ .pr-observe-switch.pr-observe-on .pr-observe-switch__track {
366
+ background: rgba(63,185,80,0.18); border: 1px solid var(--green);
367
+ }
368
+ .pr-observe-switch.pr-observe-on .pr-observe-switch__knob {
369
+ left: 14px; background: var(--green);
370
+ }
371
+ .pr-observe-switch.pr-observe-on:hover .pr-observe-switch__track { background: rgba(63,185,80,0.32); }
372
+ .pr-observe-switch.pr-observe-off:hover .pr-observe-switch__track { border-color: var(--text); }
373
+ .pr-observe-switch.pr-observe-off:hover .pr-observe-switch__knob { background: var(--text); }
374
+ .pr-observe-switch__input:focus-visible ~ .pr-observe-switch__track {
375
+ outline: 2px solid var(--blue); outline-offset: 2px;
376
+ }
351
377
 
352
378
  .archive-btn {
353
379
  background: var(--surface2); border: 1px solid var(--border); color: var(--muted);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.2056",
3
+ "version": "0.1.2057",
4
4
  "description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
5
5
  "bin": {
6
6
  "minions": "bin/minions.js"