@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.2.tgz
36
+ npm install -g ./leg3ndy-otto-bridge-0.7.4.tgz
37
37
  ```
38
38
 
39
- No `0.7.2`, `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.
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.2` passa a preferir o provider `macos-helper`, um helper `WKWebView` sem Dock para o WhatsApp Web. O helper agora sobe com user-agent de Chrome moderno para evitar o bloqueio do WhatsApp ao detectar Safari/WebKit. Se voce quiser forcar o runtime antigo com Chromium/Playwright, use `OTTO_BRIDGE_WHATSAPP_RUNTIME_PROVIDER=embedded-playwright`.
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.2`:
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.2`:
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.2
127
+ ## Handoff rapido do 0.7.4
128
128
 
129
129
  Ja fechado no codigo:
130
130
 
131
- - provider `macos-helper` dockless no macOS com fallback para `embedded-playwright`
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 InputEvent("input", { bubbles: true, inputType: "deleteContentBackward", data: null }));
266
+ searchBox.dispatchEvent(new Event("input", { bubbles: true }));
267
267
  searchBox.value = contact;
268
- searchBox.dispatchEvent(new InputEvent("input", { bubbles: true, inputType: "insertText", data: contact }));
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 InputEvent("input", { bubbles: true, inputType: "insertText", data: contact }));
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 InputEvent("input", { bubbles: true, inputType: "deleteContentBackward", data: null }));
404
+ composer.dispatchEvent(new Event("input", { bubbles: true }));
405
405
  composer.value = value;
406
- composer.dispatchEvent(new InputEvent("input", { bubbles: true, inputType: "insertText", data: value }));
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 InputEvent("input", { bubbles: true, inputType: "insertText", data: value }));
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.setFrame(NSRect(x: -2200, y: 80, width: 1320, height: 920), display: true)
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";
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
- if (helperAvailability.ok) {
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" && process.platform === "darwin") {
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
- try {
120
- this.helperRuntime = new MacOSWhatsAppHelperRuntime({ background: this.options.background });
121
- await this.helperRuntime.start();
122
- if (this.options.background) {
123
- await this.helperRuntime.hideBackground();
124
- }
125
- else {
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
- catch (error) {
132
- this.helperRuntime = null;
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
- else if (provider.source === "env") {
141
- throw new Error(helperAvailability.reason || "O helper macOS do WhatsApp nao esta disponivel nesta maquina.");
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leg3ndy/otto-bridge",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Local companion for Otto Bridge device pairing and WebSocket runtime.",