happy-imou-cloud 2.0.1 → 2.0.2

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.
Files changed (25) hide show
  1. package/dist/{BaseReasoningProcessor-01KqA3Kz.cjs → BaseReasoningProcessor-B6tJ_eL5.cjs} +2 -2
  2. package/dist/{BaseReasoningProcessor-DQE2l7Xu.mjs → BaseReasoningProcessor-D8VhEbs2.mjs} +2 -2
  3. package/dist/{api-B8v4tczT.cjs → api-D2Njw9Im.cjs} +56 -3
  4. package/dist/{api-B5Ui8Fw0.mjs → api-MYhAGPLn.mjs} +56 -3
  5. package/dist/{command-D8yNlaDo.cjs → command-CVldr51S.cjs} +3 -3
  6. package/dist/{command-BfIuJmeo.mjs → command-nmK6O-ab.mjs} +3 -3
  7. package/dist/{index-BByhFIIq.mjs → index-B97L7qLD.mjs} +15 -17
  8. package/dist/{index-BOqJ9hwi.cjs → index-Bg-YziG2.cjs} +17 -19
  9. package/dist/index.cjs +3 -3
  10. package/dist/index.mjs +3 -3
  11. package/dist/lib.cjs +1 -1
  12. package/dist/lib.d.cts +6 -0
  13. package/dist/lib.d.mts +6 -0
  14. package/dist/lib.mjs +1 -1
  15. package/dist/{persistence-C33AMdtv.cjs → persistence-D_2GkJAO.cjs} +28 -6
  16. package/dist/{persistence-CzpZpiL3.mjs → persistence-Dkm7rm8k.mjs} +29 -7
  17. package/dist/{registerKillSessionHandler-BtSK7IOa.mjs → registerKillSessionHandler-5GbrO0FM.mjs} +2 -2
  18. package/dist/{registerKillSessionHandler-BkzQulD9.cjs → registerKillSessionHandler-BAXmJQRt.cjs} +2 -2
  19. package/dist/{runClaude-CNVufgZb.cjs → runClaude-B-GNEkKg.cjs} +228 -44
  20. package/dist/{runClaude-C_WLfM6c.mjs → runClaude-Cii3R2Fv.mjs} +229 -45
  21. package/dist/{runCodex-8eWjTPJr.mjs → runCodex-C--ZwAhl.mjs} +5 -5
  22. package/dist/{runCodex-Dzy8anlX.cjs → runCodex-CPHyGwj9.cjs} +5 -5
  23. package/dist/{runGemini-nbr0mm-S.mjs → runGemini-CQp7Nuzn.mjs} +5 -5
  24. package/dist/{runGemini-CgsVKP7m.cjs → runGemini-DaDz1bzQ.cjs} +5 -5
  25. package/package.json +1 -2
@@ -2,8 +2,8 @@
2
2
 
3
3
  var os = require('node:os');
4
4
  var path = require('node:path');
5
- var api = require('./api-B8v4tczT.cjs');
6
- var index = require('./index-BOqJ9hwi.cjs');
5
+ var api = require('./api-D2Njw9Im.cjs');
6
+ var index = require('./index-Bg-YziG2.cjs');
7
7
  var node_events = require('node:events');
8
8
  var node_crypto = require('node:crypto');
9
9
 
@@ -1,7 +1,7 @@
1
1
  import os from 'node:os';
2
2
  import { resolve } from 'node:path';
3
- import { c as configuration, p as packageJson, s as startOfflineReconnection, l as logger } from './api-B5Ui8Fw0.mjs';
4
- import { p as projectPath } from './index-BByhFIIq.mjs';
3
+ import { c as configuration, p as packageJson, s as startOfflineReconnection, l as logger } from './api-MYhAGPLn.mjs';
4
+ import { p as projectPath } from './index-B97L7qLD.mjs';
5
5
  import { EventEmitter } from 'node:events';
6
6
  import { randomUUID } from 'node:crypto';
7
7
 
@@ -19,7 +19,7 @@ var path$1 = require('path');
19
19
  var expoServerSdk = require('expo-server-sdk');
20
20
 
21
21
  var name = "happy-imou-cloud";
22
- var version = "2.0.1";
22
+ var version = "2.0.2";
23
23
  var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
24
24
  var author = "long.zhu";
25
25
  var license = "MIT";
@@ -103,7 +103,6 @@ var scripts = {
103
103
  };
104
104
  var dependencies = {
105
105
  "@agentclientprotocol/sdk": "^0.14.1",
106
- "@modelcontextprotocol/sdk": "^1.25.3",
107
106
  "@stablelib/base64": "^2.0.1",
108
107
  "@stablelib/hex": "^2.0.1",
109
108
  "@types/cross-spawn": "^6.0.6",
@@ -433,7 +432,7 @@ async function listDaemonLogFiles(limit = 50) {
433
432
  return { file, path: fullPath, modified: stats.mtime };
434
433
  }).sort((a, b) => b.modified.getTime() - a.modified.getTime());
435
434
  try {
436
- const { readDaemonState } = await Promise.resolve().then(function () { return require('./persistence-C33AMdtv.cjs'); });
435
+ const { readDaemonState } = await Promise.resolve().then(function () { return require('./persistence-D_2GkJAO.cjs'); });
437
436
  const state = await readDaemonState();
438
437
  if (!state) {
439
438
  return logs;
@@ -1362,6 +1361,8 @@ class ApiSessionClient extends node_events.EventEmitter {
1362
1361
  encryptionKey;
1363
1362
  encryptionVariant;
1364
1363
  pendingReliableCodexMessages = [];
1364
+ reconnectAfterServerDisconnectTimer = null;
1365
+ lastSocketServerError = null;
1365
1366
  constructor(credentials, session) {
1366
1367
  super();
1367
1368
  this.credentials = credentials;
@@ -1396,6 +1397,8 @@ class ApiSessionClient extends node_events.EventEmitter {
1396
1397
  });
1397
1398
  this.socket.on("connect", () => {
1398
1399
  logger.debug("Socket connected successfully");
1400
+ this.clearReconnectAfterServerDisconnectTimer();
1401
+ this.lastSocketServerError = null;
1399
1402
  this.rpcHandlerManager.onSocketConnect(this.socket);
1400
1403
  this.flushReliableCodexMessages();
1401
1404
  });
@@ -1405,6 +1408,7 @@ class ApiSessionClient extends node_events.EventEmitter {
1405
1408
  this.socket.on("disconnect", (reason) => {
1406
1409
  logger.debug("[API] Socket disconnected:", reason);
1407
1410
  this.rpcHandlerManager.onSocketDisconnect();
1411
+ this.retryAfterServerDisconnect(reason);
1408
1412
  });
1409
1413
  this.socket.on("connect_error", (error) => {
1410
1414
  logger.debug("[API] Socket connection error:", error);
@@ -1452,6 +1456,7 @@ class ApiSessionClient extends node_events.EventEmitter {
1452
1456
  });
1453
1457
  this.socket.on("error", (error) => {
1454
1458
  logger.debug("[API] Socket error:", error);
1459
+ this.lastSocketServerError = this.normalizeSocketError(error);
1455
1460
  });
1456
1461
  this.socket.connect();
1457
1462
  }
@@ -1723,6 +1728,7 @@ class ApiSessionClient extends node_events.EventEmitter {
1723
1728
  }
1724
1729
  async close() {
1725
1730
  logger.debug("[API] socket.close() called");
1731
+ this.clearReconnectAfterServerDisconnectTimer();
1726
1732
  this.socket.close();
1727
1733
  }
1728
1734
  emitEncryptedSessionMessage(encrypted) {
@@ -1758,6 +1764,53 @@ class ApiSessionClient extends node_events.EventEmitter {
1758
1764
  return false;
1759
1765
  }
1760
1766
  }
1767
+ retryAfterServerDisconnect(reason) {
1768
+ if (reason !== "io server disconnect") {
1769
+ return;
1770
+ }
1771
+ const errorCode = this.lastSocketServerError?.error;
1772
+ if (errorCode !== "REQUEST_EXPIRED" && errorCode !== "REQUEST_REPLAYED") {
1773
+ return;
1774
+ }
1775
+ if (this.reconnectAfterServerDisconnectTimer || this.socket.connected) {
1776
+ return;
1777
+ }
1778
+ logger.debug("[API] Scheduling manual reconnect after retryable server disconnect", {
1779
+ reason,
1780
+ errorCode,
1781
+ message: this.lastSocketServerError?.message
1782
+ });
1783
+ this.reconnectAfterServerDisconnectTimer = setTimeout(() => {
1784
+ this.reconnectAfterServerDisconnectTimer = null;
1785
+ if (this.socket.connected) {
1786
+ return;
1787
+ }
1788
+ logger.debug("[API] Retrying socket connection after server disconnect", {
1789
+ errorCode,
1790
+ message: this.lastSocketServerError?.message
1791
+ });
1792
+ this.socket.connect();
1793
+ }, 1e3);
1794
+ }
1795
+ clearReconnectAfterServerDisconnectTimer() {
1796
+ if (!this.reconnectAfterServerDisconnectTimer) {
1797
+ return;
1798
+ }
1799
+ clearTimeout(this.reconnectAfterServerDisconnectTimer);
1800
+ this.reconnectAfterServerDisconnectTimer = null;
1801
+ }
1802
+ normalizeSocketError(error) {
1803
+ if (!error || typeof error !== "object") {
1804
+ return null;
1805
+ }
1806
+ const candidate = error;
1807
+ const errorCode = typeof candidate.error === "string" ? candidate.error : void 0;
1808
+ const message = typeof candidate.message === "string" ? candidate.message : void 0;
1809
+ if (!errorCode && !message) {
1810
+ return null;
1811
+ }
1812
+ return { error: errorCode, message };
1813
+ }
1761
1814
  }
1762
1815
  function createAbortError() {
1763
1816
  const error = new Error("The operation was aborted");
@@ -17,7 +17,7 @@ import { resolve, join as join$1 } from 'path';
17
17
  import { Expo } from 'expo-server-sdk';
18
18
 
19
19
  var name = "happy-imou-cloud";
20
- var version = "2.0.1";
20
+ var version = "2.0.2";
21
21
  var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
22
22
  var author = "long.zhu";
23
23
  var license = "MIT";
@@ -101,7 +101,6 @@ var scripts = {
101
101
  };
102
102
  var dependencies = {
103
103
  "@agentclientprotocol/sdk": "^0.14.1",
104
- "@modelcontextprotocol/sdk": "^1.25.3",
105
104
  "@stablelib/base64": "^2.0.1",
106
105
  "@stablelib/hex": "^2.0.1",
107
106
  "@types/cross-spawn": "^6.0.6",
@@ -431,7 +430,7 @@ async function listDaemonLogFiles(limit = 50) {
431
430
  return { file, path: fullPath, modified: stats.mtime };
432
431
  }).sort((a, b) => b.modified.getTime() - a.modified.getTime());
433
432
  try {
434
- const { readDaemonState } = await import('./persistence-CzpZpiL3.mjs');
433
+ const { readDaemonState } = await import('./persistence-Dkm7rm8k.mjs');
435
434
  const state = await readDaemonState();
436
435
  if (!state) {
437
436
  return logs;
@@ -1360,6 +1359,8 @@ class ApiSessionClient extends EventEmitter {
1360
1359
  encryptionKey;
1361
1360
  encryptionVariant;
1362
1361
  pendingReliableCodexMessages = [];
1362
+ reconnectAfterServerDisconnectTimer = null;
1363
+ lastSocketServerError = null;
1363
1364
  constructor(credentials, session) {
1364
1365
  super();
1365
1366
  this.credentials = credentials;
@@ -1394,6 +1395,8 @@ class ApiSessionClient extends EventEmitter {
1394
1395
  });
1395
1396
  this.socket.on("connect", () => {
1396
1397
  logger.debug("Socket connected successfully");
1398
+ this.clearReconnectAfterServerDisconnectTimer();
1399
+ this.lastSocketServerError = null;
1397
1400
  this.rpcHandlerManager.onSocketConnect(this.socket);
1398
1401
  this.flushReliableCodexMessages();
1399
1402
  });
@@ -1403,6 +1406,7 @@ class ApiSessionClient extends EventEmitter {
1403
1406
  this.socket.on("disconnect", (reason) => {
1404
1407
  logger.debug("[API] Socket disconnected:", reason);
1405
1408
  this.rpcHandlerManager.onSocketDisconnect();
1409
+ this.retryAfterServerDisconnect(reason);
1406
1410
  });
1407
1411
  this.socket.on("connect_error", (error) => {
1408
1412
  logger.debug("[API] Socket connection error:", error);
@@ -1450,6 +1454,7 @@ class ApiSessionClient extends EventEmitter {
1450
1454
  });
1451
1455
  this.socket.on("error", (error) => {
1452
1456
  logger.debug("[API] Socket error:", error);
1457
+ this.lastSocketServerError = this.normalizeSocketError(error);
1453
1458
  });
1454
1459
  this.socket.connect();
1455
1460
  }
@@ -1721,6 +1726,7 @@ class ApiSessionClient extends EventEmitter {
1721
1726
  }
1722
1727
  async close() {
1723
1728
  logger.debug("[API] socket.close() called");
1729
+ this.clearReconnectAfterServerDisconnectTimer();
1724
1730
  this.socket.close();
1725
1731
  }
1726
1732
  emitEncryptedSessionMessage(encrypted) {
@@ -1756,6 +1762,53 @@ class ApiSessionClient extends EventEmitter {
1756
1762
  return false;
1757
1763
  }
1758
1764
  }
1765
+ retryAfterServerDisconnect(reason) {
1766
+ if (reason !== "io server disconnect") {
1767
+ return;
1768
+ }
1769
+ const errorCode = this.lastSocketServerError?.error;
1770
+ if (errorCode !== "REQUEST_EXPIRED" && errorCode !== "REQUEST_REPLAYED") {
1771
+ return;
1772
+ }
1773
+ if (this.reconnectAfterServerDisconnectTimer || this.socket.connected) {
1774
+ return;
1775
+ }
1776
+ logger.debug("[API] Scheduling manual reconnect after retryable server disconnect", {
1777
+ reason,
1778
+ errorCode,
1779
+ message: this.lastSocketServerError?.message
1780
+ });
1781
+ this.reconnectAfterServerDisconnectTimer = setTimeout(() => {
1782
+ this.reconnectAfterServerDisconnectTimer = null;
1783
+ if (this.socket.connected) {
1784
+ return;
1785
+ }
1786
+ logger.debug("[API] Retrying socket connection after server disconnect", {
1787
+ errorCode,
1788
+ message: this.lastSocketServerError?.message
1789
+ });
1790
+ this.socket.connect();
1791
+ }, 1e3);
1792
+ }
1793
+ clearReconnectAfterServerDisconnectTimer() {
1794
+ if (!this.reconnectAfterServerDisconnectTimer) {
1795
+ return;
1796
+ }
1797
+ clearTimeout(this.reconnectAfterServerDisconnectTimer);
1798
+ this.reconnectAfterServerDisconnectTimer = null;
1799
+ }
1800
+ normalizeSocketError(error) {
1801
+ if (!error || typeof error !== "object") {
1802
+ return null;
1803
+ }
1804
+ const candidate = error;
1805
+ const errorCode = typeof candidate.error === "string" ? candidate.error : void 0;
1806
+ const message = typeof candidate.message === "string" ? candidate.message : void 0;
1807
+ if (!errorCode && !message) {
1808
+ return null;
1809
+ }
1810
+ return { error: errorCode, message };
1811
+ }
1759
1812
  }
1760
1813
  function createAbortError() {
1761
1814
  const error = new Error("The operation was aborted");
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-BOqJ9hwi.cjs');
3
+ var index = require('./index-Bg-YziG2.cjs');
4
4
  require('chalk');
5
- require('./api-B8v4tczT.cjs');
5
+ require('./api-D2Njw9Im.cjs');
6
6
  require('axios');
7
7
  require('fs');
8
8
  require('node:fs');
@@ -19,7 +19,7 @@ require('fs/promises');
19
19
  require('crypto');
20
20
  require('path');
21
21
  require('expo-server-sdk');
22
- require('./persistence-C33AMdtv.cjs');
22
+ require('./persistence-D_2GkJAO.cjs');
23
23
  require('node:fs/promises');
24
24
  require('os');
25
25
  require('tmp');
@@ -1,6 +1,6 @@
1
- import { c as createDefaultRuntimeShell } from './index-BByhFIIq.mjs';
1
+ import { c as createDefaultRuntimeShell } from './index-B97L7qLD.mjs';
2
2
  import 'chalk';
3
- import './api-B5Ui8Fw0.mjs';
3
+ import './api-MYhAGPLn.mjs';
4
4
  import 'axios';
5
5
  import 'fs';
6
6
  import 'node:fs';
@@ -17,7 +17,7 @@ import 'fs/promises';
17
17
  import 'crypto';
18
18
  import 'path';
19
19
  import 'expo-server-sdk';
20
- import './persistence-CzpZpiL3.mjs';
20
+ import './persistence-Dkm7rm8k.mjs';
21
21
  import 'node:fs/promises';
22
22
  import 'os';
23
23
  import 'tmp';
@@ -1,6 +1,6 @@
1
1
  import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
2
- import { l as logger, e as encodeBase64, c as configuration, h as buildAuthenticatedHeaders, S as SigningBootstrapRequiredError, j as SIGNING_BOOTSTRAP_REQUIRED_MESSAGE, k as encodeBase64Url, f as delay, m as buildClientHeaders, n as decodeBase64, H as HAPPY_CLOUD_DAEMON_PORT, p as packageJson, A as ApiClient, o as getLatestDaemonLog } from './api-B5Ui8Fw0.mjs';
3
- import { writeCredentialsLegacy, writeCredentialsDataKey, readCredentials, readSettings, updateSettings, readDaemonState, clearDaemonState, acquireDaemonLock, writeDaemonState, releaseDaemonLock, validateProfileForAgent, getProfileEnvironmentVariables, clearCredentials, clearMachineId } from './persistence-CzpZpiL3.mjs';
2
+ import { l as logger, e as encodeBase64, c as configuration, h as buildAuthenticatedHeaders, S as SigningBootstrapRequiredError, j as SIGNING_BOOTSTRAP_REQUIRED_MESSAGE, k as encodeBase64Url, f as delay, m as buildClientHeaders, n as decodeBase64, H as HAPPY_CLOUD_DAEMON_PORT, p as packageJson, A as ApiClient, o as getLatestDaemonLog } from './api-MYhAGPLn.mjs';
3
+ import { writeCredentialsLegacy, writeCredentialsDataKey, readCredentials, readSettings, updateSettings, readDaemonState, clearDaemonState, acquireDaemonLock, writeDaemonState, releaseDaemonLock, validateProfileForAgent, getProfileEnvironmentVariables, clearCredentials, clearMachineId } from './persistence-Dkm7rm8k.mjs';
4
4
  import { z } from 'zod';
5
5
  import fs from 'fs/promises';
6
6
  import os, { homedir } from 'os';
@@ -3743,19 +3743,17 @@ function updateLocalGeminiCredentials(tokens) {
3743
3743
  }
3744
3744
  }
3745
3745
 
3746
- function getProjectPath(workingDirectory) {
3747
- let resolved = resolve$1(workingDirectory);
3748
- if (process.platform === "win32" && isAbsolute(resolved)) {
3749
- resolved = resolved.replace(/^[A-Z]:/i, "");
3750
- }
3751
- const projectId = resolved.replace(/[\\\/\.: _]/g, "-");
3752
- const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR || join(homedir$1(), ".claude");
3746
+ function getProjectPath(workingDirectory, claudeConfigDirOverride) {
3747
+ const projectId = resolve$1(workingDirectory).replace(/[^a-zA-Z0-9-]/g, "-");
3748
+ const claudeConfigDirRaw = process.env.CLAUDE_CONFIG_DIR ?? "";
3749
+ const claudeConfigDirTrimmed = claudeConfigDirRaw.trim();
3750
+ const claudeConfigDir = claudeConfigDirTrimmed ? claudeConfigDirTrimmed : join(homedir$1(), ".claude");
3753
3751
  return join(claudeConfigDir, "projects", projectId);
3754
3752
  }
3755
3753
 
3756
- function claudeCheckSession(sessionId, path) {
3754
+ function claudeCheckSession(sessionId, path, transcriptPath) {
3757
3755
  const projectDir = getProjectPath(path);
3758
- const sessionFile = join(projectDir, `${sessionId}.jsonl`);
3756
+ const sessionFile = transcriptPath ?? join(projectDir, `${sessionId}.jsonl`);
3759
3757
  const sessionExists = existsSync(sessionFile);
3760
3758
  if (!sessionExists) {
3761
3759
  logger.debug(`[claudeCheckSession] Path ${sessionFile} does not exist`);
@@ -6316,12 +6314,12 @@ async function ensureUnifiedDaemonStarted() {
6316
6314
  async function executeUnifiedProvider(opts) {
6317
6315
  const credentials = await ensureUnifiedRuntimePrerequisites(opts.credentials);
6318
6316
  if (opts.provider === "claude") {
6319
- const { runClaude } = await import('./runClaude-C_WLfM6c.mjs');
6317
+ const { runClaude } = await import('./runClaude-Cii3R2Fv.mjs');
6320
6318
  await runClaude(credentials, opts.claudeOptions ?? {});
6321
6319
  return;
6322
6320
  }
6323
6321
  if (opts.provider === "codex") {
6324
- const { runCodex } = await import('./runCodex-8eWjTPJr.mjs');
6322
+ const { runCodex } = await import('./runCodex-C--ZwAhl.mjs');
6325
6323
  await runCodex({
6326
6324
  credentials,
6327
6325
  startedBy: opts.startedBy,
@@ -6331,7 +6329,7 @@ async function executeUnifiedProvider(opts) {
6331
6329
  return;
6332
6330
  }
6333
6331
  if (opts.provider === "gemini") {
6334
- const { runGemini } = await import('./runGemini-nbr0mm-S.mjs');
6332
+ const { runGemini } = await import('./runGemini-CQp7Nuzn.mjs');
6335
6333
  await runGemini({
6336
6334
  credentials,
6337
6335
  startedBy: opts.startedBy
@@ -6373,7 +6371,7 @@ function shouldRunMainClaudeFlow(opts) {
6373
6371
  return;
6374
6372
  } else if (subcommand === "runtime") {
6375
6373
  if (args[1] === "providers") {
6376
- const { renderRuntimeProviders } = await import('./command-BfIuJmeo.mjs');
6374
+ const { renderRuntimeProviders } = await import('./command-nmK6O-ab.mjs');
6377
6375
  console.log(renderRuntimeProviders());
6378
6376
  return;
6379
6377
  }
@@ -6551,8 +6549,8 @@ function shouldRunMainClaudeFlow(opts) {
6551
6549
  const projectId = args[3];
6552
6550
  try {
6553
6551
  const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return config; });
6554
- const { readCredentials: readCredentials2 } = await import('./persistence-CzpZpiL3.mjs');
6555
- const { ApiClient: ApiClient2 } = await import('./api-B5Ui8Fw0.mjs').then(function (n) { return n.q; });
6552
+ const { readCredentials: readCredentials2 } = await import('./persistence-Dkm7rm8k.mjs');
6553
+ const { ApiClient: ApiClient2 } = await import('./api-MYhAGPLn.mjs').then(function (n) { return n.q; });
6556
6554
  let userEmail = void 0;
6557
6555
  try {
6558
6556
  const credentials = await readCredentials2();
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var chalk = require('chalk');
4
- var api = require('./api-B8v4tczT.cjs');
5
- var persistence = require('./persistence-C33AMdtv.cjs');
4
+ var api = require('./api-D2Njw9Im.cjs');
5
+ var persistence = require('./persistence-D_2GkJAO.cjs');
6
6
  var z = require('zod');
7
7
  var fs$2 = require('fs/promises');
8
8
  var os$1 = require('os');
@@ -70,7 +70,7 @@ async function openBrowser(url) {
70
70
  }
71
71
  }
72
72
 
73
- const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-BOqJ9hwi.cjs', document.baseURI).href)));
73
+ const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-Bg-YziG2.cjs', document.baseURI).href)));
74
74
  const QRCode = require$1("qrcode-terminal/vendor/QRCode");
75
75
  const QRErrorCorrectLevel = require$1("qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel");
76
76
  const pendingTempFiles = /* @__PURE__ */ new Set();
@@ -693,7 +693,7 @@ function setupCleanupHandlers() {
693
693
  });
694
694
  }
695
695
 
696
- const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-BOqJ9hwi.cjs', document.baseURI).href))));
696
+ const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-Bg-YziG2.cjs', document.baseURI).href))));
697
697
  function projectPath() {
698
698
  const path = path$1.resolve(__dirname$1, "..");
699
699
  return path;
@@ -3765,19 +3765,17 @@ function updateLocalGeminiCredentials(tokens) {
3765
3765
  }
3766
3766
  }
3767
3767
 
3768
- function getProjectPath(workingDirectory) {
3769
- let resolved = path.resolve(workingDirectory);
3770
- if (process.platform === "win32" && path.isAbsolute(resolved)) {
3771
- resolved = resolved.replace(/^[A-Z]:/i, "");
3772
- }
3773
- const projectId = resolved.replace(/[\\\/\.: _]/g, "-");
3774
- const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude");
3768
+ function getProjectPath(workingDirectory, claudeConfigDirOverride) {
3769
+ const projectId = path.resolve(workingDirectory).replace(/[^a-zA-Z0-9-]/g, "-");
3770
+ const claudeConfigDirRaw = process.env.CLAUDE_CONFIG_DIR ?? "";
3771
+ const claudeConfigDirTrimmed = claudeConfigDirRaw.trim();
3772
+ const claudeConfigDir = claudeConfigDirTrimmed ? claudeConfigDirTrimmed : path.join(os.homedir(), ".claude");
3775
3773
  return path.join(claudeConfigDir, "projects", projectId);
3776
3774
  }
3777
3775
 
3778
- function claudeCheckSession(sessionId, path$1) {
3776
+ function claudeCheckSession(sessionId, path$1, transcriptPath) {
3779
3777
  const projectDir = getProjectPath(path$1);
3780
- const sessionFile = path.join(projectDir, `${sessionId}.jsonl`);
3778
+ const sessionFile = transcriptPath ?? path.join(projectDir, `${sessionId}.jsonl`);
3781
3779
  const sessionExists = fs.existsSync(sessionFile);
3782
3780
  if (!sessionExists) {
3783
3781
  api.logger.debug(`[claudeCheckSession] Path ${sessionFile} does not exist`);
@@ -6338,12 +6336,12 @@ async function ensureUnifiedDaemonStarted() {
6338
6336
  async function executeUnifiedProvider(opts) {
6339
6337
  const credentials = await ensureUnifiedRuntimePrerequisites(opts.credentials);
6340
6338
  if (opts.provider === "claude") {
6341
- const { runClaude } = await Promise.resolve().then(function () { return require('./runClaude-CNVufgZb.cjs'); });
6339
+ const { runClaude } = await Promise.resolve().then(function () { return require('./runClaude-B-GNEkKg.cjs'); });
6342
6340
  await runClaude(credentials, opts.claudeOptions ?? {});
6343
6341
  return;
6344
6342
  }
6345
6343
  if (opts.provider === "codex") {
6346
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-Dzy8anlX.cjs'); });
6344
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-CPHyGwj9.cjs'); });
6347
6345
  await runCodex({
6348
6346
  credentials,
6349
6347
  startedBy: opts.startedBy,
@@ -6353,7 +6351,7 @@ async function executeUnifiedProvider(opts) {
6353
6351
  return;
6354
6352
  }
6355
6353
  if (opts.provider === "gemini") {
6356
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-CgsVKP7m.cjs'); });
6354
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-DaDz1bzQ.cjs'); });
6357
6355
  await runGemini({
6358
6356
  credentials,
6359
6357
  startedBy: opts.startedBy
@@ -6395,7 +6393,7 @@ function shouldRunMainClaudeFlow(opts) {
6395
6393
  return;
6396
6394
  } else if (subcommand === "runtime") {
6397
6395
  if (args[1] === "providers") {
6398
- const { renderRuntimeProviders } = await Promise.resolve().then(function () { return require('./command-D8yNlaDo.cjs'); });
6396
+ const { renderRuntimeProviders } = await Promise.resolve().then(function () { return require('./command-CVldr51S.cjs'); });
6399
6397
  console.log(renderRuntimeProviders());
6400
6398
  return;
6401
6399
  }
@@ -6573,8 +6571,8 @@ function shouldRunMainClaudeFlow(opts) {
6573
6571
  const projectId = args[3];
6574
6572
  try {
6575
6573
  const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return config; });
6576
- const { readCredentials: readCredentials2 } = await Promise.resolve().then(function () { return require('./persistence-C33AMdtv.cjs'); });
6577
- const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./api-B8v4tczT.cjs'); }).then(function (n) { return n.api; });
6574
+ const { readCredentials: readCredentials2 } = await Promise.resolve().then(function () { return require('./persistence-D_2GkJAO.cjs'); });
6575
+ const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./api-D2Njw9Im.cjs'); }).then(function (n) { return n.api; });
6578
6576
  let userEmail = void 0;
6579
6577
  try {
6580
6578
  const credentials = await readCredentials2();
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  require('chalk');
4
- require('./api-B8v4tczT.cjs');
5
- require('./persistence-C33AMdtv.cjs');
4
+ require('./api-D2Njw9Im.cjs');
5
+ require('./persistence-D_2GkJAO.cjs');
6
6
  require('zod');
7
- require('./index-BOqJ9hwi.cjs');
7
+ require('./index-Bg-YziG2.cjs');
8
8
  require('node:child_process');
9
9
  require('node:fs');
10
10
  require('@agentclientprotocol/sdk');
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import 'chalk';
2
- import './api-B5Ui8Fw0.mjs';
3
- import './persistence-CzpZpiL3.mjs';
2
+ import './api-MYhAGPLn.mjs';
3
+ import './persistence-Dkm7rm8k.mjs';
4
4
  import 'zod';
5
- import './index-BByhFIIq.mjs';
5
+ import './index-B97L7qLD.mjs';
6
6
  import 'node:child_process';
7
7
  import 'node:fs';
8
8
  import '@agentclientprotocol/sdk';
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var api = require('./api-B8v4tczT.cjs');
3
+ var api = require('./api-D2Njw9Im.cjs');
4
4
  var types = require('./types-DVk3crez.cjs');
5
5
  require('axios');
6
6
  require('chalk');
package/dist/lib.d.cts CHANGED
@@ -468,6 +468,7 @@ type Metadata = {
468
468
  };
469
469
  machineId?: string;
470
470
  claudeSessionId?: string;
471
+ claudeTranscriptPath?: string;
471
472
  codexSessionId?: string;
472
473
  tools?: string[];
473
474
  slashCommands?: string[];
@@ -687,6 +688,8 @@ declare class ApiSessionClient extends EventEmitter {
687
688
  private encryptionKey;
688
689
  private encryptionVariant;
689
690
  private pendingReliableCodexMessages;
691
+ private reconnectAfterServerDisconnectTimer;
692
+ private lastSocketServerError;
690
693
  constructor(credentials: Credentials, session: Session);
691
694
  onUserMessage(callback: (data: UserMessage) => void): void;
692
695
  getMetadataSnapshot(): Metadata | null;
@@ -748,6 +751,9 @@ declare class ApiSessionClient extends EventEmitter {
748
751
  private emitEncryptedSessionMessage;
749
752
  private flushReliableCodexMessages;
750
753
  private shouldBufferReliableCodexMessage;
754
+ private retryAfterServerDisconnect;
755
+ private clearReconnectAfterServerDisconnectTimer;
756
+ private normalizeSocketError;
751
757
  }
752
758
 
753
759
  interface SpawnSessionOptions {
package/dist/lib.d.mts CHANGED
@@ -468,6 +468,7 @@ type Metadata = {
468
468
  };
469
469
  machineId?: string;
470
470
  claudeSessionId?: string;
471
+ claudeTranscriptPath?: string;
471
472
  codexSessionId?: string;
472
473
  tools?: string[];
473
474
  slashCommands?: string[];
@@ -687,6 +688,8 @@ declare class ApiSessionClient extends EventEmitter {
687
688
  private encryptionKey;
688
689
  private encryptionVariant;
689
690
  private pendingReliableCodexMessages;
691
+ private reconnectAfterServerDisconnectTimer;
692
+ private lastSocketServerError;
690
693
  constructor(credentials: Credentials, session: Session);
691
694
  onUserMessage(callback: (data: UserMessage) => void): void;
692
695
  getMetadataSnapshot(): Metadata | null;
@@ -748,6 +751,9 @@ declare class ApiSessionClient extends EventEmitter {
748
751
  private emitEncryptedSessionMessage;
749
752
  private flushReliableCodexMessages;
750
753
  private shouldBufferReliableCodexMessage;
754
+ private retryAfterServerDisconnect;
755
+ private clearReconnectAfterServerDisconnectTimer;
756
+ private normalizeSocketError;
751
757
  }
752
758
 
753
759
  interface SpawnSessionOptions {
package/dist/lib.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiClient, a as ApiSessionClient, c as configuration, l as logger } from './api-B5Ui8Fw0.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, c as configuration, l as logger } from './api-MYhAGPLn.mjs';
2
2
  export { R as RawJSONLinesSchema } from './types-CiliQpqS.mjs';
3
3
  import 'axios';
4
4
  import 'chalk';
@@ -3,7 +3,7 @@
3
3
  var promises = require('node:fs/promises');
4
4
  var fs = require('node:fs');
5
5
  var path = require('node:path');
6
- var api = require('./api-B8v4tczT.cjs');
6
+ var api = require('./api-D2Njw9Im.cjs');
7
7
  var z = require('zod');
8
8
  require('axios');
9
9
  require('chalk');
@@ -206,16 +206,37 @@ async function updateSettings(updater) {
206
206
  const LOCK_RETRY_INTERVAL_MS = 100;
207
207
  const MAX_LOCK_ATTEMPTS = 50;
208
208
  const STALE_LOCK_TIMEOUT_MS = 1e4;
209
+ const LOCK_CONTENTION_CODES = /* @__PURE__ */ new Set(["EEXIST", "EPERM", "EACCES", "EBUSY"]);
210
+ const LOCK_RELEASE_RETRYABLE_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY"]);
209
211
  const lockFile = api.configuration.settingsFile + ".lock";
210
- const tmpFile = `${api.configuration.settingsFile}.${process.pid}.${Date.now()}.tmp`;
212
+ const tmpFile = `${api.configuration.settingsFile}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
211
213
  let fileHandle;
212
214
  let attempts = 0;
215
+ if (!fs.existsSync(api.configuration.happyCloudHomeDir)) {
216
+ await promises.mkdir(api.configuration.happyCloudHomeDir, { recursive: true });
217
+ }
218
+ async function removeFileWithRetry(path) {
219
+ for (let attempt = 1; attempt <= 20; attempt++) {
220
+ try {
221
+ await promises.unlink(path);
222
+ return;
223
+ } catch (err) {
224
+ if (err?.code === "ENOENT") {
225
+ return;
226
+ }
227
+ if (!LOCK_RELEASE_RETRYABLE_CODES.has(err?.code) || attempt === 20) {
228
+ throw err;
229
+ }
230
+ await new Promise((resolve) => setTimeout(resolve, 25));
231
+ }
232
+ }
233
+ }
213
234
  while (attempts < MAX_LOCK_ATTEMPTS) {
214
235
  try {
215
236
  fileHandle = await promises.open(lockFile, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY);
216
237
  break;
217
238
  } catch (err) {
218
- if (err.code === "EEXIST") {
239
+ if (LOCK_CONTENTION_CODES.has(err?.code)) {
219
240
  attempts++;
220
241
  await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_INTERVAL_MS));
221
242
  try {
@@ -245,11 +266,12 @@ async function updateSettings(updater) {
245
266
  return updated;
246
267
  } finally {
247
268
  if (fs.existsSync(tmpFile)) {
248
- await promises.unlink(tmpFile).catch(() => {
269
+ await removeFileWithRetry(tmpFile).catch(() => {
249
270
  });
250
271
  }
251
- await fileHandle.close();
252
- await promises.unlink(lockFile).catch(() => {
272
+ await fileHandle.close().catch(() => {
273
+ });
274
+ await removeFileWithRetry(lockFile).catch(() => {
253
275
  });
254
276
  }
255
277
  }