@yemi33/minions 0.1.2439 → 0.1.2440
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/settings.js
CHANGED
|
@@ -1960,4 +1960,25 @@ window.MinionsSettings = { openSettings, saveSettings, addProject, removeProject
|
|
|
1960
1960
|
} else {
|
|
1961
1961
|
setTimeout(openWhenReady, 0);
|
|
1962
1962
|
}
|
|
1963
|
+
// FRESHNESS ON REOPEN (W-ms4ogdc800aa6931): the slim parent now CACHES this
|
|
1964
|
+
// embedded /settings frame (created once, shown/hidden) instead of cold-booting
|
|
1965
|
+
// it per open, so the iframe `load` — and thus the one-shot openSettings() boot
|
|
1966
|
+
// above — fires only ONCE. Re-pull /api/settings + /api/features whenever the
|
|
1967
|
+
// parent re-shows us (visible:true) so a value changed elsewhere isn't stale. A
|
|
1968
|
+
// full openSettings() re-render is cheap here (the SPA is already booted — just
|
|
1969
|
+
// two localhost fetches + a DOM render, no cold boot), so we prefer it over
|
|
1970
|
+
// ad-hoc partial refresh. Reuses the SAME {source:'minions-slim-embed',
|
|
1971
|
+
// type:'visibility'} channel refresh.js already honors (no second postMessage
|
|
1972
|
+
// bus). Embed-mode gated by the isSettingsPath+isEmbed early return above, so a
|
|
1973
|
+
// standalone /settings visit is completely unaffected.
|
|
1974
|
+
try {
|
|
1975
|
+
window.addEventListener('message', function(ev) {
|
|
1976
|
+
if (!ev || ev.origin !== window.location.origin) return;
|
|
1977
|
+
var d = ev.data;
|
|
1978
|
+
if (!d || d.source !== 'minions-slim-embed' || d.type !== 'visibility') return;
|
|
1979
|
+
if (d.visible && typeof openSettings === 'function') {
|
|
1980
|
+
try { openSettings(); } catch (e) { /* transient — next show retries */ }
|
|
1981
|
+
}
|
|
1982
|
+
});
|
|
1983
|
+
} catch (e) { /* defensive — never block the embed boot on this hook */ }
|
|
1963
1984
|
})();
|
|
@@ -18,16 +18,44 @@
|
|
|
18
18
|
// — two stacked "Settings" bars was the duplicate-menu-bar bug
|
|
19
19
|
// (W-mrpbzke4000ie609). Closing is driven from the embedded modal's own close
|
|
20
20
|
// X (wired below to the parent), plus backdrop-click and Escape.
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
// CACHED settings iframe (W-ms4ogdc800aa6931). The old code discarded the
|
|
22
|
+
// frame on close and appended a BRAND-NEW `/settings?embed=1` iframe on every
|
|
23
|
+
// open, so each open cold-booted the entire classic SPA + full Settings render
|
|
24
|
+
// (/api/settings + /api/features + per-agent runtime dropdowns + projects +
|
|
25
|
+
// routing, plus the SPA's 4s /api/status poll) — the multi-second stall. We
|
|
26
|
+
// now mirror the cockpit-tile reuse contract (modals-tiles.js
|
|
27
|
+
// #_getOrCreateEmbedFrame / _showReusableEmbed): create the frame ONCE, keep
|
|
28
|
+
// it mounted (hidden), and show/hide it. A single background boot replaces N
|
|
29
|
+
// per-open cold boots; while hidden the embedded SPA's poll is suspended via
|
|
30
|
+
// the shared {source:'minions-slim-embed',type:'visibility'} message
|
|
31
|
+
// (refresh.js honors it in embed mode) so the cached frame doesn't poll
|
|
32
|
+
// /api/status forever off-screen.
|
|
33
|
+
var _slimSettingsFrame = null;
|
|
34
|
+
|
|
35
|
+
// Create (once) the cached settings iframe and return it. Built with
|
|
36
|
+
// createElement (no innerHTML) to satisfy the dashboard no-unsanitized lint
|
|
37
|
+
// gate. Starts hidden; a load-time visibility message suspends its poll until
|
|
38
|
+
// it is shown. Because the frame is cached, its `load` handler fires exactly
|
|
39
|
+
// ONCE — so the close/Escape wiring is installed here and persists across all
|
|
40
|
+
// hide/show cycles.
|
|
41
|
+
function _getOrCreateSettingsFrame() {
|
|
42
|
+
if (_slimSettingsFrame) return _slimSettingsFrame;
|
|
23
43
|
var body = document.getElementById('slim-settings-body');
|
|
24
|
-
if (!
|
|
25
|
-
body.textContent = '';
|
|
44
|
+
if (!body) return null;
|
|
45
|
+
body.textContent = ''; // drop the "Loading settings…" placeholder (once)
|
|
26
46
|
var frame = document.createElement('iframe');
|
|
27
47
|
frame.className = 'slim-settings-embed';
|
|
28
48
|
frame.src = '/settings?embed=1';
|
|
29
49
|
frame.title = 'Settings';
|
|
50
|
+
frame.hidden = true;
|
|
30
51
|
frame.addEventListener('load', function() {
|
|
52
|
+
// Suspend/resume the embedded SPA poll to match current visibility. On a
|
|
53
|
+
// visible:true the embedded classic Settings also re-pulls /api/settings +
|
|
54
|
+
// /api/features (see dashboard/js/settings.js#bootSettingsEmbed) — the
|
|
55
|
+
// same single postMessage channel, no second bus.
|
|
56
|
+
var modal = document.getElementById('slim-settings-modal');
|
|
57
|
+
var shown = !!(modal && modal.classList.contains('open'));
|
|
58
|
+
if (typeof _postEmbedVisibility === 'function') _postEmbedVisibility(frame, shown);
|
|
31
59
|
var frameDocument = frame.contentDocument;
|
|
32
60
|
if (!frameDocument) return;
|
|
33
61
|
// Capture before the classic modal handler so only the parent modal closes.
|
|
@@ -53,20 +81,50 @@
|
|
|
53
81
|
}
|
|
54
82
|
});
|
|
55
83
|
body.appendChild(frame);
|
|
84
|
+
_slimSettingsFrame = frame;
|
|
85
|
+
return frame;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function openSlimSettings() {
|
|
89
|
+
var modal = document.getElementById('slim-settings-modal');
|
|
90
|
+
var frame = _getOrCreateSettingsFrame();
|
|
91
|
+
if (!modal || !frame) return;
|
|
92
|
+
frame.hidden = false;
|
|
93
|
+
// Resume the embedded SPA poll + trigger a fresh /api/settings+/api/features
|
|
94
|
+
// re-pull (freshness on reopen — the cached frame's `load` fired only once,
|
|
95
|
+
// so without this a value changed elsewhere would show stale).
|
|
96
|
+
if (typeof _postEmbedVisibility === 'function') _postEmbedVisibility(frame, true);
|
|
56
97
|
modal.classList.add('open');
|
|
57
98
|
}
|
|
58
99
|
|
|
59
100
|
function closeSlimSettings() {
|
|
60
|
-
document.getElementById('slim-settings-modal')
|
|
101
|
+
var modal = document.getElementById('slim-settings-modal');
|
|
102
|
+
if (!modal) return;
|
|
103
|
+
// Keep the frame MOUNTED for an instant reopen; just hide it and suspend its
|
|
104
|
+
// poll (so the cached frame stops polling /api/status in the background).
|
|
105
|
+
if (_slimSettingsFrame) {
|
|
106
|
+
if (typeof _postEmbedVisibility === 'function') _postEmbedVisibility(_slimSettingsFrame, false);
|
|
107
|
+
_slimSettingsFrame.hidden = true;
|
|
108
|
+
}
|
|
109
|
+
modal.classList.remove('open');
|
|
61
110
|
}
|
|
62
111
|
|
|
63
112
|
(function bindSettingsUi() {
|
|
64
113
|
var btn = document.getElementById('slim-settings-btn');
|
|
65
114
|
var backdrop = document.getElementById('slim-settings-modal');
|
|
66
|
-
if (btn)
|
|
115
|
+
if (btn) {
|
|
116
|
+
btn.addEventListener('click', openSlimSettings);
|
|
117
|
+
// PREDICTIVE prewarm: the first hover / focus / press of the gear boots the
|
|
118
|
+
// cached settings frame before the click lands, so the open is an instant
|
|
119
|
+
// show. Fires at most once (the frame is cached thereafter).
|
|
120
|
+
var predictivePrewarm = function() { _getOrCreateSettingsFrame(); };
|
|
121
|
+
btn.addEventListener('pointerenter', predictivePrewarm, { once: true });
|
|
122
|
+
btn.addEventListener('pointerdown', predictivePrewarm, { once: true });
|
|
123
|
+
btn.addEventListener('focus', predictivePrewarm, { once: true });
|
|
124
|
+
}
|
|
67
125
|
// No outer close button: the embedded classic Settings modal's own close X
|
|
68
|
-
// (wired to the parent in
|
|
69
|
-
// alongside backdrop-click and Escape below (W-mrpbzke4000ie609).
|
|
126
|
+
// (wired to the parent in _getOrCreateSettingsFrame) is the single close
|
|
127
|
+
// affordance, alongside backdrop-click and Escape below (W-mrpbzke4000ie609).
|
|
70
128
|
if (backdrop) {
|
|
71
129
|
backdrop.addEventListener('click', function(ev) {
|
|
72
130
|
if (ev.target === backdrop) closeSlimSettings();
|
|
@@ -78,6 +136,22 @@
|
|
|
78
136
|
});
|
|
79
137
|
})();
|
|
80
138
|
|
|
139
|
+
// Deferred prewarm: boot the cached settings frame AFTER the cockpit's own hot
|
|
140
|
+
// embed prewarm (modals-tiles.js schedules that at ~800ms) so it never competes
|
|
141
|
+
// with slim cockpit initial paint. Idle-callback when available, else a delayed
|
|
142
|
+
// timeout — either way it runs well after first paint. First open then becomes
|
|
143
|
+
// an instant show instead of a cold boot.
|
|
144
|
+
(function scheduleSettingsPrewarm() {
|
|
145
|
+
var warm = function() { try { _getOrCreateSettingsFrame(); } catch (e) { /* skip prewarm */ } };
|
|
146
|
+
try {
|
|
147
|
+
if (typeof requestIdleCallback === 'function') {
|
|
148
|
+
requestIdleCallback(function() { setTimeout(warm, 1200); }, { timeout: 4000 });
|
|
149
|
+
} else {
|
|
150
|
+
setTimeout(warm, 1600);
|
|
151
|
+
}
|
|
152
|
+
} catch (e) { /* no timers available — skip prewarm, first open cold-boots */ }
|
|
153
|
+
})();
|
|
154
|
+
|
|
81
155
|
// POST a feature-flag toggle; throws on a non-2xx so callers can branch on
|
|
82
156
|
// failure. Used by the one-click returnToClassicDashboard().
|
|
83
157
|
async function postFeatureToggle(id, enabled) {
|
|
@@ -797,6 +797,12 @@
|
|
|
797
797
|
outranks the class rules (no !important needed). */
|
|
798
798
|
.slim-tile-embed-host, .slim-tile-transient { display: block; }
|
|
799
799
|
#slim-tile-embed-host iframe[hidden] { display: none; }
|
|
800
|
+
/* Cached slim Settings frame (W-ms4ogdc800aa6931): like the tile embeds it is
|
|
801
|
+
created once and shown/hidden rather than cold-booted per open. The
|
|
802
|
+
.slim-settings-embed class rule above sets display:block, which outranks
|
|
803
|
+
[hidden]'s UA display:none — so a hidden cached frame must be forced back
|
|
804
|
+
to none. The id+attr selector outranks the class rule (no !important). */
|
|
805
|
+
#slim-settings-body iframe[hidden] { display: none; }
|
|
800
806
|
/* Automation tile (Watches · Schedules · Pipelines) — a tabbed composite
|
|
801
807
|
inside the shared wide tile-modal. The tab bar sits above the embedded
|
|
802
808
|
classic screen, so the iframe height leaves room for it (vs the padless
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2440",
|
|
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"
|