arona-agent 1.2.0 → 1.2.1

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/gui/main.cjs CHANGED
@@ -307,6 +307,11 @@ process.stdin.on("data", (data) => {
307
307
  }
308
308
  });
309
309
 
310
+ // 握手:告知 backend 本进程的 stdin 解析器已就绪,可以开始下发 ###GUI### 事件。
311
+ // Windows 下 spawn 后立刻写 stdin 会丢数据(GUI 白屏根因:mode 事件从未到达本进程),
312
+ // backend 收到 hello 前把事件全部入队,收到后按序下发。
313
+ send({ type: "hello" });
314
+
310
315
  // 窗口全关:先发 exit 请求让后端走完整清理,再退出(延迟让协议行先 flush)
311
316
  app.on("window-all-closed", () => {
312
317
  send({ type: "exit" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arona-agent",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Terminal AI Agent with desktop pet Arona — eye-tracking pupils, voice cloning, Computer Use, TTS/STT, MCP.",
5
5
  "keywords": [
6
6
  "voice-clone",
package/src/gui/index.ts CHANGED
@@ -21,9 +21,18 @@ class GuiBridge {
21
21
  private controller: GuiController | null = null;
22
22
  private startingMain = false;
23
23
  private exited = false;
24
+ // Windows 下 spawn 后立刻写 stdin 会丢数据(GUI 白屏根因:mode 事件从未到达 Electron 进程)——
25
+ // 等 GUI 进程回报 hello(stdin 解析器就绪的握手,gui/main.cjs 模块加载即发送)才真正下发,此前入队。
26
+ // macOS/Linux 不受影响,但握手在所有平台统一走一遍(幂等,且顺带验证 stdout 协议链路通)。
27
+ private helloReceived = false;
28
+ private queuedEvents: GuiEvent[] = [];
24
29
 
25
30
  emit(ev: GuiEvent): void {
26
- if (verbose) console.error(chalk.gray("[gui:verbose]"), "emit", ev.type); // 白屏排查:后端→GUI 事件流向
31
+ if (verbose) console.error(chalk.gray("[gui:verbose]"), "emit", ev.type, this.helloReceived ? "" : "(queued)");
32
+ if (!this.helloReceived) {
33
+ this.queuedEvents.push(ev);
34
+ return;
35
+ }
27
36
  if (!this.proc || this.proc.killed) return;
28
37
  try {
29
38
  this.proc.stdin.write(formatGuiLine(ev));
@@ -56,6 +65,16 @@ class GuiBridge {
56
65
  stdio: ["pipe", "pipe", "pipe"],
57
66
  });
58
67
 
68
+ // 握手超时告警:hello 不来 = GUI 进程的 stdin/stdout 协议链路不通(页面白屏只是其结果)
69
+ setTimeout(() => {
70
+ if (!this.helloReceived && !this.exited && this.proc) {
71
+ console.error(chalk.red(t(
72
+ "GUI:15s 未收到 GUI 进程握手(hello),###GUI### stdin 协议链路不通,界面将保持白屏。",
73
+ "GUI: no handshake (hello) from the GUI process within 15s; the ###GUI### stdin protocol is broken and the window will stay blank.",
74
+ )));
75
+ }
76
+ }, 15000);
77
+
59
78
  this.proc.stdout.on("data", (data) => {
60
79
  this.buffer += data.toString();
61
80
  const lines = this.buffer.split("\n");
@@ -167,6 +186,18 @@ class GuiBridge {
167
186
 
168
187
  private async handleRequest(req: GuiRequest): Promise<void> {
169
188
  switch (req.type) {
189
+ case "hello": {
190
+ // GUI 进程 stdin 解析器就绪:解锁排队中的事件(emit mode/setup_info 在 spawn 后立即调用,
191
+ // Windows 下彼时写入会丢失——见 emit() 注释)
192
+ this.helloReceived = true;
193
+ const queued = this.queuedEvents;
194
+ this.queuedEvents = [];
195
+ if (verbose && queued.length) {
196
+ console.error(chalk.gray("[gui:verbose]"), "hello received, flushing", queued.length, "queued events");
197
+ }
198
+ for (const ev of queued) this.emit(ev);
199
+ break;
200
+ }
170
201
  case "setup_submit": {
171
202
  const ok = await runGuiSetup(req.form as unknown as GuiSetupForm, (ev) => this.emit(ev));
172
203
  if (ok) await this.startMain();