@melaya/runner 1.1.82 → 1.1.83
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/dist/assistantHost.py +2455 -2262
- package/dist/browserAuthz.js +48 -48
- package/dist/browserBridge.js +48 -48
- package/dist/codeWorker.js +68 -68
- package/dist/connection.js +23 -1
- package/dist/localDbProbe.py +286 -286
- package/dist/localVault.py +745 -745
- package/dist/modelLoader.d.ts +12 -0
- package/dist/modelLoader.js +51 -0
- package/dist/turnSummary.d.ts +9 -0
- package/dist/turnSummary.js +29 -0
- package/localDbProbe.py +286 -286
- package/localVault.py +745 -745
- package/package.json +1 -1
- package/dist/linkedinProxy.d.ts +0 -51
- package/dist/linkedinProxy.js +0 -216
- package/dist/linkedinSetup.d.ts +0 -13
- package/dist/linkedinSetup.js +0 -111
package/dist/browserAuthz.js
CHANGED
|
@@ -332,54 +332,54 @@ async function interceptWebSockets(page, policy, hooks) {
|
|
|
332
332
|
* IP leakage via STUN/TURN. Combined with the CDP Network.enable /
|
|
333
333
|
* setRTCConfiguration override (applied separately via CDP below), this
|
|
334
334
|
* provides layered defence. */
|
|
335
|
-
const PAGE_GUARD_INIT_SCRIPT = `(function() {
|
|
336
|
-
// WebRTC neutralisation: remove peer connection constructors.
|
|
337
|
-
try { delete window.RTCPeerConnection; } catch (_) {}
|
|
338
|
-
try { delete window.RTCSessionDescription; } catch (_) {}
|
|
339
|
-
try { delete window.RTCIceCandidate; } catch (_) {}
|
|
340
|
-
// Also zero out webkit/moz-prefixed variants some legacy code still uses.
|
|
341
|
-
try { delete window.webkitRTCPeerConnection; } catch (_) {}
|
|
342
|
-
try { delete window.mozRTCPeerConnection; } catch (_) {}
|
|
343
|
-
// Override navigator.mediaDevices.getUserMedia to prevent media/camera
|
|
344
|
-
// capture that could be combined with a data channel.
|
|
345
|
-
try {
|
|
346
|
-
if (navigator.mediaDevices && typeof navigator.mediaDevices === 'object') {
|
|
347
|
-
Object.defineProperty(navigator, 'mediaDevices', { value: Object.assign({}, navigator.mediaDevices, { getUserMedia: () => Promise.reject(new DOMException('NotAllowedError')) }), configurable: false, writable: false });
|
|
348
|
-
}
|
|
349
|
-
} catch (_) {}
|
|
350
|
-
// WebSocket URL-blocking fallback (defence-in-depth, supplements
|
|
351
|
-
// routeWebSocket interception which fires at the Playwright layer).
|
|
352
|
-
var _NativeWS = window.WebSocket;
|
|
353
|
-
function _isForbiddenWsHost(url) {
|
|
354
|
-
try {
|
|
355
|
-
var u = new URL(url);
|
|
356
|
-
var h = u.hostname.replace(/^\\[|\\]$/g,'');
|
|
357
|
-
// Loopback / localhost
|
|
358
|
-
if (h === 'localhost' || h === '127.0.0.1' || h === '::1' || h.endsWith('.localhost') || h.endsWith('.local')) return true;
|
|
359
|
-
// Link-local (169.254.x.x) — cloud metadata endpoints live here
|
|
360
|
-
if (/^169\\.254\\./.test(h)) return true;
|
|
361
|
-
// RFC1918
|
|
362
|
-
if (/^10\\./.test(h)) return true;
|
|
363
|
-
if (/^172\\.(1[6-9]|2[0-9]|3[01])\\./.test(h)) return true;
|
|
364
|
-
if (/^192\\.168\\./.test(h)) return true;
|
|
365
|
-
// CGNAT
|
|
366
|
-
if (/^100\\.(6[4-9]|[7-9][0-9]|1([01][0-9]|2[0-7]))\\./.test(h)) return true;
|
|
367
|
-
// Explicit metadata hosts
|
|
368
|
-
if (h === '100.100.100.200' || h === 'metadata.google.internal' || h === 'metadata.goog') return true;
|
|
369
|
-
} catch (_) {}
|
|
370
|
-
return false;
|
|
371
|
-
}
|
|
372
|
-
window.WebSocket = function WrappedWebSocket(url, protocols) {
|
|
373
|
-
if (_isForbiddenWsHost(String(url))) {
|
|
374
|
-
throw new DOMException('WebSocket connection to ' + url + ' is blocked by Melaya egress policy', 'SecurityError');
|
|
375
|
-
}
|
|
376
|
-
return protocols !== undefined ? new _NativeWS(url, protocols) : new _NativeWS(url);
|
|
377
|
-
};
|
|
378
|
-
window.WebSocket.prototype = _NativeWS.prototype;
|
|
379
|
-
window.WebSocket.CONNECTING = _NativeWS.CONNECTING;
|
|
380
|
-
window.WebSocket.OPEN = _NativeWS.OPEN;
|
|
381
|
-
window.WebSocket.CLOSING = _NativeWS.CLOSING;
|
|
382
|
-
window.WebSocket.CLOSED = _NativeWS.CLOSED;
|
|
335
|
+
const PAGE_GUARD_INIT_SCRIPT = `(function() {
|
|
336
|
+
// WebRTC neutralisation: remove peer connection constructors.
|
|
337
|
+
try { delete window.RTCPeerConnection; } catch (_) {}
|
|
338
|
+
try { delete window.RTCSessionDescription; } catch (_) {}
|
|
339
|
+
try { delete window.RTCIceCandidate; } catch (_) {}
|
|
340
|
+
// Also zero out webkit/moz-prefixed variants some legacy code still uses.
|
|
341
|
+
try { delete window.webkitRTCPeerConnection; } catch (_) {}
|
|
342
|
+
try { delete window.mozRTCPeerConnection; } catch (_) {}
|
|
343
|
+
// Override navigator.mediaDevices.getUserMedia to prevent media/camera
|
|
344
|
+
// capture that could be combined with a data channel.
|
|
345
|
+
try {
|
|
346
|
+
if (navigator.mediaDevices && typeof navigator.mediaDevices === 'object') {
|
|
347
|
+
Object.defineProperty(navigator, 'mediaDevices', { value: Object.assign({}, navigator.mediaDevices, { getUserMedia: () => Promise.reject(new DOMException('NotAllowedError')) }), configurable: false, writable: false });
|
|
348
|
+
}
|
|
349
|
+
} catch (_) {}
|
|
350
|
+
// WebSocket URL-blocking fallback (defence-in-depth, supplements
|
|
351
|
+
// routeWebSocket interception which fires at the Playwright layer).
|
|
352
|
+
var _NativeWS = window.WebSocket;
|
|
353
|
+
function _isForbiddenWsHost(url) {
|
|
354
|
+
try {
|
|
355
|
+
var u = new URL(url);
|
|
356
|
+
var h = u.hostname.replace(/^\\[|\\]$/g,'');
|
|
357
|
+
// Loopback / localhost
|
|
358
|
+
if (h === 'localhost' || h === '127.0.0.1' || h === '::1' || h.endsWith('.localhost') || h.endsWith('.local')) return true;
|
|
359
|
+
// Link-local (169.254.x.x) — cloud metadata endpoints live here
|
|
360
|
+
if (/^169\\.254\\./.test(h)) return true;
|
|
361
|
+
// RFC1918
|
|
362
|
+
if (/^10\\./.test(h)) return true;
|
|
363
|
+
if (/^172\\.(1[6-9]|2[0-9]|3[01])\\./.test(h)) return true;
|
|
364
|
+
if (/^192\\.168\\./.test(h)) return true;
|
|
365
|
+
// CGNAT
|
|
366
|
+
if (/^100\\.(6[4-9]|[7-9][0-9]|1([01][0-9]|2[0-7]))\\./.test(h)) return true;
|
|
367
|
+
// Explicit metadata hosts
|
|
368
|
+
if (h === '100.100.100.200' || h === 'metadata.google.internal' || h === 'metadata.goog') return true;
|
|
369
|
+
} catch (_) {}
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
window.WebSocket = function WrappedWebSocket(url, protocols) {
|
|
373
|
+
if (_isForbiddenWsHost(String(url))) {
|
|
374
|
+
throw new DOMException('WebSocket connection to ' + url + ' is blocked by Melaya egress policy', 'SecurityError');
|
|
375
|
+
}
|
|
376
|
+
return protocols !== undefined ? new _NativeWS(url, protocols) : new _NativeWS(url);
|
|
377
|
+
};
|
|
378
|
+
window.WebSocket.prototype = _NativeWS.prototype;
|
|
379
|
+
window.WebSocket.CONNECTING = _NativeWS.CONNECTING;
|
|
380
|
+
window.WebSocket.OPEN = _NativeWS.OPEN;
|
|
381
|
+
window.WebSocket.CLOSING = _NativeWS.CLOSING;
|
|
382
|
+
window.WebSocket.CLOSED = _NativeWS.CLOSED;
|
|
383
383
|
})();`;
|
|
384
384
|
/** Disable WebRTC at the CDP Network domain level in addition to the
|
|
385
385
|
* init-script layer (belt-and-suspenders). Silently skips if CDP
|
package/dist/browserBridge.js
CHANGED
|
@@ -66,29 +66,29 @@ function cdpRace(p, what, ms = 20_000) {
|
|
|
66
66
|
// across navigations) and the one-shot page.evaluate on the already-open page.
|
|
67
67
|
// Palette: cyan #22D3EE primary accent, indigo #7C6FF0 subtle secondary,
|
|
68
68
|
// slate/navy #0F172A base. Less purple than the prior version.
|
|
69
|
-
const MELAYA_BRAND_SCRIPT = `(() => {
|
|
70
|
-
// Top document ONLY: injecting into sub-frames (e.g. the Google Sign-In
|
|
71
|
-
// iframe) rendered a stray badge on top of third-party widgets.
|
|
72
|
-
try { if (window.top !== window.self) return; } catch (e) { return; }
|
|
73
|
-
if (window.__melayaBrand) return; window.__melayaBrand = true;
|
|
74
|
-
const ID = "__melaya_brand";
|
|
75
|
-
const LOGO = "data:image/png;base64,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";
|
|
76
|
-
const inject = () => {
|
|
77
|
-
const root = document.documentElement; if (!root) return;
|
|
78
|
-
if (document.getElementById(ID + "_border")) return;
|
|
79
|
-
const style = document.createElement("style");
|
|
80
|
-
style.id = ID + "_style";
|
|
81
|
-
style.textContent = "@keyframes melBrandPulse{0%,100%{box-shadow:inset 0 0 9px 2px rgba(34,211,238,.5),inset 0 0 30px 7px rgba(124,111,240,.18)}50%{box-shadow:inset 0 0 16px 4px rgba(34,211,238,.8),inset 0 0 54px 13px rgba(124,111,240,.32)}}@keyframes melBrandGlow{0%,100%{opacity:.78}50%{opacity:1}}#" + ID + "_border{position:fixed;inset:0;pointer-events:none;z-index:2147483647;border-radius:7px;animation:melBrandPulse 2.6s ease-in-out infinite}#" + ID + "_badge{position:fixed;top:10px;left:50%;transform:translateX(-50%);pointer-events:none;z-index:2147483647;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-weight:600;font-size:12px;line-height:1;white-space:nowrap;max-width:calc(100vw - 24px);box-sizing:border-box;color:#E2E8F0;background:linear-gradient(180deg,rgba(15,23,42,.94),rgba(15,23,42,.82));padding:5px 13px 5px 7px;border-radius:999px;letter-spacing:.2px;border:1px solid rgba(34,211,238,.45);box-shadow:0 0 16px 1px rgba(34,211,238,.4),0 4px 14px rgba(0,0,0,.45);display:flex;align-items:center;gap:8px;backdrop-filter:blur(6px);animation:melBrandGlow 2.6s ease-in-out infinite}#" + ID + "_logo{height:16px;width:auto;display:block;filter:drop-shadow(0 0 4px rgba(34,211,238,.55))}#" + ID + "_label{display:inline-flex;align-items:center;height:16px;line-height:1}@media (max-width:600px){#" + ID + "_badge{font-size:10px;padding:4px 10px 4px 6px;gap:6px;top:6px}#" + ID + "_logo{height:13px}#" + ID + "_label{height:13px}}";
|
|
82
|
-
(document.head || root).appendChild(style);
|
|
83
|
-
const border = document.createElement("div"); border.id = ID + "_border";
|
|
84
|
-
const badge = document.createElement("div"); badge.id = ID + "_badge";
|
|
85
|
-
const logo = document.createElement("img"); logo.id = ID + "_logo"; logo.src = LOGO; logo.alt = "Melaya";
|
|
86
|
-
const label = document.createElement("span"); label.id = ID + "_label"; label.textContent = "Controlled by Melaya";
|
|
87
|
-
badge.appendChild(logo); badge.appendChild(label);
|
|
88
|
-
root.appendChild(border); root.appendChild(badge);
|
|
89
|
-
};
|
|
90
|
-
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", inject); else inject();
|
|
91
|
-
try { new MutationObserver(() => { if (!document.getElementById(ID + "_border")) inject(); }).observe(document.documentElement, { childList: true }); } catch (e) {}
|
|
69
|
+
const MELAYA_BRAND_SCRIPT = `(() => {
|
|
70
|
+
// Top document ONLY: injecting into sub-frames (e.g. the Google Sign-In
|
|
71
|
+
// iframe) rendered a stray badge on top of third-party widgets.
|
|
72
|
+
try { if (window.top !== window.self) return; } catch (e) { return; }
|
|
73
|
+
if (window.__melayaBrand) return; window.__melayaBrand = true;
|
|
74
|
+
const ID = "__melaya_brand";
|
|
75
|
+
const LOGO = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAsCAMAAADGmMENAAADAFBMVEVMaXEATOaL9vsBTesAEokAF5oAEo0AY9sAHafj/f8ADogAUucAfuoARscAXusAeOce1/8Ac+UAb+QTzv8D2P8CoPfT9v8BCHIAEpMAF5YASsoAQMUAT80AHq4B1f8A0/8ENska0v8FGn8BU9Dy//8AFpECauEAg+0Bie4AO8EBkfIAlfUAGqIAzv8i3f8AXNbM8f8HLosBO+RB7/8CjfBd7P598P4Lre8GQ9cH3P8Ev/067f8w6f8AL7MAObcACnsBU9gHpe4Aaugo4f8FaPBK8f8JxP0AJ7cA0f8ArfoP2//a+/8ADYIDStIBjOgQvPQBi/QInugBhOkKf9sAWNIBgOXe+/8Ltf/r//8AZduf8/4ktfctt/p08P1I1P0Rw/gEleoVyvoAZN8AYtwGadQFm+8Sv/4Cb/ABWdwCQ80AJq8EYeiL8P9r8v912/whsegkeLcMtfEAXuACY+QAWOUBfu0ClO800f3E8v8AZ90+4/+64v4AReyWu/gBSNT5//4u4P8WPoRf0/MNuPkHoOwnxfsas/EAa+TO+/YFie0CQ8sWxvtJjvgAT9QCJ4QAZuxhv+8DkN0AHIoomOoUnfkQS5MdfsgML30CeNMuXJlQib9P5P6m9/sAOtQANs0ALL+h+PwAYuMIne4ZwfUBj+8Oq+yn1/2e+P0BcOp+vfvP+Pw8ofgTaO1no/YHTMOazfsEW6Vg4PwAK7Uck/qI9v5Gca09wPxim8s4ZKkIPpkCfuMBbuNb6v0AYuRe7PyL9v0AhfOL8vJO5fsBmvQAV+aM9vwESNwALb1F4Pwp0fcAKLcAIaoEQtoXX/EAU88BW+cAGJkAfPAsdPMgfe8oaaLQ+vtTg7o/pdIzuul5sNh3vNwAY98PoOG27/4T3/8AWOkAGaABY+4Csv0BRuQCuf0k5v8EqvsBmvYCy/8PyP8DpPwHg/oDePQKsPYAML4Bdesb4/8AmvwBYdoIb7dP/P8BWfMAUPIAIJsAkfsTpOMARLUDY/Vostxr/v8r7v8zndiULzD1AAAA3nRSTlMA/gP+/v7+Av7+/v7+/v79/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vz+/v3+/v7+/v7+/v7+/v79/v7+/v7+/f3+/v3+/gn+/P7+/v79/f76+v7+/v0gFP7+/v7++/79/f3+/v7+/vxC/vX+/v3+/v4z/v7+/v4t90pmEpFn/v7+/qr++P7++/7+/v7+/v5HUM6PaeZkptHN/o6A/ij+9/6j/v7+qv7q/v7+/v6xz7CH0LPFKoyow9Chu2PJfevd/t3c5L3+/v6a/v7+/qny6f5DYJsMAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFTklEQVR42oXVd1jSeRzA8Z8JCCEgIJi4Q4npDs+BkaKgYplmpqkt98ortdKu1Pbe++queXXta9/ee49u/KFAoiiouRtW9/n+0MrOuu/z8Dw8PK/f5/f+wcP3i2Ej15gx8FpzbOqJNSkYZmeHvWwBxdZ9/c3c1pD29hNHc17qkf3k08W+7Kmvhkyeltuyff0q5Ee7AE94/f1qo9fc2bieM2VKUuq7lWNG8ciue/PDoEcODs/oVIal8721zwehhLffmtj7KDra9xmdnMpgCqJURz6Y/zTImvBRaW94RATCbNDtIZNzcc0SLFrY2FextdLO6vGELx72BoUP642zVyJdNSXZHumKCqpNP/XztegbRQlXHvbGxCAdbdV5K9vbOblVwgn2nayoYirVBlZ/30+nIOiPDGRjgoLCI2KqG+JBt4Ju5rSIk0BH0YvP2sKyoVL7+86uxzLkJaVgYbSxZGbGQS9T68a8NENzW4skyWzJ/+1czWvLbPFFV6nMWNadg1klpUEREeFGube395Iyr7CmtLTmtq67ZvOZC/4JFKvuUy1SFrIwudE33uFSSVaQ8Y7cm0LxXjEjIxvHZ07XJCRw/RNA9z9QFRSKChM7QUc7sE2x2WXyCPmKmRQKZSa6Qea2k9wZXH9YlNf6HxQnijoAb2ZgWaC92LFNhsyy0gwK7uECCsVqExJqNlW4KNQiFxqPr7QH7evAbo0Na4rLnBhaK+eu8EZ+BpfL9YfpFzbZ9onUHSKRC891ul8yPOVTfachtGHiEm98MjeBsuT0r8sCb+tpCNNc+X7dQqS9hnUDcEfH6gxUQqk590Ng4G0bGxWtwwV1TO9OD8ay8B8E6VlIx4c6emhqS7gnN9nilkpV8VA0dKQvFWJXHsWz2a1hTbhuQLPd3WUeuwLBItzYmO8qAsz380vv3IX9M1hfawoLazLgGka7e2hkjsFgcUwHDU8Impnacx4re3zger1DmOGp1mhk7uKhyXQ63cJ34fH4rH0XAwaUWLZp473yA9sWp3Fw7QjZGpmHGE8GrNeD3izYd3HLgFqdiGU3GQzt28tvDV7LPBgKGoWYPCS3wSKs0lu6BXt2bxlwI0vJSMdxxOLc7T1X/5YbHd0hRCYzaSQ2jYD1sCy7wBLJunFEstsrWLYhjlOVzGKl7rt5Y/CS0UOG6xYqFOvpevPlPXVORKnP2HFEKdKLDc0twcnMdD7/5p/lN67XGzUmE+hGPbI7y+t2RI6fpB1LGtbNHInQnpU+nRbwl9eCnv236ms1sTIOna4Cu3eHoqNwvNNYpHVIr27jiJMZgm7QCwyGvJCe3Ve3VbtLHlze+TtYBVnnOVK3BNszl/rxkY7jcNJCeur2D157vH+8T1GRs7OUPKzxktVdEiEDQlxdQMOfN1jcNrlnb50TgTxAIDjryOQRs2dJxBOYEILrNo5ILLS3l1TdJ/potSRn4vM6L0mIh/BEAffQvhAM2wizk+akJRBGarzkWNtdhgBCaKBhW0CYwey8P4lAIPg80QTSOGed2vNLDFv1WZLFz5VHiwy41wUdCLOikCaBlj7Rburzy/G9bdV6RjFPFBkwrcs6mSWIihzS1tlagvS7N+bjFu2x808dUYKWDOF5i0ZqndVa92S01+as/fH+nKQh3L0w8kmJ1HPg529zRhwQ6H3KhuNdZisuKBjWRDfP7zfk/PcwQf7ocXP+vHkLC5QFikmAfXzIHYc3pIx+sMFndms+tkQplZuVCi2JRJKqDx9KecGhNuQrf8lvTExUaAm6oq8O2b3YDvVglVuLqQpi0TvL//cwtoLlW2mj238Bms49IJNu4nIAAAAASUVORK5CYII=";
|
|
76
|
+
const inject = () => {
|
|
77
|
+
const root = document.documentElement; if (!root) return;
|
|
78
|
+
if (document.getElementById(ID + "_border")) return;
|
|
79
|
+
const style = document.createElement("style");
|
|
80
|
+
style.id = ID + "_style";
|
|
81
|
+
style.textContent = "@keyframes melBrandPulse{0%,100%{box-shadow:inset 0 0 9px 2px rgba(34,211,238,.5),inset 0 0 30px 7px rgba(124,111,240,.18)}50%{box-shadow:inset 0 0 16px 4px rgba(34,211,238,.8),inset 0 0 54px 13px rgba(124,111,240,.32)}}@keyframes melBrandGlow{0%,100%{opacity:.78}50%{opacity:1}}#" + ID + "_border{position:fixed;inset:0;pointer-events:none;z-index:2147483647;border-radius:7px;animation:melBrandPulse 2.6s ease-in-out infinite}#" + ID + "_badge{position:fixed;top:10px;left:50%;transform:translateX(-50%);pointer-events:none;z-index:2147483647;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-weight:600;font-size:12px;line-height:1;white-space:nowrap;max-width:calc(100vw - 24px);box-sizing:border-box;color:#E2E8F0;background:linear-gradient(180deg,rgba(15,23,42,.94),rgba(15,23,42,.82));padding:5px 13px 5px 7px;border-radius:999px;letter-spacing:.2px;border:1px solid rgba(34,211,238,.45);box-shadow:0 0 16px 1px rgba(34,211,238,.4),0 4px 14px rgba(0,0,0,.45);display:flex;align-items:center;gap:8px;backdrop-filter:blur(6px);animation:melBrandGlow 2.6s ease-in-out infinite}#" + ID + "_logo{height:16px;width:auto;display:block;filter:drop-shadow(0 0 4px rgba(34,211,238,.55))}#" + ID + "_label{display:inline-flex;align-items:center;height:16px;line-height:1}@media (max-width:600px){#" + ID + "_badge{font-size:10px;padding:4px 10px 4px 6px;gap:6px;top:6px}#" + ID + "_logo{height:13px}#" + ID + "_label{height:13px}}";
|
|
82
|
+
(document.head || root).appendChild(style);
|
|
83
|
+
const border = document.createElement("div"); border.id = ID + "_border";
|
|
84
|
+
const badge = document.createElement("div"); badge.id = ID + "_badge";
|
|
85
|
+
const logo = document.createElement("img"); logo.id = ID + "_logo"; logo.src = LOGO; logo.alt = "Melaya";
|
|
86
|
+
const label = document.createElement("span"); label.id = ID + "_label"; label.textContent = "Controlled by Melaya";
|
|
87
|
+
badge.appendChild(logo); badge.appendChild(label);
|
|
88
|
+
root.appendChild(border); root.appendChild(badge);
|
|
89
|
+
};
|
|
90
|
+
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", inject); else inject();
|
|
91
|
+
try { new MutationObserver(() => { if (!document.getElementById(ID + "_border")) inject(); }).observe(document.documentElement, { childList: true }); } catch (e) {}
|
|
92
92
|
})();`;
|
|
93
93
|
// ── Stealth init script ────────────────────────────────────────────────────
|
|
94
94
|
// Runs in EVERY frame BEFORE page scripts (context.addInitScript).
|
|
@@ -103,31 +103,31 @@ const MELAYA_BRAND_SCRIPT = `(() => {
|
|
|
103
103
|
// Any function we replace is given a native-looking toString so the patch is not
|
|
104
104
|
// itself a tell. We do NOT fake plugins/webgl/hardware/languages/chrome — a real
|
|
105
105
|
// headed browser already has correct, self-consistent values.
|
|
106
|
-
const STEALTH_SCRIPT = `(() => {
|
|
107
|
-
const def = (o, k, get) => { try { Object.defineProperty(o, k, { get, configurable: true }); } catch (e) {} };
|
|
108
|
-
const nativeToString = (fn, name) => {
|
|
109
|
-
try {
|
|
110
|
-
const s = "function " + name + "() { [native code] }";
|
|
111
|
-
Object.defineProperty(fn, "toString", { value: function () { return s; }, configurable: true, writable: true });
|
|
112
|
-
} catch (e) {}
|
|
113
|
-
};
|
|
114
|
-
// 1. navigator.webdriver → false. The launch flag disables it, but some CDP
|
|
115
|
-
// builds still expose it truthy; keep it false as a belt-and-suspenders.
|
|
116
|
-
def(Object.getPrototypeOf(navigator) || navigator, "webdriver", () => false);
|
|
117
|
-
try { delete Navigator.prototype.webdriver; } catch (e) {}
|
|
118
|
-
// 2. Notification.permission must agree with permissions.query (CDP mismatch).
|
|
119
|
-
try {
|
|
120
|
-
const q = navigator.permissions && navigator.permissions.query ? navigator.permissions.query.bind(navigator.permissions) : null;
|
|
121
|
-
if (q) {
|
|
122
|
-
const patched = function (p) {
|
|
123
|
-
return (p && p.name === "notifications")
|
|
124
|
-
? Promise.resolve({ state: (typeof Notification !== "undefined" ? Notification.permission : "default"), onchange: null })
|
|
125
|
-
: q(p);
|
|
126
|
-
};
|
|
127
|
-
nativeToString(patched, "query");
|
|
128
|
-
navigator.permissions.query = patched;
|
|
129
|
-
}
|
|
130
|
-
} catch (e) {}
|
|
106
|
+
const STEALTH_SCRIPT = `(() => {
|
|
107
|
+
const def = (o, k, get) => { try { Object.defineProperty(o, k, { get, configurable: true }); } catch (e) {} };
|
|
108
|
+
const nativeToString = (fn, name) => {
|
|
109
|
+
try {
|
|
110
|
+
const s = "function " + name + "() { [native code] }";
|
|
111
|
+
Object.defineProperty(fn, "toString", { value: function () { return s; }, configurable: true, writable: true });
|
|
112
|
+
} catch (e) {}
|
|
113
|
+
};
|
|
114
|
+
// 1. navigator.webdriver → false. The launch flag disables it, but some CDP
|
|
115
|
+
// builds still expose it truthy; keep it false as a belt-and-suspenders.
|
|
116
|
+
def(Object.getPrototypeOf(navigator) || navigator, "webdriver", () => false);
|
|
117
|
+
try { delete Navigator.prototype.webdriver; } catch (e) {}
|
|
118
|
+
// 2. Notification.permission must agree with permissions.query (CDP mismatch).
|
|
119
|
+
try {
|
|
120
|
+
const q = navigator.permissions && navigator.permissions.query ? navigator.permissions.query.bind(navigator.permissions) : null;
|
|
121
|
+
if (q) {
|
|
122
|
+
const patched = function (p) {
|
|
123
|
+
return (p && p.name === "notifications")
|
|
124
|
+
? Promise.resolve({ state: (typeof Notification !== "undefined" ? Notification.permission : "default"), onchange: null })
|
|
125
|
+
: q(p);
|
|
126
|
+
};
|
|
127
|
+
nativeToString(patched, "query");
|
|
128
|
+
navigator.permissions.query = patched;
|
|
129
|
+
}
|
|
130
|
+
} catch (e) {}
|
|
131
131
|
})();`;
|
|
132
132
|
// ── Humanized input helpers ────────────────────────────────────────────────
|
|
133
133
|
// Instant teleport-clicks and zero-delay typing are a behavioural bot tell.
|
package/dist/codeWorker.js
CHANGED
|
@@ -95,74 +95,74 @@ const WORKER_OP_ALLOWLIST = new Set([
|
|
|
95
95
|
// boundary is the process + OS sandbox around it. The vm context exposes
|
|
96
96
|
// exactly: browser.<op>(), console.log/warn/error, sleep(ms), and
|
|
97
97
|
// JSON/Math/Date via the fresh realm.
|
|
98
|
-
const WORKER_ENTRY_SOURCE = `"use strict";
|
|
99
|
-
const vm = require("node:vm");
|
|
100
|
-
const readline = require("node:readline");
|
|
101
|
-
|
|
102
|
-
let seq = 0;
|
|
103
|
-
const pending = new Map();
|
|
104
|
-
function send(msg) { process.stdout.write(JSON.stringify(msg) + "\\n"); }
|
|
105
|
-
|
|
106
|
-
const rl = readline.createInterface({ input: process.stdin, terminal: false });
|
|
107
|
-
let scriptSource = null;
|
|
108
|
-
rl.on("line", (line) => {
|
|
109
|
-
let m;
|
|
110
|
-
try { m = JSON.parse(line); } catch { return; }
|
|
111
|
-
if (m.type === "start" && typeof m.script === "string" && scriptSource === null) {
|
|
112
|
-
scriptSource = m.script;
|
|
113
|
-
run(scriptSource);
|
|
114
|
-
} else if (m.type === "op_result" && pending.has(m.id)) {
|
|
115
|
-
const { resolve, reject } = pending.get(m.id);
|
|
116
|
-
pending.delete(m.id);
|
|
117
|
-
if (m.ok) resolve(m.result);
|
|
118
|
-
else reject(new Error(m.error || "op failed"));
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
function facadeOp(op) {
|
|
123
|
-
return (args) => new Promise((resolve, reject) => {
|
|
124
|
-
const id = ++seq;
|
|
125
|
-
pending.set(id, { resolve, reject });
|
|
126
|
-
send({ type: "op", id, op, args: args && typeof args === "object" ? args : {} });
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async function run(source) {
|
|
131
|
-
const browser = Object.freeze({
|
|
132
|
-
currentTarget: facadeOp("current_target"),
|
|
133
|
-
getScreenTree: facadeOp("get_screen_tree"),
|
|
134
|
-
screenshot: facadeOp("screenshot"),
|
|
135
|
-
act: facadeOp("act"),
|
|
136
|
-
wait: facadeOp("wait"),
|
|
137
|
-
});
|
|
138
|
-
const consoleShim = {
|
|
139
|
-
log: (...a) => send({ type: "console", line: a.map(String).join(" ") }),
|
|
140
|
-
warn: (...a) => send({ type: "console", line: "[warn] " + a.map(String).join(" ") }),
|
|
141
|
-
error: (...a) => send({ type: "console", line: "[error] " + a.map(String).join(" ") }),
|
|
142
|
-
};
|
|
143
|
-
const sleep = (ms) => facadeOp("wait")({ ms });
|
|
144
|
-
const ctx = vm.createContext(Object.create(null), { codeGeneration: { strings: false, wasm: false } });
|
|
145
|
-
ctx.browser = browser;
|
|
146
|
-
ctx.console = consoleShim;
|
|
147
|
-
ctx.sleep = sleep;
|
|
148
|
-
ctx.JSON = JSON;
|
|
149
|
-
try {
|
|
150
|
-
const script = new vm.Script(
|
|
151
|
-
"(async () => {\\n" + source + "\\n})()",
|
|
152
|
-
{ filename: "model-script.js" },
|
|
153
|
-
);
|
|
154
|
-
const result = await script.runInContext(ctx, { timeout: 30000 });
|
|
155
|
-
send({ type: "done", result: safeJson(result) });
|
|
156
|
-
} catch (e) {
|
|
157
|
-
send({ type: "error", message: String((e && e.message) || e) });
|
|
158
|
-
}
|
|
159
|
-
process.exit(0);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function safeJson(v) {
|
|
163
|
-
try { return JSON.parse(JSON.stringify(v === undefined ? null : v)); }
|
|
164
|
-
catch { return String(v); }
|
|
165
|
-
}
|
|
98
|
+
const WORKER_ENTRY_SOURCE = `"use strict";
|
|
99
|
+
const vm = require("node:vm");
|
|
100
|
+
const readline = require("node:readline");
|
|
101
|
+
|
|
102
|
+
let seq = 0;
|
|
103
|
+
const pending = new Map();
|
|
104
|
+
function send(msg) { process.stdout.write(JSON.stringify(msg) + "\\n"); }
|
|
105
|
+
|
|
106
|
+
const rl = readline.createInterface({ input: process.stdin, terminal: false });
|
|
107
|
+
let scriptSource = null;
|
|
108
|
+
rl.on("line", (line) => {
|
|
109
|
+
let m;
|
|
110
|
+
try { m = JSON.parse(line); } catch { return; }
|
|
111
|
+
if (m.type === "start" && typeof m.script === "string" && scriptSource === null) {
|
|
112
|
+
scriptSource = m.script;
|
|
113
|
+
run(scriptSource);
|
|
114
|
+
} else if (m.type === "op_result" && pending.has(m.id)) {
|
|
115
|
+
const { resolve, reject } = pending.get(m.id);
|
|
116
|
+
pending.delete(m.id);
|
|
117
|
+
if (m.ok) resolve(m.result);
|
|
118
|
+
else reject(new Error(m.error || "op failed"));
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
function facadeOp(op) {
|
|
123
|
+
return (args) => new Promise((resolve, reject) => {
|
|
124
|
+
const id = ++seq;
|
|
125
|
+
pending.set(id, { resolve, reject });
|
|
126
|
+
send({ type: "op", id, op, args: args && typeof args === "object" ? args : {} });
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function run(source) {
|
|
131
|
+
const browser = Object.freeze({
|
|
132
|
+
currentTarget: facadeOp("current_target"),
|
|
133
|
+
getScreenTree: facadeOp("get_screen_tree"),
|
|
134
|
+
screenshot: facadeOp("screenshot"),
|
|
135
|
+
act: facadeOp("act"),
|
|
136
|
+
wait: facadeOp("wait"),
|
|
137
|
+
});
|
|
138
|
+
const consoleShim = {
|
|
139
|
+
log: (...a) => send({ type: "console", line: a.map(String).join(" ") }),
|
|
140
|
+
warn: (...a) => send({ type: "console", line: "[warn] " + a.map(String).join(" ") }),
|
|
141
|
+
error: (...a) => send({ type: "console", line: "[error] " + a.map(String).join(" ") }),
|
|
142
|
+
};
|
|
143
|
+
const sleep = (ms) => facadeOp("wait")({ ms });
|
|
144
|
+
const ctx = vm.createContext(Object.create(null), { codeGeneration: { strings: false, wasm: false } });
|
|
145
|
+
ctx.browser = browser;
|
|
146
|
+
ctx.console = consoleShim;
|
|
147
|
+
ctx.sleep = sleep;
|
|
148
|
+
ctx.JSON = JSON;
|
|
149
|
+
try {
|
|
150
|
+
const script = new vm.Script(
|
|
151
|
+
"(async () => {\\n" + source + "\\n})()",
|
|
152
|
+
{ filename: "model-script.js" },
|
|
153
|
+
);
|
|
154
|
+
const result = await script.runInContext(ctx, { timeout: 30000 });
|
|
155
|
+
send({ type: "done", result: safeJson(result) });
|
|
156
|
+
} catch (e) {
|
|
157
|
+
send({ type: "error", message: String((e && e.message) || e) });
|
|
158
|
+
}
|
|
159
|
+
process.exit(0);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function safeJson(v) {
|
|
163
|
+
try { return JSON.parse(JSON.stringify(v === undefined ? null : v)); }
|
|
164
|
+
catch { return String(v); }
|
|
165
|
+
}
|
|
166
166
|
`;
|
|
167
167
|
function nodePermissionFlags(scratchDir, entryPath) {
|
|
168
168
|
const major = Number(process.version.replace(/^v/, "").split(".")[0]) || 0;
|
package/dist/connection.js
CHANGED
|
@@ -40,6 +40,7 @@ import { getRunnerDeviceId } from "./sessionManager.js";
|
|
|
40
40
|
import { scrubTriggeredEnv } from "./triggerEnv.js";
|
|
41
41
|
import { pickNativeFolder } from "./folderPicker.js";
|
|
42
42
|
import { newTurnFileState, readTurnFile, turnOutputDir } from "./assistantFiles.js";
|
|
43
|
+
import { formatTurnSummary } from "./turnSummary.js";
|
|
43
44
|
// Obsidian vault host (docs/plans/obsidian-vault-protocol.md): device vaults
|
|
44
45
|
// registered on this computer, served after the runner verifies each
|
|
45
46
|
// capability itself.
|
|
@@ -1871,6 +1872,15 @@ export async function connect(opts) {
|
|
|
1871
1872
|
}
|
|
1872
1873
|
if (parsed?.kind === "done" && typeof parsed.turnId === "string")
|
|
1873
1874
|
session.turnFiles?.delete(parsed.turnId);
|
|
1875
|
+
// One line per turn (why it ended, the model's finish_reason, tool
|
|
1876
|
+
// calls, context use): the runner log used to show only the session
|
|
1877
|
+
// start, which made a looping local model hard to diagnose. Logged
|
|
1878
|
+
// here and not forwarded (the server protocol is unchanged).
|
|
1879
|
+
if (parsed?.kind === "done" && parsed.summary && typeof parsed.summary === "object") {
|
|
1880
|
+
if (session.forward)
|
|
1881
|
+
console.log(chalk.gray(` ◆ Assistant turn ${String(parsed.turnId || "").slice(0, 8)}… ${formatTurnSummary(parsed.summary)}`));
|
|
1882
|
+
delete parsed.summary;
|
|
1883
|
+
}
|
|
1874
1884
|
if (typeof parsed?.memoryWatermark === "number")
|
|
1875
1885
|
session.memoryWatermark = parsed.memoryWatermark;
|
|
1876
1886
|
if (parsed?.kind === "ready") {
|
|
@@ -2031,8 +2041,20 @@ export async function connect(opts) {
|
|
|
2031
2041
|
const certBundle = (await import("./pythonEnv.js")).getCertBundlePath();
|
|
2032
2042
|
const sslEnv = certBundle ? { SSL_CERT_FILE: certBundle, REQUESTS_CA_BUNDLE: certBundle } : {};
|
|
2033
2043
|
const httpBase = opts.serverUrl.replace(/^wss:/, "https:").replace(/^ws:/, "http:");
|
|
2044
|
+
// Same MEL_MODEL_* scrub as the pipeline spawns: a stray value in the
|
|
2045
|
+
// runner's own env (e.g. MEL_MODEL_MAX_ITERS) must never govern the host.
|
|
2046
|
+
const inherited = { ...process.env };
|
|
2047
|
+
for (const k of Object.keys(inherited)) {
|
|
2048
|
+
if (k.startsWith("MEL_MODEL_"))
|
|
2049
|
+
delete inherited[k];
|
|
2050
|
+
}
|
|
2051
|
+
// Local models (ollama / lmstudio): output cap, family and the context
|
|
2052
|
+
// window the model is loaded with, like a pipeline run's preflight profile.
|
|
2053
|
+
const { assistantModelEnv } = await import("./modelLoader.js");
|
|
2054
|
+
const modelEnv = await assistantModelEnv(String(payload.provider || ""), String(payload.model || ""));
|
|
2034
2055
|
const env = {
|
|
2035
|
-
...
|
|
2056
|
+
...inherited,
|
|
2057
|
+
...modelEnv,
|
|
2036
2058
|
PYTHONPATH: sharedDir,
|
|
2037
2059
|
PYTHONIOENCODING: "utf-8",
|
|
2038
2060
|
PYTHONUTF8: "1",
|