@leg3ndy/otto-bridge 1.0.6 → 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 +8 -8
- package/dist/cli_terminal.js +164 -28
- package/dist/main.js +32 -2
- package/dist/types.js +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.mjs +1 -1
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.
|
|
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.
|
|
41
|
+
npm install -g ./leg3ndy-otto-bridge-1.0.8.tgz
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Na linha `1.0.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
176
|
+
## Handoff rapido da linha 1.0.8
|
|
177
177
|
|
|
178
178
|
Ja fechado no codigo:
|
|
179
179
|
|
package/dist/cli_terminal.js
CHANGED
|
@@ -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,22 +690,22 @@ 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();
|
|
588
696
|
input.setRawMode(true);
|
|
697
|
+
input.resume();
|
|
589
698
|
return await new Promise((resolve, reject) => {
|
|
590
699
|
const enabled = supportsAnsi();
|
|
591
700
|
const availableWidth = Number(output.columns || 96);
|
|
592
701
|
const innerWidth = Math.max(42, Math.min(availableWidth - 8, 116));
|
|
593
|
-
const sectionTopOffsetFromInputLine =
|
|
702
|
+
const sectionTopOffsetFromInputLine = 1;
|
|
594
703
|
let renderedOnce = false;
|
|
595
704
|
let value = "";
|
|
596
705
|
const cleanup = () => {
|
|
597
706
|
input.removeListener("data", onData);
|
|
598
707
|
input.setRawMode(false);
|
|
708
|
+
input.pause();
|
|
599
709
|
rl.resume();
|
|
600
710
|
};
|
|
601
711
|
const renderInputContent = () => {
|
|
@@ -620,13 +730,12 @@ async function askConsoleInput(rl) {
|
|
|
620
730
|
else {
|
|
621
731
|
renderedOnce = true;
|
|
622
732
|
}
|
|
623
|
-
const commands = style(`Comandos: ${CONSOLE_COMMAND_HINT}`, ANSI.slateItalic, enabled);
|
|
624
733
|
const top = renderPromptFrameLine(innerWidth + 2, "┌", "┐");
|
|
625
734
|
const border = style("│", ANSI.brandBlue, enabled);
|
|
626
735
|
const middle = `${border} ${renderInputContent()} ${border}`;
|
|
627
736
|
const bottom = renderPromptFrameLine(innerWidth + 2, "└", "┘");
|
|
628
737
|
output.write("\u001b[J");
|
|
629
|
-
output.write(`${
|
|
738
|
+
output.write(`${top}\n${middle}\n${bottom}\n`);
|
|
630
739
|
cursorTo(output, 0);
|
|
631
740
|
moveCursor(output, 0, -2);
|
|
632
741
|
const visibleValueLength = Math.min(value.length, Math.max(0, innerWidth - 2));
|
|
@@ -836,6 +945,30 @@ export async function runTerminalShell(options) {
|
|
|
836
945
|
});
|
|
837
946
|
});
|
|
838
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
|
+
}
|
|
839
972
|
function buildConversationSummary(summary, job) {
|
|
840
973
|
const rendered = renderStructuredOutcome(job, { compact: true });
|
|
841
974
|
if (!rendered) {
|
|
@@ -847,23 +980,8 @@ function buildConversationSummary(summary, job) {
|
|
|
847
980
|
return `${summary}\n${rendered}`.slice(0, 4_000).trim();
|
|
848
981
|
}
|
|
849
982
|
async function printExtensionsOverview(config) {
|
|
850
|
-
printSection("
|
|
851
|
-
|
|
852
|
-
printMuted("Nenhuma extensão instalada neste bridge.");
|
|
853
|
-
return;
|
|
854
|
-
}
|
|
855
|
-
for (const extension of config.installedExtensions) {
|
|
856
|
-
if (!isManagedBridgeExtensionSlug(extension)) {
|
|
857
|
-
console.log(`- ${extension}`);
|
|
858
|
-
continue;
|
|
859
|
-
}
|
|
860
|
-
const state = await loadManagedBridgeExtensionState(extension);
|
|
861
|
-
const status = state ? formatManagedBridgeExtensionStatus(state.status) : "sem estado salvo";
|
|
862
|
-
console.log(`- ${extension}: ${status}`);
|
|
863
|
-
if (state?.notes) {
|
|
864
|
-
printMuted(` ${truncate(state.notes, 140)}`);
|
|
865
|
-
}
|
|
866
|
-
}
|
|
983
|
+
printSection("Extensões");
|
|
984
|
+
console.log(renderInfoCard(await buildExtensionsCard(config)));
|
|
867
985
|
}
|
|
868
986
|
async function runSetupWizard(rl, options) {
|
|
869
987
|
printSection(options?.postinstall ? "Setup Inicial" : "Pairing Setup");
|
|
@@ -1109,7 +1227,7 @@ async function runOttoConsole(rl, config, runtimeSession, options) {
|
|
|
1109
1227
|
}
|
|
1110
1228
|
async function printStatusView(rl, config, runtimeSession) {
|
|
1111
1229
|
printSection("Bridge Status");
|
|
1112
|
-
|
|
1230
|
+
console.log(renderInfoCard(buildStatusCard(config, runtimeSession)));
|
|
1113
1231
|
await pauseForEnter(rl);
|
|
1114
1232
|
}
|
|
1115
1233
|
async function printHelpView(rl) {
|
|
@@ -1150,7 +1268,7 @@ async function pickHomeChoice(rl, paired) {
|
|
|
1150
1268
|
`${style("2.", ANSI.brandBlue, supportsAnsi())} Terminal`,
|
|
1151
1269
|
`${style("3.", ANSI.brandBlue, supportsAnsi())} Setup / parear novamente`,
|
|
1152
1270
|
`${style("4.", ANSI.brandBlue, supportsAnsi())} Status detalhado`,
|
|
1153
|
-
`${style("5.", ANSI.brandBlue, supportsAnsi())} Extensões
|
|
1271
|
+
`${style("5.", ANSI.brandBlue, supportsAnsi())} Extensões`,
|
|
1154
1272
|
`${style("6.", ANSI.brandBlue, supportsAnsi())} Ajuda`,
|
|
1155
1273
|
`${style("7.", ANSI.brandBlue, supportsAnsi())} Sair`,
|
|
1156
1274
|
]
|
|
@@ -1188,6 +1306,7 @@ async function pickHomeChoice(rl, paired) {
|
|
|
1188
1306
|
export async function launchInteractiveCli(options) {
|
|
1189
1307
|
let rl = await createPromptInterface();
|
|
1190
1308
|
let runtimeSession = null;
|
|
1309
|
+
let restartRequested = false;
|
|
1191
1310
|
try {
|
|
1192
1311
|
let config = await loadBridgeConfig();
|
|
1193
1312
|
if (!config) {
|
|
@@ -1201,7 +1320,7 @@ export async function launchInteractiveCli(options) {
|
|
|
1201
1320
|
await runOttoConsole(rl, config, runtimeSession);
|
|
1202
1321
|
}
|
|
1203
1322
|
if (!config) {
|
|
1204
|
-
return;
|
|
1323
|
+
return { restartRequested: false };
|
|
1205
1324
|
}
|
|
1206
1325
|
}
|
|
1207
1326
|
runtimeSession = runtimeSession || new CliRuntimeSession(config);
|
|
@@ -1218,18 +1337,34 @@ export async function launchInteractiveCli(options) {
|
|
|
1218
1337
|
continue;
|
|
1219
1338
|
}
|
|
1220
1339
|
if (choice === "terminal") {
|
|
1340
|
+
const snapshotBefore = await captureBridgeRuntimeSnapshot(config);
|
|
1221
1341
|
rl.close();
|
|
1222
1342
|
await runTerminalShell({ fromHub: true });
|
|
1223
|
-
rl = await createPromptInterface();
|
|
1224
1343
|
const refreshedConfig = await loadBridgeConfig();
|
|
1344
|
+
const snapshotAfter = await captureBridgeRuntimeSnapshot(refreshedConfig);
|
|
1345
|
+
const runtimeDiff = diffBridgeRuntimeSnapshots(snapshotBefore, snapshotAfter);
|
|
1346
|
+
rl = await createPromptInterface();
|
|
1225
1347
|
if (!refreshedConfig) {
|
|
1226
1348
|
await runtimeSession?.stop().catch(() => undefined);
|
|
1227
1349
|
runtimeSession = null;
|
|
1228
1350
|
printWarning("Pairing local removido no terminal. Encerrando o hub.");
|
|
1229
1351
|
break;
|
|
1230
1352
|
}
|
|
1231
|
-
if (
|
|
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) {
|
|
1232
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
|
+
});
|
|
1233
1368
|
if (runtimeSession) {
|
|
1234
1369
|
await runtimeSession.replaceConfig(refreshedConfig);
|
|
1235
1370
|
await runtimeSession.waitForReady();
|
|
@@ -1284,6 +1419,7 @@ export async function launchInteractiveCli(options) {
|
|
|
1284
1419
|
await runtimeSession?.stop().catch(() => undefined);
|
|
1285
1420
|
rl.close();
|
|
1286
1421
|
}
|
|
1422
|
+
return { restartRequested };
|
|
1287
1423
|
}
|
|
1288
1424
|
export async function runSetupCommand(options) {
|
|
1289
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.
|
|
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
package/scripts/postinstall.mjs
CHANGED
|
@@ -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.
|
|
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"], {
|