@leg3ndy/otto-bridge 0.7.2 → 0.7.4
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/README.md
CHANGED
|
@@ -33,12 +33,12 @@ Enquanto o pacote nao estiver publicado, voce pode gerar um tarball local:
|
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
35
|
npm pack
|
|
36
|
-
npm install -g ./leg3ndy-otto-bridge-0.7.
|
|
36
|
+
npm install -g ./leg3ndy-otto-bridge-0.7.4.tgz
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
No `0.7.
|
|
39
|
+
No `0.7.4`, `playwright` segue como dependencia obrigatoria no `otto-bridge`. O primeiro `npm install -g @leg3ndy/otto-bridge` pode demorar mais porque instala o browser persistente usado pelo WhatsApp Web e pelos fluxos web em background do bridge.
|
|
40
40
|
|
|
41
|
-
No macOS, o `0.7.
|
|
41
|
+
No macOS, o `0.7.4` usa o provider `macos-helper`, um helper `WKWebView` sem Dock para o WhatsApp Web. O helper sobe com user-agent de Chrome moderno para evitar o bloqueio do WhatsApp ao detectar Safari/WebKit. O runtime antigo com Chromium/Playwright fica disponivel apenas como override explicito via `OTTO_BRIDGE_WHATSAPP_RUNTIME_PROVIDER=embedded-playwright`.
|
|
42
42
|
|
|
43
43
|
## Publicacao
|
|
44
44
|
|
|
@@ -108,7 +108,7 @@ otto-bridge run --executor clawd-cursor --clawd-url http://127.0.0.1:3847
|
|
|
108
108
|
|
|
109
109
|
### WhatsApp Web em background
|
|
110
110
|
|
|
111
|
-
Fluxo recomendado no `0.7.
|
|
111
|
+
Fluxo recomendado no `0.7.4`:
|
|
112
112
|
|
|
113
113
|
```bash
|
|
114
114
|
otto-bridge extensions --install whatsappweb
|
|
@@ -118,17 +118,17 @@ otto-bridge extensions --status whatsappweb
|
|
|
118
118
|
|
|
119
119
|
O setup agora abre o login do WhatsApp Web no helper/background browser do proprio bridge. Depois do QR code, o Otto usa a sessao local em background, sem depender de aba visivel no Safari.
|
|
120
120
|
|
|
121
|
-
Contrato do `0.7.
|
|
121
|
+
Contrato do `0.7.4`:
|
|
122
122
|
|
|
123
123
|
- `otto-bridge extensions --setup whatsappweb`: autentica a sessao uma vez
|
|
124
124
|
- `otto-bridge run`: mantem o browser persistente do WhatsApp vivo em background enquanto o runtime estiver ativo, sem depender de uma aba aberta no Safari
|
|
125
125
|
- ao parar o `otto-bridge run`: o browser em background e desligado, mas a sessao local fica lembrada para o proximo boot
|
|
126
126
|
|
|
127
|
-
## Handoff rapido do 0.7.
|
|
127
|
+
## Handoff rapido do 0.7.4
|
|
128
128
|
|
|
129
129
|
Ja fechado no codigo:
|
|
130
130
|
|
|
131
|
-
- provider `macos-helper` dockless no macOS
|
|
131
|
+
- provider `macos-helper` dockless no macOS como runtime padrao do WhatsApp
|
|
132
132
|
- user-agent do helper ajustado para evitar bloqueio do WhatsApp por detecao de Safari/WebKit
|
|
133
133
|
- resultado final dos `device_job` agora e persistido como contexto mais forte para o proximo turno do Otto
|
|
134
134
|
- prompt bridge-aware no chat normal para ajudar o Otto a responder com base no que realmente aconteceu no device
|
|
@@ -263,9 +263,9 @@ export class MacOSWhatsAppHelperRuntime {
|
|
|
263
263
|
|
|
264
264
|
if (searchBox instanceof HTMLInputElement || searchBox instanceof HTMLTextAreaElement) {
|
|
265
265
|
searchBox.value = "";
|
|
266
|
-
searchBox.dispatchEvent(new
|
|
266
|
+
searchBox.dispatchEvent(new Event("input", { bubbles: true }));
|
|
267
267
|
searchBox.value = contact;
|
|
268
|
-
searchBox.dispatchEvent(new
|
|
268
|
+
searchBox.dispatchEvent(new Event("input", { bubbles: true }));
|
|
269
269
|
} else {
|
|
270
270
|
const selection = window.getSelection();
|
|
271
271
|
const range = document.createRange();
|
|
@@ -278,7 +278,7 @@ export class MacOSWhatsAppHelperRuntime {
|
|
|
278
278
|
if ((searchBox.innerText || "").trim() !== contact.trim()) {
|
|
279
279
|
searchBox.textContent = contact;
|
|
280
280
|
}
|
|
281
|
-
searchBox.dispatchEvent(new
|
|
281
|
+
searchBox.dispatchEvent(new Event("input", { bubbles: true }));
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
return { ok: true };
|
|
@@ -401,9 +401,9 @@ export class MacOSWhatsAppHelperRuntime {
|
|
|
401
401
|
composer.focus();
|
|
402
402
|
if (composer instanceof HTMLInputElement || composer instanceof HTMLTextAreaElement) {
|
|
403
403
|
composer.value = "";
|
|
404
|
-
composer.dispatchEvent(new
|
|
404
|
+
composer.dispatchEvent(new Event("input", { bubbles: true }));
|
|
405
405
|
composer.value = value;
|
|
406
|
-
composer.dispatchEvent(new
|
|
406
|
+
composer.dispatchEvent(new Event("input", { bubbles: true }));
|
|
407
407
|
} else {
|
|
408
408
|
const selection = window.getSelection();
|
|
409
409
|
const range = document.createRange();
|
|
@@ -416,7 +416,7 @@ export class MacOSWhatsAppHelperRuntime {
|
|
|
416
416
|
if ((composer.innerText || "").trim() !== value.trim()) {
|
|
417
417
|
composer.textContent = value;
|
|
418
418
|
}
|
|
419
|
-
composer.dispatchEvent(new
|
|
419
|
+
composer.dispatchEvent(new Event("input", { bubbles: true }));
|
|
420
420
|
}
|
|
421
421
|
composer.click();
|
|
422
422
|
|
|
@@ -24,6 +24,10 @@ final class OttoWhatsAppHelper: NSObject, WKNavigationDelegate {
|
|
|
24
24
|
app.setActivationPolicy(.accessory)
|
|
25
25
|
window.title = "Otto WhatsApp Helper"
|
|
26
26
|
window.isReleasedWhenClosed = false
|
|
27
|
+
window.collectionBehavior = [.canJoinAllSpaces, .stationary, .ignoresCycle]
|
|
28
|
+
window.level = .normal
|
|
29
|
+
window.hasShadow = false
|
|
30
|
+
window.hidesOnDeactivate = false
|
|
27
31
|
window.contentView = webView
|
|
28
32
|
webView.navigationDelegate = self
|
|
29
33
|
webView.customUserAgent = Self.chromeUserAgent
|
|
@@ -116,6 +120,8 @@ final class OttoWhatsAppHelper: NSObject, WKNavigationDelegate {
|
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
private func showSetup() {
|
|
123
|
+
window.alphaValue = 1
|
|
124
|
+
window.ignoresMouseEvents = false
|
|
119
125
|
if let screen = NSScreen.main {
|
|
120
126
|
let frame = screen.visibleFrame
|
|
121
127
|
let originX = frame.origin.x + max(0, (frame.width - 1320) / 2)
|
|
@@ -129,7 +135,9 @@ final class OttoWhatsAppHelper: NSObject, WKNavigationDelegate {
|
|
|
129
135
|
}
|
|
130
136
|
|
|
131
137
|
private func hideBackground() {
|
|
132
|
-
window.
|
|
138
|
+
window.ignoresMouseEvents = true
|
|
139
|
+
window.alphaValue = 0
|
|
140
|
+
window.setFrame(NSRect(x: -2200, y: 80, width: 1320, height: 920), display: false)
|
|
133
141
|
window.orderFrontRegardless()
|
|
134
142
|
}
|
|
135
143
|
|
package/dist/types.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const BRIDGE_CONFIG_VERSION = 1;
|
|
2
|
-
export const BRIDGE_VERSION = "0.7.
|
|
2
|
+
export const BRIDGE_VERSION = "0.7.4";
|
|
3
3
|
export const BRIDGE_PACKAGE_NAME = "@leg3ndy/otto-bridge";
|
|
4
4
|
export const DEFAULT_API_BASE_URL = "http://localhost:8000";
|
|
5
5
|
export const DEFAULT_POLL_INTERVAL_MS = 3000;
|
|
@@ -90,12 +90,7 @@ export class WhatsAppBackgroundBrowser {
|
|
|
90
90
|
const provider = getConfiguredWhatsAppRuntimeProvider();
|
|
91
91
|
if (provider.kind === "macos-helper") {
|
|
92
92
|
const helperAvailability = await checkMacOSWhatsAppHelperAvailability();
|
|
93
|
-
|
|
94
|
-
return helperAvailability;
|
|
95
|
-
}
|
|
96
|
-
if (provider.source === "env") {
|
|
97
|
-
return helperAvailability;
|
|
98
|
-
}
|
|
93
|
+
return helperAvailability;
|
|
99
94
|
}
|
|
100
95
|
try {
|
|
101
96
|
await loadEmbeddedPlaywrightModule();
|
|
@@ -113,32 +108,29 @@ export class WhatsAppBackgroundBrowser {
|
|
|
113
108
|
return;
|
|
114
109
|
}
|
|
115
110
|
const provider = getConfiguredWhatsAppRuntimeProvider();
|
|
116
|
-
if (provider.kind === "macos-helper"
|
|
111
|
+
if (provider.kind === "macos-helper") {
|
|
112
|
+
if (process.platform !== "darwin") {
|
|
113
|
+
throw new Error("O helper nativo do WhatsApp esta disponivel apenas no macOS.");
|
|
114
|
+
}
|
|
117
115
|
const helperAvailability = await checkMacOSWhatsAppHelperAvailability();
|
|
118
|
-
if (helperAvailability.ok) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
await this.helperRuntime.showSetup();
|
|
127
|
-
}
|
|
128
|
-
this.activeProviderKind = "macos-helper";
|
|
129
|
-
return;
|
|
116
|
+
if (!helperAvailability.ok) {
|
|
117
|
+
throw new Error(helperAvailability.reason || "O helper macOS do WhatsApp nao esta disponivel nesta maquina.");
|
|
118
|
+
}
|
|
119
|
+
this.helperRuntime = new MacOSWhatsAppHelperRuntime({ background: this.options.background });
|
|
120
|
+
try {
|
|
121
|
+
await this.helperRuntime.start();
|
|
122
|
+
if (this.options.background) {
|
|
123
|
+
await this.helperRuntime.hideBackground();
|
|
130
124
|
}
|
|
131
|
-
|
|
132
|
-
this.helperRuntime
|
|
133
|
-
if (provider.source === "env") {
|
|
134
|
-
throw error;
|
|
135
|
-
}
|
|
136
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
137
|
-
console.warn(`[otto-bridge] whatsapp runtime fallback para embedded-playwright: ${detail}`);
|
|
125
|
+
else {
|
|
126
|
+
await this.helperRuntime.showSetup();
|
|
138
127
|
}
|
|
128
|
+
this.activeProviderKind = "macos-helper";
|
|
129
|
+
return;
|
|
139
130
|
}
|
|
140
|
-
|
|
141
|
-
|
|
131
|
+
catch (error) {
|
|
132
|
+
this.helperRuntime = null;
|
|
133
|
+
throw error;
|
|
142
134
|
}
|
|
143
135
|
}
|
|
144
136
|
const playwright = await loadEmbeddedPlaywrightModule();
|
|
@@ -283,6 +275,7 @@ export class WhatsAppBackgroundBrowser {
|
|
|
283
275
|
return candidates[0]?.pid || null;
|
|
284
276
|
}
|
|
285
277
|
async getSessionState() {
|
|
278
|
+
await this.start();
|
|
286
279
|
if (this.helperRuntime) {
|
|
287
280
|
return await this.helperRuntime.getSessionState();
|
|
288
281
|
}
|
|
@@ -330,6 +323,7 @@ export class WhatsAppBackgroundBrowser {
|
|
|
330
323
|
};
|
|
331
324
|
}
|
|
332
325
|
async ensureReady() {
|
|
326
|
+
await this.start();
|
|
333
327
|
if (this.helperRuntime) {
|
|
334
328
|
return await this.helperRuntime.ensureReady();
|
|
335
329
|
}
|
|
@@ -343,6 +337,7 @@ export class WhatsAppBackgroundBrowser {
|
|
|
343
337
|
throw new Error("Nao consegui confirmar uma sessao pronta do WhatsApp Web neste browser em background.");
|
|
344
338
|
}
|
|
345
339
|
async waitForLogin(timeoutMs = DEFAULT_SETUP_TIMEOUT_MS) {
|
|
340
|
+
await this.start();
|
|
346
341
|
if (this.helperRuntime) {
|
|
347
342
|
return await this.helperRuntime.waitForLogin(timeoutMs);
|
|
348
343
|
}
|
|
@@ -358,6 +353,7 @@ export class WhatsAppBackgroundBrowser {
|
|
|
358
353
|
return lastState || await this.getSessionState();
|
|
359
354
|
}
|
|
360
355
|
async waitForStableSessionState(options) {
|
|
356
|
+
await this.start();
|
|
361
357
|
if (this.helperRuntime) {
|
|
362
358
|
return await this.helperRuntime.waitForStableSessionState(options);
|
|
363
359
|
}
|