@leg3ndy/otto-bridge 1.0.7 → 1.0.8

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.7`, com hotfix do input-box TTY do console, veja [`leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_0_7_PATCH.md`](../leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_0_7_PATCH.md).
18
+ Para a release atual `1.0.8`, com cards visuais para status/extensoes e refresh inteligente ao voltar do Terminal, veja [`leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_0_8_PATCH.md`](../leg3ndy-ai-backend/docs/otto-bridge/releases/OTTO_BRIDGE_1_0_8_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.7.tgz
41
+ npm install -g ./leg3ndy-otto-bridge-1.0.8.tgz
42
42
  ```
43
43
 
44
- Na linha `1.0.7`, `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.8`, `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.7` 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.8` 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.7` preserva esse fluxo e corrige o freeze do input-box TTY introduzido no refinamento visual do console.
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.8` preserva esse fluxo, mantem o input-box TTY estavel 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.7`:
160
+ Fluxo recomendado na linha `1.0.8`:
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.7`:
170
+ Contrato da linha `1.0.8`:
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.7
176
+ ## Handoff rapido da linha 1.0.8
177
177
 
178
178
  Ja fechado no codigo:
179
179
 
@@ -1,9 +1,10 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { spawn } from "node:child_process";
3
+ import { readFile } from "node:fs/promises";
3
4
  import { createInterface } from "node:readline/promises";
4
5
  import { cursorTo, moveCursor, } from "node:readline";
5
6
  import process, { stdin as input, stdout as output } from "node:process";
6
- import { defaultDeviceName, getBridgeConfigPath, loadBridgeConfig, resolveApiBaseUrl, resolveExecutorConfig, } from "./config.js";
7
+ import { defaultDeviceName, getBridgeConfigPath, loadBridgeConfig, normalizeInstalledExtensions, resolveApiBaseUrl, resolveExecutorConfig, } from "./config.js";
7
8
  import { streamDeviceCliChat, } from "./chat_cli_client.js";
8
9
  import { formatManagedBridgeExtensionStatus, isManagedBridgeExtensionSlug, loadManagedBridgeExtensionState, } from "./extensions.js";
9
10
  import { pairDevice } from "./pairing.js";
@@ -308,6 +309,47 @@ export function resolveCliModelMode(value) {
308
309
  function delay(ms) {
309
310
  return new Promise((resolve) => setTimeout(resolve, ms));
310
311
  }
312
+ async function resolveInstalledBridgeVersion() {
313
+ try {
314
+ const raw = await readFile(new URL("../package.json", import.meta.url), "utf8");
315
+ const parsed = JSON.parse(raw);
316
+ return normalizeText(parsed.version) || BRIDGE_VERSION;
317
+ }
318
+ catch {
319
+ return BRIDGE_VERSION;
320
+ }
321
+ }
322
+ async function captureBridgeRuntimeSnapshot(config) {
323
+ const managedExtensionState = await Promise.all(normalizeInstalledExtensions(config?.installedExtensions || [])
324
+ .filter(isManagedBridgeExtensionSlug)
325
+ .sort((left, right) => left.localeCompare(right))
326
+ .map(async (slug) => {
327
+ const state = await loadManagedBridgeExtensionState(slug);
328
+ return {
329
+ slug,
330
+ status: normalizeText(state?.status),
331
+ lastSetupAt: normalizeText(state?.lastSetupAt),
332
+ notes: normalizeText(state?.notes),
333
+ };
334
+ }));
335
+ return {
336
+ bridgeVersion: await resolveInstalledBridgeVersion(),
337
+ configFingerprint: JSON.stringify(config || null),
338
+ extensionStateFingerprint: JSON.stringify(managedExtensionState),
339
+ };
340
+ }
341
+ export function diffBridgeRuntimeSnapshots(before, after) {
342
+ const versionChanged = before.bridgeVersion !== after.bridgeVersion;
343
+ const configChanged = before.configFingerprint !== after.configFingerprint;
344
+ const extensionStateChanged = before.extensionStateFingerprint !== after.extensionStateFingerprint;
345
+ return {
346
+ versionChanged,
347
+ configChanged,
348
+ extensionStateChanged,
349
+ requiresCliRestart: versionChanged,
350
+ requiresRuntimeRefresh: configChanged || extensionStateChanged,
351
+ };
352
+ }
311
353
  async function createPromptInterface() {
312
354
  const rl = createInterface({
313
355
  input,
@@ -539,6 +581,72 @@ function buildBridgeReleaseCard(notice) {
539
581
  { text: `Rode: ${notice.updateCommand || "otto-bridge update"}`, tone: "primary" },
540
582
  ];
541
583
  }
584
+ function buildStatusCard(config, runtimeSession) {
585
+ const releaseNotice = runtimeSession.getReleaseNotice();
586
+ return [
587
+ { text: "Bridge Status", tone: "title" },
588
+ { text: "", tone: "muted" },
589
+ { text: `device: ${config.deviceName}`, tone: "primary" },
590
+ { text: `device id: ${config.deviceId}`, tone: "primary" },
591
+ { text: `api: ${config.apiBaseUrl}`, tone: "primary" },
592
+ { text: `executor: ${config.executor.type}`, tone: "primary" },
593
+ { text: `approval: ${config.approvalMode}`, tone: "primary" },
594
+ { text: `runtime: ${runtimeSession.getStatusLabel()}`, tone: "primary" },
595
+ ...(runtimeSession.getStatusDetail()
596
+ ? [{ text: `runtime note: ${runtimeSession.getStatusDetail()}`, tone: "muted" }]
597
+ : []),
598
+ ...(releaseNotice
599
+ ? [
600
+ { text: "", tone: "muted" },
601
+ {
602
+ text: `bridge update: ${releaseNotice.kind === "required" ? "required" : "available"}`,
603
+ tone: releaseNotice.kind === "required" ? "warning" : "primary",
604
+ },
605
+ ...(releaseNotice.currentVersion
606
+ ? [{ text: `current version: ${releaseNotice.currentVersion}`, tone: "primary" }]
607
+ : []),
608
+ ...(releaseNotice.latestVersion
609
+ ? [{ text: `latest version: ${releaseNotice.latestVersion}`, tone: "primary" }]
610
+ : []),
611
+ ...(releaseNotice.minSupportedVersion
612
+ ? [{ text: `min supported: ${releaseNotice.minSupportedVersion}`, tone: "primary" }]
613
+ : []),
614
+ { text: `update command: ${releaseNotice.updateCommand || "otto-bridge update"}`, tone: "muted" },
615
+ ]
616
+ : []),
617
+ { text: "", tone: "muted" },
618
+ { text: `config: ${getBridgeConfigPath()}`, tone: "muted" },
619
+ ];
620
+ }
621
+ async function buildExtensionsCard(config) {
622
+ const lines = [
623
+ { text: "Extensões", tone: "title" },
624
+ { text: "", tone: "muted" },
625
+ ];
626
+ if (!config.installedExtensions.length) {
627
+ lines.push({ text: "Nenhuma extensão instalada neste bridge.", tone: "muted" });
628
+ return lines;
629
+ }
630
+ for (const extension of config.installedExtensions) {
631
+ if (!isManagedBridgeExtensionSlug(extension)) {
632
+ lines.push({ text: `• ${extension}`, tone: "primary" });
633
+ lines.push({ text: "Extensão local sem status gerenciado.", tone: "muted" });
634
+ lines.push({ text: "", tone: "muted" });
635
+ continue;
636
+ }
637
+ const state = await loadManagedBridgeExtensionState(extension);
638
+ const status = state ? formatManagedBridgeExtensionStatus(state.status) : "sem estado salvo";
639
+ lines.push({ text: `• ${extension}: ${status}`, tone: "primary" });
640
+ if (state?.notes) {
641
+ lines.push({ text: truncate(state.notes, 160), tone: "muted" });
642
+ }
643
+ lines.push({ text: "", tone: "muted" });
644
+ }
645
+ while (lines.length > 2 && !normalizeText(lines[lines.length - 1]?.text)) {
646
+ lines.pop();
647
+ }
648
+ return lines;
649
+ }
542
650
  function printHubScreen(runtimeSession, modelMode) {
543
651
  clearScreen();
544
652
  console.log(renderBanner());
@@ -561,6 +669,8 @@ function printConsoleScreen(runtimeSession, modelMode) {
561
669
  console.log(renderInfoCard(buildBridgeReleaseCard(releaseNotice)));
562
670
  }
563
671
  console.log("");
672
+ printSoft(`Comandos: ${CONSOLE_COMMAND_HINT}`);
673
+ console.log("");
564
674
  }
565
675
  function renderPromptFrameLine(width, edgeLeft, edgeRight) {
566
676
  return style(`${edgeLeft}${"─".repeat(width)}${edgeRight}`, ANSI.brandBlue, supportsAnsi());
@@ -580,8 +690,6 @@ function renderConsolePromptContentLine(text, width, tone) {
580
690
  }
581
691
  async function askConsoleInput(rl) {
582
692
  if (!supportsAnsi() || typeof input.setRawMode !== "function" || !input.isTTY) {
583
- printSoft(`Comandos: ${CONSOLE_COMMAND_HINT}`);
584
- console.log("");
585
693
  return normalizeText(await question(rl, "> "));
586
694
  }
587
695
  rl.pause();
@@ -591,7 +699,7 @@ async function askConsoleInput(rl) {
591
699
  const enabled = supportsAnsi();
592
700
  const availableWidth = Number(output.columns || 96);
593
701
  const innerWidth = Math.max(42, Math.min(availableWidth - 8, 116));
594
- const sectionTopOffsetFromInputLine = 3;
702
+ const sectionTopOffsetFromInputLine = 1;
595
703
  let renderedOnce = false;
596
704
  let value = "";
597
705
  const cleanup = () => {
@@ -622,13 +730,12 @@ async function askConsoleInput(rl) {
622
730
  else {
623
731
  renderedOnce = true;
624
732
  }
625
- const commands = style(`Comandos: ${CONSOLE_COMMAND_HINT}`, ANSI.slateItalic, enabled);
626
733
  const top = renderPromptFrameLine(innerWidth + 2, "┌", "┐");
627
734
  const border = style("│", ANSI.brandBlue, enabled);
628
735
  const middle = `${border} ${renderInputContent()} ${border}`;
629
736
  const bottom = renderPromptFrameLine(innerWidth + 2, "└", "┘");
630
737
  output.write("\u001b[J");
631
- output.write(`${commands}\n\n${top}\n${middle}\n${bottom}\n`);
738
+ output.write(`${top}\n${middle}\n${bottom}\n`);
632
739
  cursorTo(output, 0);
633
740
  moveCursor(output, 0, -2);
634
741
  const visibleValueLength = Math.min(value.length, Math.max(0, innerWidth - 2));
@@ -838,6 +945,30 @@ export async function runTerminalShell(options) {
838
945
  });
839
946
  });
840
947
  }
948
+ async function showRuntimeRefreshProgress(options) {
949
+ clearScreen();
950
+ console.log(renderBanner());
951
+ console.log("");
952
+ console.log(renderInfoCard([
953
+ { text: options.title, tone: "title" },
954
+ { text: "", tone: "muted" },
955
+ { text: options.detail, tone: "muted" },
956
+ ]));
957
+ console.log("");
958
+ const enabled = supportsAnsi();
959
+ const width = 28;
960
+ const steps = Math.max(8, options.steps || width);
961
+ const delayMs = Math.max(20, options.delayMs || 45);
962
+ for (let step = 0; step <= steps; step += 1) {
963
+ const filled = Math.round((step / steps) * width);
964
+ const empty = Math.max(0, width - filled);
965
+ const bar = `${"█".repeat(filled)}${"░".repeat(empty)}`;
966
+ const line = `[${bar}] ${Math.round((step / steps) * 100)}%`;
967
+ output.write(`\r${style(line, ANSI.brandBlue, enabled)}`);
968
+ await delay(delayMs);
969
+ }
970
+ output.write("\n\n");
971
+ }
841
972
  function buildConversationSummary(summary, job) {
842
973
  const rendered = renderStructuredOutcome(job, { compact: true });
843
974
  if (!rendered) {
@@ -849,23 +980,8 @@ function buildConversationSummary(summary, job) {
849
980
  return `${summary}\n${rendered}`.slice(0, 4_000).trim();
850
981
  }
851
982
  async function printExtensionsOverview(config) {
852
- printSection("Extensions");
853
- if (!config.installedExtensions.length) {
854
- printMuted("Nenhuma extensão instalada neste bridge.");
855
- return;
856
- }
857
- for (const extension of config.installedExtensions) {
858
- if (!isManagedBridgeExtensionSlug(extension)) {
859
- console.log(`- ${extension}`);
860
- continue;
861
- }
862
- const state = await loadManagedBridgeExtensionState(extension);
863
- const status = state ? formatManagedBridgeExtensionStatus(state.status) : "sem estado salvo";
864
- console.log(`- ${extension}: ${status}`);
865
- if (state?.notes) {
866
- printMuted(` ${truncate(state.notes, 140)}`);
867
- }
868
- }
983
+ printSection("Extensões");
984
+ console.log(renderInfoCard(await buildExtensionsCard(config)));
869
985
  }
870
986
  async function runSetupWizard(rl, options) {
871
987
  printSection(options?.postinstall ? "Setup Inicial" : "Pairing Setup");
@@ -1111,7 +1227,7 @@ async function runOttoConsole(rl, config, runtimeSession, options) {
1111
1227
  }
1112
1228
  async function printStatusView(rl, config, runtimeSession) {
1113
1229
  printSection("Bridge Status");
1114
- renderStatusOverview(config, runtimeSession).forEach((line) => console.log(line));
1230
+ console.log(renderInfoCard(buildStatusCard(config, runtimeSession)));
1115
1231
  await pauseForEnter(rl);
1116
1232
  }
1117
1233
  async function printHelpView(rl) {
@@ -1152,7 +1268,7 @@ async function pickHomeChoice(rl, paired) {
1152
1268
  `${style("2.", ANSI.brandBlue, supportsAnsi())} Terminal`,
1153
1269
  `${style("3.", ANSI.brandBlue, supportsAnsi())} Setup / parear novamente`,
1154
1270
  `${style("4.", ANSI.brandBlue, supportsAnsi())} Status detalhado`,
1155
- `${style("5.", ANSI.brandBlue, supportsAnsi())} Extensões instaladas`,
1271
+ `${style("5.", ANSI.brandBlue, supportsAnsi())} Extensões`,
1156
1272
  `${style("6.", ANSI.brandBlue, supportsAnsi())} Ajuda`,
1157
1273
  `${style("7.", ANSI.brandBlue, supportsAnsi())} Sair`,
1158
1274
  ]
@@ -1190,6 +1306,7 @@ async function pickHomeChoice(rl, paired) {
1190
1306
  export async function launchInteractiveCli(options) {
1191
1307
  let rl = await createPromptInterface();
1192
1308
  let runtimeSession = null;
1309
+ let restartRequested = false;
1193
1310
  try {
1194
1311
  let config = await loadBridgeConfig();
1195
1312
  if (!config) {
@@ -1203,7 +1320,7 @@ export async function launchInteractiveCli(options) {
1203
1320
  await runOttoConsole(rl, config, runtimeSession);
1204
1321
  }
1205
1322
  if (!config) {
1206
- return;
1323
+ return { restartRequested: false };
1207
1324
  }
1208
1325
  }
1209
1326
  runtimeSession = runtimeSession || new CliRuntimeSession(config);
@@ -1220,18 +1337,34 @@ export async function launchInteractiveCli(options) {
1220
1337
  continue;
1221
1338
  }
1222
1339
  if (choice === "terminal") {
1340
+ const snapshotBefore = await captureBridgeRuntimeSnapshot(config);
1223
1341
  rl.close();
1224
1342
  await runTerminalShell({ fromHub: true });
1225
- rl = await createPromptInterface();
1226
1343
  const refreshedConfig = await loadBridgeConfig();
1344
+ const snapshotAfter = await captureBridgeRuntimeSnapshot(refreshedConfig);
1345
+ const runtimeDiff = diffBridgeRuntimeSnapshots(snapshotBefore, snapshotAfter);
1346
+ rl = await createPromptInterface();
1227
1347
  if (!refreshedConfig) {
1228
1348
  await runtimeSession?.stop().catch(() => undefined);
1229
1349
  runtimeSession = null;
1230
1350
  printWarning("Pairing local removido no terminal. Encerrando o hub.");
1231
1351
  break;
1232
1352
  }
1233
- if (JSON.stringify(refreshedConfig) !== JSON.stringify(config)) {
1353
+ if (runtimeDiff.requiresCliRestart) {
1354
+ config = refreshedConfig;
1355
+ restartRequested = true;
1356
+ await showRuntimeRefreshProgress({
1357
+ title: "Reiniciando Otto Bridge",
1358
+ detail: "Aguarde um minuto, o Otto Bridge está reiniciando para aplicar mudanças.",
1359
+ });
1360
+ break;
1361
+ }
1362
+ if (runtimeDiff.requiresRuntimeRefresh) {
1234
1363
  config = refreshedConfig;
1364
+ await showRuntimeRefreshProgress({
1365
+ title: "Aplicando mudanças do runtime",
1366
+ detail: "Aguarde um instante, o Otto Bridge está atualizando o runtime local para aplicar mudanças.",
1367
+ });
1235
1368
  if (runtimeSession) {
1236
1369
  await runtimeSession.replaceConfig(refreshedConfig);
1237
1370
  await runtimeSession.waitForReady();
@@ -1286,6 +1419,7 @@ export async function launchInteractiveCli(options) {
1286
1419
  await runtimeSession?.stop().catch(() => undefined);
1287
1420
  rl.close();
1288
1421
  }
1422
+ return { restartRequested };
1289
1423
  }
1290
1424
  export async function runSetupCommand(options) {
1291
1425
  const rl = await createPromptInterface();
package/dist/main.js CHANGED
@@ -140,6 +140,32 @@ Examples:
140
140
  function printVersion() {
141
141
  console.log(`${BRIDGE_PACKAGE_NAME} ${BRIDGE_VERSION}`);
142
142
  }
143
+ async function restartCurrentCliProcess() {
144
+ const command = process.platform === "win32" ? "otto-bridge.cmd" : "otto-bridge";
145
+ const fallbackEntrypoint = process.argv[1];
146
+ const spawnRestart = (binary, args) => new Promise((resolve, reject) => {
147
+ const child = spawn(binary, args, {
148
+ stdio: "inherit",
149
+ env: process.env,
150
+ });
151
+ child.once("spawn", () => {
152
+ resolve();
153
+ });
154
+ child.once("error", (error) => {
155
+ reject(error);
156
+ });
157
+ });
158
+ try {
159
+ await spawnRestart(command, []);
160
+ return;
161
+ }
162
+ catch {
163
+ if (!fallbackEntrypoint) {
164
+ throw new Error("Nao foi possivel relancar o Otto Bridge apos atualizar.");
165
+ }
166
+ }
167
+ await spawnRestart(process.execPath, [fallbackEntrypoint]);
168
+ }
143
169
  function runChildCommand(command, args) {
144
170
  return new Promise((resolve, reject) => {
145
171
  const child = spawn(command, args, {
@@ -555,7 +581,9 @@ async function main() {
555
581
  const args = parseArgs(process.argv.slice(2));
556
582
  switch (args.command) {
557
583
  case "home":
558
- await launchInteractiveCli();
584
+ if ((await launchInteractiveCli()).restartRequested) {
585
+ await restartCurrentCliProcess();
586
+ }
559
587
  return;
560
588
  case "setup":
561
589
  await runSetupCommand({
@@ -572,7 +600,9 @@ async function main() {
572
600
  await runPairCommand(args);
573
601
  return;
574
602
  case "run":
575
- await launchInteractiveCli();
603
+ if ((await launchInteractiveCli()).restartRequested) {
604
+ await restartCurrentCliProcess();
605
+ }
576
606
  return;
577
607
  case "status":
578
608
  await runStatusCommand();
package/dist/types.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export const BRIDGE_CONFIG_VERSION = 1;
2
- export const BRIDGE_VERSION = "1.0.7";
2
+ export const BRIDGE_VERSION = "1.0.8";
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.7",
3
+ "version": "1.0.8",
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.7");
27
+ console.log("\n[otto-bridge] Welcome to OTTOAI 1.0.8");
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"], {