@leg3ndy/otto-bridge 1.0.9 → 1.0.11

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
@@ -15,7 +15,7 @@ Para o estado atual da arquitetura, capacidades entregues, limitacoes e roadmap
15
15
 
16
16
  Para o corte de arquitetura do `0.9.0`, veja [`leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_0_9_0_RELEASE.md`](../leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_0_9_0_RELEASE.md).
17
17
 
18
- Para a release atual `1.0.9`, com composer multiline no console TTY e quebra de linha dentro da moldura, veja [`leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_0_9_PATCH.md`](../leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_0_9_PATCH.md).
18
+ Para a release atual `1.0.11`, com redraw do composer TTY endurecido para terminais reais, cursor alinhado ao placeholder e multiline sem abrir caixas duplicadas, veja [`leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_0_11_PATCH.md`](../leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_0_11_PATCH.md).
19
19
 
20
20
  ## Distribuicao
21
21
 
@@ -38,14 +38,14 @@ Enquanto o pacote nao estiver publicado, voce pode gerar um tarball local:
38
38
 
39
39
  ```bash
40
40
  npm pack
41
- npm install -g ./leg3ndy-otto-bridge-1.0.9.tgz
41
+ npm install -g ./leg3ndy-otto-bridge-1.0.11.tgz
42
42
  ```
43
43
 
44
- Na linha `1.0.9`, `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.
44
+ Na linha `1.0.11`, `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.
45
45
 
46
- No macOS, a linha `1.0.9` 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`.
46
+ No macOS, a linha `1.0.11` 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`.
47
47
 
48
- No nivel arquitetural, o `0.9.0` marcou a mudanca de papel do bridge: ele publica tools e resultados estruturados para o Otto, em vez de injetar resposta pronta como caminho principal do chat. O `1.0.0` oficializou isso como runtime agentico; o `1.0.9` preserva esse fluxo, mantem o input-box TTY estavel, adiciona composer multiline e melhora as views de status/extensoes e o refresh ao sair do `Terminal`.
48
+ No nivel arquitetural, o `0.9.0` marcou a mudanca de papel do bridge: ele publica tools e resultados estruturados para o Otto, em vez de injetar resposta pronta como caminho principal do chat. O `1.0.0` oficializou isso como runtime agentico; o `1.0.11` preserva esse fluxo, endurece o redraw do input-box TTY para terminais mais temperamentais, mantem o composer multiline e melhora as views de status/extensoes e o refresh ao sair do `Terminal`.
49
49
 
50
50
  ## Publicacao
51
51
 
@@ -157,7 +157,7 @@ Esse comando abre um shell local interativo para instalar extensoes, rodar coman
157
157
 
158
158
  ### WhatsApp Web em background
159
159
 
160
- Fluxo recomendado na linha `1.0.9`:
160
+ Fluxo recomendado na linha `1.0.11`:
161
161
 
162
162
  ```bash
163
163
  otto-bridge extensions --install whatsappweb
@@ -167,13 +167,13 @@ otto-bridge extensions --status whatsappweb
167
167
 
168
168
  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.
169
169
 
170
- Contrato da linha `1.0.9`:
170
+ Contrato da linha `1.0.11`:
171
171
 
172
172
  - `otto-bridge extensions --setup whatsappweb`: autentica a sessao uma vez
173
173
  - `otto-bridge`: mantem o browser persistente do WhatsApp vivo em background enquanto o runtime do hub estiver ativo, sem depender de uma aba aberta no Safari
174
174
  - ao fechar o `otto-bridge`: o browser em background e desligado, mas a sessao local fica lembrada para o proximo boot
175
175
 
176
- ## Handoff rapido da linha 1.0.9
176
+ ## Handoff rapido da linha 1.0.11
177
177
 
178
178
  Ja fechado no codigo:
179
179
 
@@ -53,6 +53,8 @@ const MAX_RENDERED_FILE_CHARS = 6_000;
53
53
  const MAX_RENDERED_FILE_CHARS_COMPACT = 1_400;
54
54
  const CONSOLE_PLACEHOLDER = "Peça algo ao Otto";
55
55
  const CONSOLE_COMMAND_HINT = "/help, /model [fast|thinking], /status, /clear, /exit";
56
+ const CONSOLE_COMPOSER_PROMPT_WIDTH = 2;
57
+ const CONSOLE_COMPOSER_CURSOR_COLUMN = 4;
56
58
  class CliRuntimeSession {
57
59
  config;
58
60
  runtime = null;
@@ -688,6 +690,12 @@ function renderConsolePromptContentLine(text, width, tone) {
688
690
  : style(clipped, ANSI.slateItalic, enabled);
689
691
  return `${border} ${body} ${border}`;
690
692
  }
693
+ function enableTerminalEnhancedKeys() {
694
+ output.write("\u001b[>4;2m");
695
+ }
696
+ function disableTerminalEnhancedKeys() {
697
+ output.write("\u001b[>4m");
698
+ }
691
699
  function sliceByWidth(text, width) {
692
700
  if (width <= 0) {
693
701
  return [""];
@@ -704,8 +712,7 @@ function sliceByWidth(text, width) {
704
712
  return parts.length ? parts : [""];
705
713
  }
706
714
  export function buildConsoleComposerLayout(value, innerWidth) {
707
- const promptWidth = 2;
708
- const lineContentWidth = Math.max(1, innerWidth - promptWidth);
715
+ const lineContentWidth = Math.max(1, innerWidth - CONSOLE_COMPOSER_PROMPT_WIDTH);
709
716
  if (!value) {
710
717
  return {
711
718
  lines: [CONSOLE_PLACEHOLDER],
@@ -724,7 +731,7 @@ export function buildConsoleComposerLayout(value, innerWidth) {
724
731
  const needsSoftWrapCursorRow = !trailingNewline
725
732
  && lastLogicalLine.length > 0
726
733
  && lastLogicalLine.length % lineContentWidth === 0;
727
- if (trailingNewline || needsSoftWrapCursorRow) {
734
+ if (needsSoftWrapCursorRow) {
728
735
  lines.push("");
729
736
  }
730
737
  const cursorLineIndex = trailingNewline
@@ -766,9 +773,10 @@ function renderConsoleComposerLines(value, innerWidth, enabled) {
766
773
  cursorColumn: layout.cursorColumn,
767
774
  };
768
775
  }
769
- function tryConsumeControlSequence(buffer) {
776
+ export function tryConsumeControlSequence(buffer) {
770
777
  const knownNewlineSequences = [
771
778
  "\u001b[13;2u",
779
+ "\u001b[13;2~",
772
780
  "\u001b[27;2;13~",
773
781
  "\u001b[1;2M",
774
782
  "\u001b\r",
@@ -822,11 +830,13 @@ async function askConsoleInput(rl) {
822
830
  const availableWidth = Number(output.columns || 96);
823
831
  const innerWidth = Math.max(42, Math.min(availableWidth - 8, 116));
824
832
  let renderedOnce = false;
833
+ let lastRenderedLineCount = 0;
834
+ let lastCursorLineIndex = 0;
825
835
  let value = "";
826
836
  let pendingControlBuffer = "";
827
- let previousCursorRowsFromTop = 0;
828
837
  const cleanup = () => {
829
838
  input.removeListener("data", onData);
839
+ disableTerminalEnhancedKeys();
830
840
  input.setRawMode(false);
831
841
  input.pause();
832
842
  rl.resume();
@@ -834,8 +844,8 @@ async function askConsoleInput(rl) {
834
844
  const render = () => {
835
845
  const composer = renderConsoleComposerLines(value, innerWidth, enabled);
836
846
  if (renderedOnce) {
847
+ moveCursor(output, 0, -(1 + lastCursorLineIndex));
837
848
  cursorTo(output, 0);
838
- moveCursor(output, 0, -previousCursorRowsFromTop);
839
849
  }
840
850
  else {
841
851
  renderedOnce = true;
@@ -845,17 +855,21 @@ async function askConsoleInput(rl) {
845
855
  const bottom = renderPromptFrameLine(innerWidth + 2, "└", "┘");
846
856
  const content = composer.renderedLines.map((line) => `${border} ${line} ${border}`).join("\n");
847
857
  output.write("\u001b[J");
848
- output.write(`${top}\n${content}\n${bottom}\n`);
849
- cursorTo(output, 0);
850
- previousCursorRowsFromTop = 1 + composer.cursorLineIndex;
851
- moveCursor(output, 0, -previousCursorRowsFromTop);
852
- cursorTo(output, 4 + composer.cursorColumn);
858
+ output.write(`${top}\n${content}\n${bottom}`);
859
+ moveCursor(output, 0, -(composer.renderedLines.length - composer.cursorLineIndex));
860
+ cursorTo(output, CONSOLE_COMPOSER_CURSOR_COLUMN + composer.cursorColumn);
861
+ lastRenderedLineCount = composer.renderedLines.length;
862
+ lastCursorLineIndex = composer.cursorLineIndex;
853
863
  };
854
864
  const insertNewline = () => {
855
865
  value = `${value}\n`;
856
866
  render();
857
867
  };
858
868
  const submitPrompt = () => {
869
+ if (renderedOnce) {
870
+ moveCursor(output, 0, lastRenderedLineCount - lastCursorLineIndex + 1);
871
+ cursorTo(output, 0);
872
+ }
859
873
  cleanup();
860
874
  output.write("\n");
861
875
  resolve(normalizeText(value));
@@ -910,6 +924,7 @@ async function askConsoleInput(rl) {
910
924
  }
911
925
  };
912
926
  render();
927
+ enableTerminalEnhancedKeys();
913
928
  input.on("data", onData);
914
929
  });
915
930
  }
package/dist/types.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export const BRIDGE_CONFIG_VERSION = 1;
2
- export const BRIDGE_VERSION = "1.0.9";
2
+ export const BRIDGE_VERSION = "1.0.11";
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leg3ndy/otto-bridge",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Local companion for Otto Bridge device pairing and WebSocket runtime.",
@@ -24,7 +24,7 @@ if (!existsSync(mainPath)) {
24
24
  process.exit(0);
25
25
  }
26
26
 
27
- console.log("\n[otto-bridge] Welcome to OTTOAI 1.0.9");
27
+ console.log("\n[otto-bridge] Welcome to OTTOAI 1.0.11");
28
28
  console.log("[otto-bridge] Vamos iniciar o setup interativo do bridge.\n");
29
29
 
30
30
  const result = spawnSync(process.execPath, [mainPath, "setup", "--postinstall"], {