@yemi33/minions 0.1.2340 → 0.1.2341
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-other.js +12 -0
- package/dashboard/js/settings.js +90 -13
- package/dashboard.js +9 -0
- package/package.json +1 -1
|
@@ -166,6 +166,18 @@ function _liveValidationTypesArray(p) {
|
|
|
166
166
|
return arr.filter(function(t) { return typeof t === 'string' && t.length > 0; });
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
// Expose the hybrid constants + normalizer on window so the Settings page
|
|
170
|
+
// (dashboard/js/settings.js) can reuse the SAME single source of truth for the
|
|
171
|
+
// hybrid work-item-type list, default type, and liveValidationType normalizer
|
|
172
|
+
// rather than duplicating them (CLAUDE.md "no duplicate solutions"). Both files
|
|
173
|
+
// concatenate into one dashboard <script> scope, but attaching to window makes
|
|
174
|
+
// the cross-file dependency explicit and order-independent.
|
|
175
|
+
try {
|
|
176
|
+
window.CHECKOUT_MODE_HYBRID_TYPES = CHECKOUT_MODE_HYBRID_TYPES;
|
|
177
|
+
window.CHECKOUT_MODE_HYBRID_DEFAULT_TYPE = CHECKOUT_MODE_HYBRID_DEFAULT_TYPE;
|
|
178
|
+
window._liveValidationTypesArray = _liveValidationTypesArray;
|
|
179
|
+
} catch (e) { /* non-browser (unit test require) */ }
|
|
180
|
+
|
|
169
181
|
function _closeCheckoutModeMenu() {
|
|
170
182
|
const existing = document.getElementById('checkout-mode-menu');
|
|
171
183
|
if (existing) existing.remove();
|
package/dashboard/js/settings.js
CHANGED
|
@@ -276,18 +276,55 @@ async function openSettings() {
|
|
|
276
276
|
// where worktrees are unworkable. p.checkoutMode is resolved server-side
|
|
277
277
|
// (honors the legacy worktreeMode field). Chip is hidden by default and
|
|
278
278
|
// toggled reactively below.
|
|
279
|
+
// W-mr9mx93d000x1dda — third option "Hybrid dispatch": checkoutMode:'live'
|
|
280
|
+
// PLUS a liveValidation block (coding WIs author in isolated worktrees; only
|
|
281
|
+
// the chosen validation type(s) run in-place on the live checkout, with an
|
|
282
|
+
// optional auto-dispatch-after-coding toggle). This mirrors the Projects-bar
|
|
283
|
+
// picker (render-other.js _openCheckoutModeMenu / _renderCheckoutModeHybridStep)
|
|
284
|
+
// so both surfaces configure the SAME liveValidation shape identically.
|
|
279
285
|
var currentWtMode = (p.checkoutMode === 'live') ? 'live' : 'worktree';
|
|
280
|
-
var
|
|
286
|
+
var lvTypes = (window._liveValidationTypesArray ? window._liveValidationTypesArray(p) : []);
|
|
287
|
+
// 3-way UI mode: worktree / live / hybrid. Hybrid = live + >=1 validation type.
|
|
288
|
+
var currentCheckoutMode = (currentWtMode === 'live')
|
|
289
|
+
? (lvTypes.length > 0 ? 'hybrid' : 'live')
|
|
290
|
+
: 'worktree';
|
|
291
|
+
var hybridTypes = window.CHECKOUT_MODE_HYBRID_TYPES || [];
|
|
292
|
+
var hybridDefaultType = window.CHECKOUT_MODE_HYBRID_DEFAULT_TYPE || 'test';
|
|
293
|
+
var hybridPreselect = lvTypes.length > 0 ? lvTypes : [hybridDefaultType];
|
|
294
|
+
var hybridAutoPre = p.liveValidationAutoDispatch === true;
|
|
295
|
+
var wtModeSearch = 'checkout mode worktree isolated live hybrid dispatch validation';
|
|
296
|
+
var hybridTypeChecks = hybridTypes.map(function(t) {
|
|
297
|
+
var checkedAttr = hybridPreselect.indexOf(t) !== -1 ? ' checked' : '';
|
|
298
|
+
return '<label style="display:inline-flex;align-items:center;gap:4px;margin:2px 10px 2px 0;font-size:var(--text-sm);color:var(--text)">' +
|
|
299
|
+
'<input type="checkbox" data-live-validation-type="' + escHtml(p.name) + '" value="' + escHtml(t) + '"' + checkedAttr + '>' +
|
|
300
|
+
'<span>' + escHtml(t) + '</span>' +
|
|
301
|
+
'</label>';
|
|
302
|
+
}).join('');
|
|
303
|
+
var hybridPanel =
|
|
304
|
+
'<div data-checkout-hybrid-panel="' + escHtml(p.name) + '" style="' + (currentCheckoutMode === 'hybrid' ? '' : 'display:none;') + 'margin-top:6px">' +
|
|
305
|
+
'<div style="padding:6px 8px;background:rgba(234,179,8,0.12);border:1px solid var(--yellow);border-radius:4px;color:var(--yellow);font-size:var(--text-xs);line-height:1.4;margin-bottom:6px">' +
|
|
306
|
+
'⚠ Hybrid mode: coding work items author in isolated worktrees; only the chosen validation type(s) run in-place on the live checkout (one mutating dispatch at a time; refused on a dirty tree).' +
|
|
307
|
+
'</div>' +
|
|
308
|
+
'<div style="font-size:var(--text-sm);color:var(--muted);margin-bottom:2px">Work-item type(s) to validate live:</div>' +
|
|
309
|
+
'<div style="margin-bottom:4px">' + hybridTypeChecks + '</div>' +
|
|
310
|
+
'<label style="display:inline-flex;align-items:center;gap:6px;font-size:var(--text-sm);color:var(--text);margin-top:2px">' +
|
|
311
|
+
'<input type="checkbox" id="set-liveValidationAutoDispatch-' + escHtml(p.name) + '"' + (hybridAutoPre ? ' checked' : '') + '>' +
|
|
312
|
+
'<span>Automatically validate after each coding work item completes</span>' +
|
|
313
|
+
'</label>' +
|
|
314
|
+
'<div data-checkout-hybrid-error="' + escHtml(p.name) + '" style="display:none;margin-top:6px;color:var(--red);font-size:var(--text-xs)">Select at least one work-item type to validate live.</div>' +
|
|
315
|
+
'</div>';
|
|
281
316
|
var worktreeModeBlock =
|
|
282
317
|
'<div data-search="' + escHtml(wtModeSearch) + '" style="margin-bottom:6px">' +
|
|
283
318
|
'<label style="font-size:var(--text-sm);color:var(--muted);display:block;margin-bottom:2px">Checkout mode</label>' +
|
|
284
319
|
'<select id="set-checkoutMode-' + escHtml(p.name) + '" data-checkout-mode-select="' + escHtml(p.name) + '" style="width:100%;padding:4px 6px;background:var(--surface);border:1px solid var(--border);border-radius:4px;color:var(--text);font-size:var(--text-md)">' +
|
|
285
|
-
'<option value="worktree" title="Each dispatch runs in its own isolated git worktree. Fully parallel, never touches your working directory."' + (
|
|
286
|
-
'<option value="live" title="Agents run in-place in the project folder. One mutating dispatch at a time; refuses to run on a dirty tree."' + (
|
|
320
|
+
'<option value="worktree" title="Each dispatch runs in its own isolated git worktree. Fully parallel, never touches your working directory."' + (currentCheckoutMode === 'worktree' ? ' selected' : '') + '>Worktree (default)</option>' +
|
|
321
|
+
'<option value="live" title="Agents run in-place in the project folder. One mutating dispatch at a time; refuses to run on a dirty tree."' + (currentCheckoutMode === 'live' ? ' selected' : '') + '>Live checkout</option>' +
|
|
322
|
+
'<option value="hybrid" title="Coding work authors in isolated worktrees; only a chosen validation step runs on the real checkout."' + (currentCheckoutMode === 'hybrid' ? ' selected' : '') + '>Hybrid dispatch</option>' +
|
|
287
323
|
'</select>' +
|
|
288
|
-
'<div data-checkout-mode-chip="' + escHtml(p.name) + '" style="' + (
|
|
324
|
+
'<div data-checkout-mode-chip="' + escHtml(p.name) + '" style="' + (currentCheckoutMode === 'live' ? '' : 'display:none;') + 'margin-top:6px;padding:6px 8px;background:rgba(234,179,8,0.12);border:1px solid var(--yellow);border-radius:4px;color:var(--yellow);font-size:var(--text-xs);line-height:1.4">' +
|
|
289
325
|
'⚠ Live mode: dispatches run directly in this repo\'s checkout. Only one mutating dispatch runs at a time. Dirty working trees block dispatch — commit or stash before running.' +
|
|
290
326
|
'</div>' +
|
|
327
|
+
hybridPanel +
|
|
291
328
|
'</div>';
|
|
292
329
|
// W-mqtvnnj1000357fa — per-project live-checkout auto-stash override.
|
|
293
330
|
// Tri-state: "" (use fleet default → engine.liveCheckoutAutoStash), "on"
|
|
@@ -715,12 +752,17 @@ async function openSettings() {
|
|
|
715
752
|
// chip is rendered once with display:none for worktree-mode projects and
|
|
716
753
|
// visible for already-live projects; this handler only flips the
|
|
717
754
|
// display style — no markup is regenerated.
|
|
755
|
+
// W-mr9mx93d000x1dda — also reveal/hide the Hybrid sub-panel: the live chip
|
|
756
|
+
// shows for 'live', the hybrid panel (type checkboxes + auto-validate) shows
|
|
757
|
+
// for 'hybrid', neither for 'worktree'.
|
|
718
758
|
document.querySelectorAll('[data-checkout-mode-select]').forEach(function(sel) {
|
|
719
759
|
sel.addEventListener('change', function() {
|
|
720
760
|
const projName = sel.getAttribute('data-checkout-mode-select');
|
|
721
|
-
const
|
|
722
|
-
|
|
723
|
-
chip.style.display = (sel.value === 'live') ? '' : 'none';
|
|
761
|
+
const esc = (window.CSS && CSS.escape ? CSS.escape(projName) : projName);
|
|
762
|
+
const chip = document.querySelector('[data-checkout-mode-chip="' + esc + '"]');
|
|
763
|
+
if (chip) chip.style.display = (sel.value === 'live') ? '' : 'none';
|
|
764
|
+
const hybridPanel = document.querySelector('[data-checkout-hybrid-panel="' + esc + '"]');
|
|
765
|
+
if (hybridPanel) hybridPanel.style.display = (sel.value === 'hybrid') ? '' : 'none';
|
|
724
766
|
});
|
|
725
767
|
});
|
|
726
768
|
}
|
|
@@ -1165,18 +1207,48 @@ async function saveSettings() {
|
|
|
1165
1207
|
});
|
|
1166
1208
|
|
|
1167
1209
|
const currentProjects = (_settingsData && Array.isArray(_settingsData.projects)) ? _settingsData.projects : [];
|
|
1210
|
+
// W-mr9mx93d000x1dda — collect per-project hybrid validation errors so a
|
|
1211
|
+
// Hybrid selection with zero checked types blocks the whole save with an
|
|
1212
|
+
// inline error (mirrors the Projects-bar picker's "require >=1 type" guard)
|
|
1213
|
+
// rather than silently POSTing an empty/absent liveValidation.
|
|
1214
|
+
const hybridValidationErrors = [];
|
|
1168
1215
|
const projectsPayload = currentProjects.map(function(p) {
|
|
1169
1216
|
// W-mpg3whgp000d09ec / #2732 — mainBranch is now editable from Settings →
|
|
1170
1217
|
// Projects. Empty string = clear the override; the field stays optional.
|
|
1171
1218
|
const mainBranchInput = document.getElementById('set-mainBranch-' + p.name);
|
|
1172
1219
|
const mainBranchValue = mainBranchInput ? mainBranchInput.value.trim() : (p.mainBranch || '');
|
|
1173
1220
|
// P-a3f9b207 (consolidated W-mqiaw974) — per-project checkoutMode.
|
|
1174
|
-
//
|
|
1175
|
-
//
|
|
1176
|
-
//
|
|
1177
|
-
//
|
|
1221
|
+
// W-mr9mx93d000x1dda — the select now carries THREE UI values:
|
|
1222
|
+
// 'worktree' | 'live' | 'hybrid'. Both 'live' and 'hybrid' persist as the
|
|
1223
|
+
// server enum checkoutMode:'live'; hybrid additionally carries a
|
|
1224
|
+
// liveValidation block. Any unknown value normalizes to 'worktree' so a
|
|
1225
|
+
// stale DOM never POSTs garbage (shared.validateCheckoutMode /
|
|
1226
|
+
// shared.validateLiveValidation are the authoritative server gates).
|
|
1178
1227
|
const wtModeInput = document.getElementById('set-checkoutMode-' + p.name);
|
|
1179
|
-
const
|
|
1228
|
+
const uiMode = wtModeInput ? wtModeInput.value : 'worktree';
|
|
1229
|
+
const isHybrid = uiMode === 'hybrid';
|
|
1230
|
+
const checkoutMode = (uiMode === 'live' || uiMode === 'hybrid') ? 'live' : 'worktree';
|
|
1231
|
+
// liveValidation: an explicit block for hybrid, else explicit null. Always
|
|
1232
|
+
// sending the key (never omitting it) matches the Projects-bar picker
|
|
1233
|
+
// (_applyCheckoutModeChange) contract EXACTLY and guarantees a Settings
|
|
1234
|
+
// save can never silently leave a stale hybrid block on a project the
|
|
1235
|
+
// operator just moved to Worktrees/Live checkout.
|
|
1236
|
+
let liveValidation = null;
|
|
1237
|
+
if (isHybrid) {
|
|
1238
|
+
const esc = (window.CSS && CSS.escape ? CSS.escape(p.name) : p.name);
|
|
1239
|
+
const typeEls = document.querySelectorAll('[data-live-validation-type="' + esc + '"]');
|
|
1240
|
+
const types = [];
|
|
1241
|
+
typeEls.forEach(function(el) { if (el && el.checked) types.push(el.value); });
|
|
1242
|
+
const errEl = document.querySelector('[data-checkout-hybrid-error="' + esc + '"]');
|
|
1243
|
+
if (types.length === 0) {
|
|
1244
|
+
hybridValidationErrors.push(p.name);
|
|
1245
|
+
if (errEl) errEl.style.display = '';
|
|
1246
|
+
} else {
|
|
1247
|
+
if (errEl) errEl.style.display = 'none';
|
|
1248
|
+
const autoEl = document.getElementById('set-liveValidationAutoDispatch-' + p.name);
|
|
1249
|
+
liveValidation = { type: types, autoDispatch: !!(autoEl && autoEl.checked) };
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1180
1252
|
// W-mqtvnnj1000357fa — per-project live-checkout auto-stash override.
|
|
1181
1253
|
// '' → null (clear override, fall back to engine fleet setting); 'on' →
|
|
1182
1254
|
// true; 'off' → false. The server deletes the field on null and validates
|
|
@@ -1187,7 +1259,8 @@ async function saveSettings() {
|
|
|
1187
1259
|
return {
|
|
1188
1260
|
name: p.name,
|
|
1189
1261
|
mainBranch: mainBranchValue || null,
|
|
1190
|
-
checkoutMode:
|
|
1262
|
+
checkoutMode: checkoutMode,
|
|
1263
|
+
liveValidation: liveValidation,
|
|
1191
1264
|
liveCheckoutAutoStash: autoStashValue,
|
|
1192
1265
|
workSources: {
|
|
1193
1266
|
pullRequests: { enabled: document.getElementById('set-ws-prs-' + p.name)?.checked ?? true },
|
|
@@ -1196,6 +1269,10 @@ async function saveSettings() {
|
|
|
1196
1269
|
};
|
|
1197
1270
|
});
|
|
1198
1271
|
|
|
1272
|
+
if (hybridValidationErrors.length > 0) {
|
|
1273
|
+
throw new Error('Hybrid dispatch needs at least one validation work-item type for: ' + hybridValidationErrors.join(', '));
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1199
1276
|
// Save config
|
|
1200
1277
|
const res = await fetch('/api/settings', {
|
|
1201
1278
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
package/dashboard.js
CHANGED
|
@@ -11037,6 +11037,15 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
11037
11037
|
// the per-project dropdown. resolveCheckoutMode honors the legacy
|
|
11038
11038
|
// worktreeMode field; 'worktree' (default) or 'live'.
|
|
11039
11039
|
checkoutMode: shared.resolveCheckoutMode(p),
|
|
11040
|
+
// W-mr9mx93d000x1dda — surface the hybrid liveValidation config
|
|
11041
|
+
// (type(s) + autoDispatch) so the Settings → Projects checkout-mode
|
|
11042
|
+
// control can pre-fill its Hybrid sub-panel authoritatively (mirrors
|
|
11043
|
+
// the /api/status project mapping the Projects-bar picker reads).
|
|
11044
|
+
// Only meaningful under checkoutMode:'live'; null/false otherwise.
|
|
11045
|
+
liveValidationType: (shared.resolveCheckoutMode(p) === 'live' && p.liveValidation && p.liveValidation.type)
|
|
11046
|
+
? p.liveValidation.type
|
|
11047
|
+
: null,
|
|
11048
|
+
liveValidationAutoDispatch: !!(shared.resolveCheckoutMode(p) === 'live' && p.liveValidation && p.liveValidation.autoDispatch === true),
|
|
11040
11049
|
// W-mqtvnnj1000357fa — surface the RAW per-project auto-stash override
|
|
11041
11050
|
// (true / false / undefined) so the Settings UI can pre-select the
|
|
11042
11051
|
// tri-state dropdown. Undefined means "use fleet default"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2341",
|
|
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"
|