@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.
- package/dashboard/js/render-prs.js +43 -16
- package/dashboard/styles.css +36 -10
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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
|
-
+ '
|
|
95
|
-
+ '
|
|
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
|
|
292
|
-
// the
|
|
293
|
-
// `_contextOnly` to gate review/fix
|
|
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.
|
|
306
|
-
btn.
|
|
307
|
-
|
|
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.
|
|
319
|
-
btn.
|
|
320
|
-
|
|
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.
|
|
328
|
-
btn.
|
|
329
|
-
|
|
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;
|
package/dashboard/styles.css
CHANGED
|
@@ -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
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
.pr-observe-
|
|
350
|
-
.pr-observe-
|
|
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.
|
|
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"
|