happy-imou-cloud 2.0.2 → 2.0.4

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-B6tJ_eL5.cjs → BaseReasoningProcessor-DEEfNi5Y.cjs} +4 -4
  2. package/dist/{BaseReasoningProcessor-D8VhEbs2.mjs → BaseReasoningProcessor-Di1yEMMv.mjs} +2 -2
  3. package/dist/{api-MYhAGPLn.mjs → api-CIHTNilH.mjs} +2 -2
  4. package/dist/{api-D2Njw9Im.cjs → api-CyJG1mr6.cjs} +43 -43
  5. package/dist/{command-nmK6O-ab.mjs → command-BERqmFB0.mjs} +3 -3
  6. package/dist/{command-CVldr51S.cjs → command-CPlJKXDn.cjs} +3 -3
  7. package/dist/{index-Bg-YziG2.cjs → index-1zlH6s7a.cjs} +313 -118
  8. package/dist/{index-B97L7qLD.mjs → index-vNYxNqVZ.mjs} +226 -31
  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.mjs +1 -1
  13. package/dist/{persistence-D_2GkJAO.cjs → persistence-BeFVx6kI.cjs} +28 -28
  14. package/dist/{persistence-Dkm7rm8k.mjs → persistence-sLEqV8vk.mjs} +1 -1
  15. package/dist/{registerKillSessionHandler-BAXmJQRt.cjs → registerKillSessionHandler-CCxqGFjZ.cjs} +2 -2
  16. package/dist/{registerKillSessionHandler-5GbrO0FM.mjs → registerKillSessionHandler-uVHqIC4h.mjs} +2 -2
  17. package/dist/{runClaude-Cii3R2Fv.mjs → runClaude-Dl9nIRIg.mjs} +25 -5
  18. package/dist/{runClaude-B-GNEkKg.cjs → runClaude-Dz-PCSvb.cjs} +53 -33
  19. package/dist/{runCodex-CPHyGwj9.cjs → runCodex-BtZplK1R.cjs} +275 -408
  20. package/dist/{runCodex-C--ZwAhl.mjs → runCodex-DgKKw3IU.mjs} +273 -409
  21. package/dist/{runGemini-CQp7Nuzn.mjs → runGemini-CM1v3I24.mjs} +10 -8
  22. package/dist/{runGemini-DaDz1bzQ.cjs → runGemini-DUyH311Z.cjs} +10 -8
  23. package/package.json +1 -1
  24. package/dist/future-Dq4Ha1Dn.cjs +0 -24
  25. package/dist/future-xRdLl3vf.mjs +0 -22
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var chalk = require('chalk');
4
- var api = require('./api-D2Njw9Im.cjs');
5
- var persistence = require('./persistence-D_2GkJAO.cjs');
4
+ var api = require('./api-CyJG1mr6.cjs');
5
+ var persistence = require('./persistence-BeFVx6kI.cjs');
6
6
  var z = require('zod');
7
- var fs$2 = require('fs/promises');
7
+ var fs$1 = require('fs/promises');
8
8
  var os$1 = require('os');
9
9
  var tmp = require('tmp');
10
10
  var node_crypto = require('node:crypto');
@@ -14,18 +14,18 @@ var qrcode = require('qrcode-terminal');
14
14
  var promises = require('node:fs/promises');
15
15
  var node_module = require('node:module');
16
16
  var os = require('node:os');
17
- var path = require('node:path');
17
+ var node_path = require('node:path');
18
18
  var open = require('open');
19
19
  var React = require('react');
20
20
  var ink = require('ink');
21
21
  var child_process = require('child_process');
22
- var path$1 = require('path');
22
+ var path = require('path');
23
23
  var url = require('url');
24
- var fs$1 = require('fs');
24
+ var fs = require('fs');
25
25
  var node_child_process = require('node:child_process');
26
26
  var psList = require('ps-list');
27
27
  var spawn = require('cross-spawn');
28
- var fs = require('node:fs');
28
+ var node_fs = require('node:fs');
29
29
  var fastify = require('fastify');
30
30
  var fastifyTypeProviderZod = require('fastify-type-provider-zod');
31
31
  var node_readline = require('node:readline');
@@ -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-Bg-YziG2.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-1zlH6s7a.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();
@@ -164,7 +164,7 @@ async function openWindowsQrCode(value) {
164
164
  "</body>",
165
165
  "</html>"
166
166
  ].join("");
167
- const filePath = path.join(os.tmpdir(), `happy-auth-qrcode-${node_crypto.randomUUID()}.html`);
167
+ const filePath = node_path.join(os.tmpdir(), `happy-auth-qrcode-${node_crypto.randomUUID()}.html`);
168
168
  await promises.writeFile(filePath, html, "utf8");
169
169
  const opened = await openBrowser(filePath);
170
170
  if (opened) {
@@ -693,18 +693,18 @@ 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-Bg-YziG2.cjs', document.baseURI).href))));
696
+ const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-1zlH6s7a.cjs', document.baseURI).href))));
697
697
  function projectPath() {
698
- const path = path$1.resolve(__dirname$1, "..");
699
- return path;
698
+ const path$1 = path.resolve(__dirname$1, "..");
699
+ return path$1;
700
700
  }
701
701
 
702
702
  function getDaemonPid() {
703
703
  try {
704
- if (!fs.existsSync(api.configuration.daemonStateFile)) {
704
+ if (!node_fs.existsSync(api.configuration.daemonStateFile)) {
705
705
  return null;
706
706
  }
707
- const state = JSON.parse(fs.readFileSync(api.configuration.daemonStateFile, "utf-8"));
707
+ const state = JSON.parse(node_fs.readFileSync(api.configuration.daemonStateFile, "utf-8"));
708
708
  return typeof state.pid === "number" ? state.pid : null;
709
709
  } catch {
710
710
  return null;
@@ -1030,8 +1030,8 @@ async function isDaemonRunningCurrentlyInstalledHappyVersion() {
1030
1030
  return false;
1031
1031
  }
1032
1032
  try {
1033
- const packageJsonPath = path$1.join(projectPath(), "package.json");
1034
- const packageJson = JSON.parse(fs$1.readFileSync(packageJsonPath, "utf-8"));
1033
+ const packageJsonPath = path.join(projectPath(), "package.json");
1034
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
1035
1035
  const currentCliVersion = packageJson.version;
1036
1036
  api.logger.debug(`[DAEMON CONTROL] Current CLI version: ${currentCliVersion}, Daemon started with version: ${state.startedWithCliVersion}`);
1037
1037
  if (currentCliVersion !== state.startedWithCliVersion) {
@@ -1131,14 +1131,14 @@ function getEnvironmentInfo() {
1131
1131
  };
1132
1132
  }
1133
1133
  function getLogFiles(logDir) {
1134
- if (!fs.existsSync(logDir)) {
1134
+ if (!node_fs.existsSync(logDir)) {
1135
1135
  return [];
1136
1136
  }
1137
1137
  try {
1138
- return fs.readdirSync(logDir).filter((file) => file.endsWith(".log")).map((file) => {
1139
- const path$1 = path.join(logDir, file);
1140
- const stats = fs.statSync(path$1);
1141
- return { file, path: path$1, modified: stats.mtime };
1138
+ return node_fs.readdirSync(logDir).filter((file) => file.endsWith(".log")).map((file) => {
1139
+ const path = node_path.join(logDir, file);
1140
+ const stats = node_fs.statSync(path);
1141
+ return { file, path, modified: stats.mtime };
1142
1142
  }).sort((a, b) => b.modified.getTime() - a.modified.getTime());
1143
1143
  } catch {
1144
1144
  return [];
@@ -1157,13 +1157,13 @@ async function runDoctorCommand(filter) {
1157
1157
  console.log("");
1158
1158
  console.log(chalk.bold("\u{1F527} Daemon Spawn Diagnostics"));
1159
1159
  const projectRoot = projectPath();
1160
- const wrapperPath = path.join(projectRoot, "bin", "happy.mjs");
1161
- const cliEntrypoint = path.join(projectRoot, "dist", "index.mjs");
1160
+ const wrapperPath = node_path.join(projectRoot, "bin", "happy.mjs");
1161
+ const cliEntrypoint = node_path.join(projectRoot, "dist", "index.mjs");
1162
1162
  console.log(`Project Root: ${chalk.blue(projectRoot)}`);
1163
1163
  console.log(`Wrapper Script: ${chalk.blue(wrapperPath)}`);
1164
1164
  console.log(`CLI Entrypoint: ${chalk.blue(cliEntrypoint)}`);
1165
- console.log(`Wrapper Exists: ${fs.existsSync(wrapperPath) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
1166
- console.log(`CLI Exists: ${fs.existsSync(cliEntrypoint) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
1165
+ console.log(`Wrapper Exists: ${node_fs.existsSync(wrapperPath) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
1166
+ console.log(`CLI Exists: ${node_fs.existsSync(cliEntrypoint) ? chalk.green("\u2713 Yes") : chalk.red("\u274C No")}`);
1167
1167
  console.log("");
1168
1168
  console.log(chalk.bold("\u2699\uFE0F Configuration"));
1169
1169
  console.log(`Happy Home: ${chalk.blue(api.configuration.happyCloudHomeDir)}`);
@@ -1329,7 +1329,7 @@ const isBun = () => getRuntime() === "bun";
1329
1329
 
1330
1330
  function spawnHappyCLI(args, options = {}) {
1331
1331
  const projectRoot = projectPath();
1332
- const entrypoint = path.join(projectRoot, "dist", "index.mjs");
1332
+ const entrypoint = node_path.join(projectRoot, "dist", "index.mjs");
1333
1333
  let directory;
1334
1334
  if ("cwd" in options) {
1335
1335
  directory = options.cwd;
@@ -1344,7 +1344,7 @@ function spawnHappyCLI(args, options = {}) {
1344
1344
  entrypoint,
1345
1345
  ...args
1346
1346
  ];
1347
- if (!fs.existsSync(entrypoint)) {
1347
+ if (!node_fs.existsSync(entrypoint)) {
1348
1348
  const errorMessage = `Entrypoint ${entrypoint} does not exist`;
1349
1349
  api.logger.debug(`[SPAWN HAPPY CLOUD CLI] ${errorMessage}`);
1350
1350
  throw new Error(errorMessage);
@@ -2404,7 +2404,7 @@ async function startDaemon() {
2404
2404
  const { directory, sessionId, machineId: machineId2, approvedNewDirectoryCreation = true } = options;
2405
2405
  let directoryCreated = false;
2406
2406
  try {
2407
- await fs$2.access(directory);
2407
+ await fs$1.access(directory);
2408
2408
  api.logger.debug(`[DAEMON RUN] Directory exists: ${directory}`);
2409
2409
  } catch (error) {
2410
2410
  api.logger.debug(`[DAEMON RUN] Directory doesn't exist, creating: ${directory}`);
@@ -2416,7 +2416,7 @@ async function startDaemon() {
2416
2416
  };
2417
2417
  }
2418
2418
  try {
2419
- await fs$2.mkdir(directory, { recursive: true });
2419
+ await fs$1.mkdir(directory, { recursive: true });
2420
2420
  api.logger.debug(`[DAEMON RUN] Successfully created directory: ${directory}`);
2421
2421
  directoryCreated = true;
2422
2422
  } catch (mkdirError) {
@@ -2445,7 +2445,7 @@ async function startDaemon() {
2445
2445
  if (options.token) {
2446
2446
  if (options.agent === "codex") {
2447
2447
  const codexHomeDir = tmp__namespace.dirSync();
2448
- fs$2.writeFile(path$1.join(codexHomeDir.name, "auth.json"), options.token);
2448
+ fs$1.writeFile(path.join(codexHomeDir.name, "auth.json"), options.token);
2449
2449
  authEnv.CODEX_HOME = codexHomeDir.name;
2450
2450
  } else {
2451
2451
  authEnv.CLAUDE_CODE_OAUTH_TOKEN = options.token;
@@ -2511,7 +2511,7 @@ async function startDaemon() {
2511
2511
  const sessionDesc = tmuxSessionName || "current/most recent session";
2512
2512
  api.logger.debug(`[DAEMON RUN] Attempting to spawn session in tmux: ${sessionDesc}`);
2513
2513
  const tmux = getTmuxUtilities(tmuxSessionName);
2514
- const cliPath = path$1.join(projectPath(), "dist", "index.mjs");
2514
+ const cliPath = path.join(projectPath(), "dist", "index.mjs");
2515
2515
  const agent = resolveDaemonSpawnAgent(options.agent);
2516
2516
  const fullCommand = `node --no-warnings --no-deprecation ${cliPath} ${buildDaemonSpawnArgs(agent).join(" ")}`;
2517
2517
  const windowName = `happy-${Date.now()}-${agent}`;
@@ -2757,7 +2757,7 @@ async function startDaemon() {
2757
2757
  pidToTrackedSession.delete(pid);
2758
2758
  }
2759
2759
  }
2760
- const projectVersion = JSON.parse(fs$1.readFileSync(path$1.join(projectPath(), "package.json"), "utf-8")).version;
2760
+ const projectVersion = JSON.parse(fs.readFileSync(path.join(projectPath(), "package.json"), "utf-8")).version;
2761
2761
  if (projectVersion !== api.configuration.currentCliVersion) {
2762
2762
  api.logger.debug("[DAEMON RUN] Daemon is outdated, triggering self-restart with latest version, clearing heartbeat interval");
2763
2763
  clearInterval(restartOnStaleVersionAndHeartbeat);
@@ -2850,7 +2850,7 @@ const PLIST_LABEL$1 = "com.happy-cloud.daemon";
2850
2850
  const PLIST_FILE$1 = `/Library/LaunchDaemons/${PLIST_LABEL$1}.plist`;
2851
2851
  async function install$1() {
2852
2852
  try {
2853
- if (fs$1.existsSync(PLIST_FILE$1)) {
2853
+ if (fs.existsSync(PLIST_FILE$1)) {
2854
2854
  api.logger.info("Daemon plist already exists. Uninstalling first...");
2855
2855
  child_process.execSync(`launchctl unload ${PLIST_FILE$1}`, { stdio: "inherit" });
2856
2856
  }
@@ -2894,8 +2894,8 @@ async function install$1() {
2894
2894
  </dict>
2895
2895
  </plist>
2896
2896
  `);
2897
- fs$1.writeFileSync(PLIST_FILE$1, plistContent);
2898
- fs$1.chmodSync(PLIST_FILE$1, 420);
2897
+ fs.writeFileSync(PLIST_FILE$1, plistContent);
2898
+ fs.chmodSync(PLIST_FILE$1, 420);
2899
2899
  api.logger.info(`Created daemon plist at ${PLIST_FILE$1}`);
2900
2900
  child_process.execSync(`launchctl load ${PLIST_FILE$1}`, { stdio: "inherit" });
2901
2901
  api.logger.info("Daemon installed and started successfully");
@@ -2921,7 +2921,7 @@ const PLIST_LABEL = "com.happy-cli.daemon";
2921
2921
  const PLIST_FILE = `/Library/LaunchDaemons/${PLIST_LABEL}.plist`;
2922
2922
  async function uninstall$1() {
2923
2923
  try {
2924
- if (!fs$1.existsSync(PLIST_FILE)) {
2924
+ if (!fs.existsSync(PLIST_FILE)) {
2925
2925
  api.logger.info("Daemon plist not found. Nothing to uninstall.");
2926
2926
  return;
2927
2927
  }
@@ -2931,7 +2931,7 @@ async function uninstall$1() {
2931
2931
  } catch (error) {
2932
2932
  api.logger.info("Failed to unload daemon (it might not be running)");
2933
2933
  }
2934
- fs$1.unlinkSync(PLIST_FILE);
2934
+ fs.unlinkSync(PLIST_FILE);
2935
2935
  api.logger.info(`Removed daemon plist from ${PLIST_FILE}`);
2936
2936
  api.logger.info("Daemon uninstalled successfully");
2937
2937
  } catch (error) {
@@ -3071,8 +3071,8 @@ async function handleAuthLogout(args = []) {
3071
3071
  console.log(chalk.gray("Stopped daemon"));
3072
3072
  } catch {
3073
3073
  }
3074
- if (fs.existsSync(happyDir)) {
3075
- fs.rmSync(happyDir, { recursive: true, force: true });
3074
+ if (node_fs.existsSync(happyDir)) {
3075
+ node_fs.rmSync(happyDir, { recursive: true, force: true });
3076
3076
  }
3077
3077
  console.log(chalk.green("\u2713 Successfully logged out"));
3078
3078
  console.log(chalk.gray(' Run "hicloud auth login" to authenticate again'));
@@ -3745,10 +3745,10 @@ async function handleConnectStatus() {
3745
3745
  }
3746
3746
  function updateLocalGeminiCredentials(tokens) {
3747
3747
  try {
3748
- const geminiDir = path$1.join(os$1.homedir(), ".gemini");
3749
- const credentialsPath = path$1.join(geminiDir, "oauth_creds.json");
3750
- if (!fs$1.existsSync(geminiDir)) {
3751
- fs$1.mkdirSync(geminiDir, { recursive: true });
3748
+ const geminiDir = path.join(os$1.homedir(), ".gemini");
3749
+ const credentialsPath = path.join(geminiDir, "oauth_creds.json");
3750
+ if (!fs.existsSync(geminiDir)) {
3751
+ fs.mkdirSync(geminiDir, { recursive: true });
3752
3752
  }
3753
3753
  const credentials = {
3754
3754
  access_token: tokens.access_token,
@@ -3758,7 +3758,7 @@ function updateLocalGeminiCredentials(tokens) {
3758
3758
  ...tokens.id_token && { id_token: tokens.id_token },
3759
3759
  ...tokens.expires_in && { expires_in: tokens.expires_in }
3760
3760
  };
3761
- fs$1.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), "utf-8");
3761
+ fs.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), "utf-8");
3762
3762
  console.log(chalk.gray(` Updated local credentials: ${credentialsPath}`));
3763
3763
  } catch (error) {
3764
3764
  console.log(chalk.yellow(` \u26A0\uFE0F Could not update local credentials: ${error}`));
@@ -3766,22 +3766,22 @@ function updateLocalGeminiCredentials(tokens) {
3766
3766
  }
3767
3767
 
3768
3768
  function getProjectPath(workingDirectory, claudeConfigDirOverride) {
3769
- const projectId = path.resolve(workingDirectory).replace(/[^a-zA-Z0-9-]/g, "-");
3769
+ const projectId = node_path.resolve(workingDirectory).replace(/[^a-zA-Z0-9-]/g, "-");
3770
3770
  const claudeConfigDirRaw = process.env.CLAUDE_CONFIG_DIR ?? "";
3771
3771
  const claudeConfigDirTrimmed = claudeConfigDirRaw.trim();
3772
- const claudeConfigDir = claudeConfigDirTrimmed ? claudeConfigDirTrimmed : path.join(os.homedir(), ".claude");
3773
- return path.join(claudeConfigDir, "projects", projectId);
3772
+ const claudeConfigDir = claudeConfigDirTrimmed ? claudeConfigDirTrimmed : node_path.join(os.homedir(), ".claude");
3773
+ return node_path.join(claudeConfigDir, "projects", projectId);
3774
3774
  }
3775
3775
 
3776
- function claudeCheckSession(sessionId, path$1, transcriptPath) {
3777
- const projectDir = getProjectPath(path$1);
3778
- const sessionFile = transcriptPath ?? path.join(projectDir, `${sessionId}.jsonl`);
3779
- const sessionExists = fs.existsSync(sessionFile);
3776
+ function claudeCheckSession(sessionId, path, transcriptPath) {
3777
+ const projectDir = getProjectPath(path);
3778
+ const sessionFile = transcriptPath ?? node_path.join(projectDir, `${sessionId}.jsonl`);
3779
+ const sessionExists = node_fs.existsSync(sessionFile);
3780
3780
  if (!sessionExists) {
3781
3781
  api.logger.debug(`[claudeCheckSession] Path ${sessionFile} does not exist`);
3782
3782
  return false;
3783
3783
  }
3784
- const sessionData = fs.readFileSync(sessionFile, "utf-8").split("\n");
3784
+ const sessionData = node_fs.readFileSync(sessionFile, "utf-8").split("\n");
3785
3785
  const hasGoodMessage = !!sessionData.find((v, index) => {
3786
3786
  if (!v.trim()) return false;
3787
3787
  try {
@@ -3802,7 +3802,7 @@ function claudeFindLastSession(workingDirectory) {
3802
3802
  try {
3803
3803
  const projectDir = getProjectPath(workingDirectory);
3804
3804
  const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
3805
- const files = fs.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).map((f) => {
3805
+ const files = node_fs.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).map((f) => {
3806
3806
  const sessionId = f.replace(".jsonl", "");
3807
3807
  if (!uuidPattern.test(sessionId)) {
3808
3808
  return null;
@@ -3811,7 +3811,7 @@ function claudeFindLastSession(workingDirectory) {
3811
3811
  return {
3812
3812
  name: f,
3813
3813
  sessionId,
3814
- mtime: fs.statSync(path.join(projectDir, f)).mtime.getTime()
3814
+ mtime: node_fs.statSync(node_path.join(projectDir, f)).mtime.getTime()
3815
3815
  };
3816
3816
  }
3817
3817
  return null;
@@ -3831,10 +3831,10 @@ class ExitCodeError extends Error {
3831
3831
  this.exitCode = exitCode;
3832
3832
  }
3833
3833
  }
3834
- const claudeCliPath = path.resolve(path.join(projectPath(), "scripts", "claude_local_launcher.cjs"));
3834
+ const claudeCliPath = node_path.resolve(node_path.join(projectPath(), "scripts", "claude_local_launcher.cjs"));
3835
3835
  async function claudeLocal(opts) {
3836
3836
  const projectDir = getProjectPath(opts.path);
3837
- fs.mkdirSync(projectDir, { recursive: true });
3837
+ node_fs.mkdirSync(projectDir, { recursive: true });
3838
3838
  const hasContinueFlag = opts.claudeArgs?.includes("--continue");
3839
3839
  const hasResumeFlag = opts.claudeArgs?.includes("--resume");
3840
3840
  const hasUserSessionControl = hasContinueFlag || hasResumeFlag;
@@ -3953,7 +3953,7 @@ async function claudeLocal(opts) {
3953
3953
  args.push("--settings", opts.hookSettingsPath);
3954
3954
  api.logger.debug(`[ClaudeLocal] Using hook settings: ${opts.hookSettingsPath}`);
3955
3955
  }
3956
- if (!claudeCliPath || !fs.existsSync(claudeCliPath)) {
3956
+ if (!claudeCliPath || !node_fs.existsSync(claudeCliPath)) {
3957
3957
  throw new Error("Claude local launcher not found. Please ensure HAPPY_PROJECT_ROOT is set correctly for development.");
3958
3958
  }
3959
3959
  const env = {
@@ -4527,6 +4527,107 @@ function parseArgsFromContent(content) {
4527
4527
  }
4528
4528
  return {};
4529
4529
  }
4530
+ function appendToolOutput(existing, next) {
4531
+ if (!existing || existing.length === 0) {
4532
+ return next;
4533
+ }
4534
+ if (next === existing || existing.endsWith(next)) {
4535
+ return existing;
4536
+ }
4537
+ if (next.startsWith(existing)) {
4538
+ return next;
4539
+ }
4540
+ return `${existing}${next}`;
4541
+ }
4542
+ function isRecord(value) {
4543
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4544
+ }
4545
+ function hasMeaningfulContent(value) {
4546
+ if (value === null || value === void 0) {
4547
+ return false;
4548
+ }
4549
+ if (typeof value === "string") {
4550
+ return value.length > 0;
4551
+ }
4552
+ if (Array.isArray(value)) {
4553
+ return value.length > 0;
4554
+ }
4555
+ if (isRecord(value)) {
4556
+ return Object.keys(value).length > 0;
4557
+ }
4558
+ return true;
4559
+ }
4560
+ function looksLikeToolMetadata(record) {
4561
+ const metadataKeys = [
4562
+ "command",
4563
+ "cmd",
4564
+ "script",
4565
+ "argv",
4566
+ "cwd",
4567
+ "workingDirectory",
4568
+ "description",
4569
+ "title",
4570
+ "parsed_cmd"
4571
+ ];
4572
+ if (metadataKeys.some((key) => key in record)) {
4573
+ return true;
4574
+ }
4575
+ const nestedKeys = ["input", "toolCall", "arguments", "content"];
4576
+ for (const key of nestedKeys) {
4577
+ const nested = record[key];
4578
+ if (isRecord(nested) && looksLikeToolMetadata(nested)) {
4579
+ return true;
4580
+ }
4581
+ }
4582
+ return false;
4583
+ }
4584
+ function extractToolOutputChunk(content) {
4585
+ if (typeof content === "string") {
4586
+ return content.length > 0 ? content : null;
4587
+ }
4588
+ if (Array.isArray(content)) {
4589
+ const parts = content.map((item) => extractToolOutputChunk(item)).filter((item) => Boolean(item));
4590
+ return parts.length > 0 ? parts.join("") : null;
4591
+ }
4592
+ if (!isRecord(content)) {
4593
+ return null;
4594
+ }
4595
+ const outputKeys = ["stdout", "stderr", "output", "text", "message", "data", "error", "reason"];
4596
+ const hasOutputKey = outputKeys.some((key) => key in content);
4597
+ if (!hasOutputKey && looksLikeToolMetadata(content)) {
4598
+ return null;
4599
+ }
4600
+ for (const key of outputKeys) {
4601
+ if (!(key in content)) {
4602
+ continue;
4603
+ }
4604
+ const value = content[key];
4605
+ const formatted2 = typeof value === "string" ? value : formatDisplayMessage(value);
4606
+ if (formatted2.length > 0) {
4607
+ return formatted2;
4608
+ }
4609
+ }
4610
+ const formatted = formatDisplayMessage(content);
4611
+ return formatted.length > 0 ? formatted : null;
4612
+ }
4613
+ function mergeStreamedOutputWithResult(content, streamedOutput) {
4614
+ if (!streamedOutput || streamedOutput.length === 0) {
4615
+ return content;
4616
+ }
4617
+ if (!hasMeaningfulContent(content)) {
4618
+ return streamedOutput;
4619
+ }
4620
+ if (isRecord(content)) {
4621
+ const hasStructuredOutput = ["stdout", "stderr", "output", "text", "message", "data"].some((key) => key in content);
4622
+ if (!hasStructuredOutput) {
4623
+ return {
4624
+ ...content,
4625
+ stdout: streamedOutput
4626
+ };
4627
+ }
4628
+ }
4629
+ return content;
4630
+ }
4530
4631
  function extractErrorDetail(content) {
4531
4632
  if (!content) return void 0;
4532
4633
  if (typeof content === "string") {
@@ -4674,11 +4775,13 @@ function completeToolCall(toolCallId, toolKind, content, ctx) {
4674
4775
  clearTimeout(timeout);
4675
4776
  ctx.toolCallTimeouts.delete(toolCallId);
4676
4777
  }
4778
+ const streamedOutput = ctx.toolCallOutputs.get(toolCallId);
4779
+ ctx.toolCallOutputs.delete(toolCallId);
4677
4780
  api.logger.debug(`[AcpBackend] \u2705 Tool call COMPLETED: ${toolCallId} (${toolKindStr}) - Duration: ${duration}. Active tool calls: ${ctx.activeToolCalls.size}`);
4678
4781
  ctx.emit({
4679
4782
  type: "tool-result",
4680
4783
  toolName: toolKindStr,
4681
- result: content,
4784
+ result: mergeStreamedOutputWithResult(content, streamedOutput),
4682
4785
  callId: toolCallId
4683
4786
  });
4684
4787
  if (ctx.activeToolCalls.size === 0) {
@@ -4720,6 +4823,8 @@ function failToolCall(toolCallId, status, toolKind, content, ctx) {
4720
4823
  }
4721
4824
  const durationStr = formatDuration(startTime);
4722
4825
  api.logger.debug(`[AcpBackend] \u274C Tool call ${status.toUpperCase()}: ${toolCallId} (${toolKindStr}) - Duration: ${durationStr}. Active tool calls: ${ctx.activeToolCalls.size}`);
4826
+ const streamedOutput = ctx.toolCallOutputs.get(toolCallId);
4827
+ ctx.toolCallOutputs.delete(toolCallId);
4723
4828
  const errorDetail = extractErrorDetail(content);
4724
4829
  if (errorDetail) {
4725
4830
  api.logger.debug(`[AcpBackend] \u274C Tool call error details: ${errorDetail.substring(0, 500)}`);
@@ -4729,7 +4834,11 @@ function failToolCall(toolCallId, status, toolKind, content, ctx) {
4729
4834
  ctx.emit({
4730
4835
  type: "tool-result",
4731
4836
  toolName: toolKindStr,
4732
- result: errorDetail ? { error: errorDetail, status } : { error: `Tool call ${status}`, status },
4837
+ result: streamedOutput ? {
4838
+ stdout: streamedOutput,
4839
+ error: errorDetail || `Tool call ${status}`,
4840
+ status
4841
+ } : errorDetail ? { error: errorDetail, status } : { error: `Tool call ${status}`, status },
4733
4842
  callId: toolCallId
4734
4843
  });
4735
4844
  if (ctx.activeToolCalls.size === 0) {
@@ -4745,8 +4854,13 @@ function handleToolCallUpdate(update, ctx) {
4745
4854
  api.logger.debug("[AcpBackend] Tool call update without toolCallId:", update);
4746
4855
  return { handled: false };
4747
4856
  }
4748
- const toolKind = update.kind || "unknown";
4857
+ const toolKind = update.kind || ctx.toolCallIdToNameMap.get(toolCallId) || "unknown";
4749
4858
  let toolCallCountSincePrompt = ctx.toolCallCountSincePrompt;
4859
+ const outputChunk = extractToolOutputChunk(update.content);
4860
+ if (outputChunk) {
4861
+ const nextOutput = appendToolOutput(ctx.toolCallOutputs.get(toolCallId), outputChunk);
4862
+ ctx.toolCallOutputs.set(toolCallId, nextOutput);
4863
+ }
4750
4864
  if (status === "in_progress" || status === "pending") {
4751
4865
  if (!ctx.activeToolCalls.has(toolCallId)) {
4752
4866
  toolCallCountSincePrompt++;
@@ -4995,6 +5109,11 @@ function normalizeAcpError(error) {
4995
5109
  }
4996
5110
  return normalized;
4997
5111
  }
5112
+ function createAcpAbortError(message) {
5113
+ const error = new Error(message);
5114
+ error.name = "AbortError";
5115
+ return error;
5116
+ }
4998
5117
  function enrichAcpError(error, stderrExcerpt) {
4999
5118
  const normalized = normalizeAcpError(error);
5000
5119
  if (!stderrExcerpt.trim()) {
@@ -5021,6 +5140,8 @@ class AcpBackend {
5021
5140
  toolCallTimeouts = /* @__PURE__ */ new Map();
5022
5141
  /** Track tool call start times for performance monitoring */
5023
5142
  toolCallStartTimes = /* @__PURE__ */ new Map();
5143
+ /** Track streamed tool output between ACP updates and final completion */
5144
+ toolCallOutputs = /* @__PURE__ */ new Map();
5024
5145
  /** Pending permission requests that need response */
5025
5146
  pendingPermissions = /* @__PURE__ */ new Map();
5026
5147
  /** Map from permission request ID to real tool call ID for tracking */
@@ -5031,6 +5152,14 @@ class AcpBackend {
5031
5152
  toolCallCountSincePrompt = 0;
5032
5153
  /** Timeout for emitting 'idle' status after last message chunk */
5033
5154
  idleTimeout = null;
5155
+ /** Promise resolver for waitForResponseComplete */
5156
+ idleResolver = null;
5157
+ /** Promise rejecter for waitForResponseComplete */
5158
+ idleRejecter = null;
5159
+ /** Completion signal captured before waitForResponseComplete is attached */
5160
+ responseCompletionOutcome = null;
5161
+ /** Whether the current prompt is still waiting for completion */
5162
+ waitingForResponse = false;
5034
5163
  /** Transport handler for agent-specific behavior */
5035
5164
  transport;
5036
5165
  /** Keep a short rolling stderr buffer so startup failures can surface the real cause. */
@@ -5048,6 +5177,44 @@ class AcpBackend {
5048
5177
  getRecentStderrExcerpt() {
5049
5178
  return this.recentStderrLines.slice(-6).join("\n");
5050
5179
  }
5180
+ clearIdleTimeoutState() {
5181
+ if (this.idleTimeout) {
5182
+ clearTimeout(this.idleTimeout);
5183
+ this.idleTimeout = null;
5184
+ }
5185
+ }
5186
+ clearToolCallTracking() {
5187
+ this.activeToolCalls.clear();
5188
+ for (const timeout of this.toolCallTimeouts.values()) {
5189
+ clearTimeout(timeout);
5190
+ }
5191
+ this.toolCallTimeouts.clear();
5192
+ this.toolCallStartTimes.clear();
5193
+ this.toolCallIdToNameMap.clear();
5194
+ this.toolCallOutputs.clear();
5195
+ this.toolCallCountSincePrompt = 0;
5196
+ }
5197
+ resetResponseTrackingForNewPrompt() {
5198
+ this.responseCompletionOutcome = null;
5199
+ this.clearIdleTimeoutState();
5200
+ this.clearToolCallTracking();
5201
+ }
5202
+ settleResponseWaiter(outcome) {
5203
+ const hasActiveWaiter = Boolean(this.idleResolver || this.idleRejecter);
5204
+ if (!this.waitingForResponse && !hasActiveWaiter) {
5205
+ return;
5206
+ }
5207
+ if (!hasActiveWaiter) {
5208
+ this.waitingForResponse = false;
5209
+ this.responseCompletionOutcome = outcome;
5210
+ return;
5211
+ }
5212
+ if (outcome.kind === "resolved") {
5213
+ this.idleResolver?.();
5214
+ return;
5215
+ }
5216
+ this.idleRejecter?.(outcome.error);
5217
+ }
5051
5218
  onMessage(handler) {
5052
5219
  this.listeners.push(handler);
5053
5220
  }
@@ -5122,10 +5289,15 @@ class AcpBackend {
5122
5289
  });
5123
5290
  this.process.on("error", (err) => {
5124
5291
  api.logger.debug(`[AcpBackend] Process error:`, err);
5292
+ this.settleResponseWaiter({ kind: "rejected", error: err });
5125
5293
  this.emit({ type: "status", status: "error", detail: err.message });
5126
5294
  });
5127
5295
  this.process.on("exit", (code, signal) => {
5128
5296
  if (!this.disposed && code !== 0 && code !== null) {
5297
+ this.settleResponseWaiter({
5298
+ kind: "rejected",
5299
+ error: new Error(`ACP process exited with code ${code}${signal ? ` (${signal})` : ""}`)
5300
+ });
5129
5301
  api.logger.debug(`[AcpBackend] Process exited with code ${code}, signal ${signal}`);
5130
5302
  this.emit({ type: "status", status: "stopped", detail: `Exit code: ${code}` });
5131
5303
  }
@@ -5456,6 +5628,7 @@ class AcpBackend {
5456
5628
  toolCallStartTimes: this.toolCallStartTimes,
5457
5629
  toolCallTimeouts: this.toolCallTimeouts,
5458
5630
  toolCallIdToNameMap: this.toolCallIdToNameMap,
5631
+ toolCallOutputs: this.toolCallOutputs,
5459
5632
  idleTimeout: this.idleTimeout,
5460
5633
  toolCallCountSincePrompt: this.toolCallCountSincePrompt,
5461
5634
  emit: (msg) => this.emit(msg),
@@ -5532,20 +5705,24 @@ class AcpBackend {
5532
5705
  this.emitUsageTelemetry(update, "acp-usage-update");
5533
5706
  continue;
5534
5707
  }
5708
+ if (sessionUpdateType === "task_complete") {
5709
+ this.emitUsageTelemetry(update.usage, "acp-session-usage");
5710
+ ctx.clearIdleTimeout();
5711
+ api.logger.debug("[AcpBackend] task_complete received, emitting idle status");
5712
+ this.emitIdleStatus();
5713
+ continue;
5714
+ }
5535
5715
  const handledLegacy = handleLegacyMessageChunk(update, ctx).handled;
5536
5716
  const handledPlan = handlePlanUpdate(update, ctx).handled;
5537
5717
  const handledThinking = handleThinkingUpdate(update, ctx).handled;
5538
5718
  const handledUsage = this.emitUsageTelemetry(update.usage, "acp-session-usage");
5539
5719
  const updateTypeStr = sessionUpdateType;
5540
- const handledTypes = ["agent_message_chunk", "tool_call_update", "agent_thought_chunk", "tool_call", "usage_update"];
5720
+ const handledTypes = ["agent_message_chunk", "tool_call_update", "agent_thought_chunk", "tool_call", "usage_update", "task_complete"];
5541
5721
  if (updateTypeStr && !handledTypes.includes(updateTypeStr) && !handledLegacy && !handledPlan && !handledThinking && !handledUsage) {
5542
5722
  api.logger.debug(`[AcpBackend] Unhandled session update type: ${updateTypeStr}`, JSON.stringify(update, null, 2));
5543
5723
  }
5544
5724
  }
5545
5725
  }
5546
- // Promise resolver for waitForIdle - set when waiting for response to complete
5547
- idleResolver = null;
5548
- waitingForResponse = false;
5549
5726
  async sendPrompt(sessionId, prompt) {
5550
5727
  this.toolCallCountSincePrompt = 0;
5551
5728
  if (this.disposed) {
@@ -5554,6 +5731,7 @@ class AcpBackend {
5554
5731
  if (!this.connection || !this.acpSessionId) {
5555
5732
  throw new Error("Session not started");
5556
5733
  }
5734
+ this.resetResponseTrackingForNewPrompt();
5557
5735
  this.emit({ type: "status", status: "running" });
5558
5736
  this.waitingForResponse = true;
5559
5737
  try {
@@ -5572,7 +5750,6 @@ class AcpBackend {
5572
5750
  api.logger.debug("[AcpBackend] Prompt request sent to ACP connection");
5573
5751
  } catch (error) {
5574
5752
  api.logger.debug("[AcpBackend] Error sending prompt:", error);
5575
- this.waitingForResponse = false;
5576
5753
  let errorDetail;
5577
5754
  if (error instanceof Error) {
5578
5755
  errorDetail = error.message;
@@ -5586,6 +5763,10 @@ class AcpBackend {
5586
5763
  status: "error",
5587
5764
  detail: errorDetail
5588
5765
  });
5766
+ this.settleResponseWaiter({
5767
+ kind: "rejected",
5768
+ error: error instanceof Error ? error : normalizeAcpError(error)
5769
+ });
5589
5770
  throw error;
5590
5771
  }
5591
5772
  }
@@ -5594,21 +5775,38 @@ class AcpBackend {
5594
5775
  * Call this after sendPrompt to wait for Gemini to finish responding
5595
5776
  */
5596
5777
  async waitForResponseComplete(timeoutMs = 12e4) {
5778
+ const pendingOutcome = this.responseCompletionOutcome;
5779
+ if (pendingOutcome) {
5780
+ this.responseCompletionOutcome = null;
5781
+ if (pendingOutcome.kind === "rejected") {
5782
+ throw pendingOutcome.error;
5783
+ }
5784
+ return;
5785
+ }
5597
5786
  if (!this.waitingForResponse) {
5598
5787
  return;
5599
5788
  }
5600
5789
  return new Promise((resolve, reject) => {
5601
5790
  const timeout = setTimeout(() => {
5602
5791
  this.idleResolver = null;
5792
+ this.idleRejecter = null;
5603
5793
  this.waitingForResponse = false;
5604
5794
  reject(new Error("Timeout waiting for response to complete"));
5605
5795
  }, timeoutMs);
5606
5796
  this.idleResolver = () => {
5607
5797
  clearTimeout(timeout);
5608
5798
  this.idleResolver = null;
5799
+ this.idleRejecter = null;
5609
5800
  this.waitingForResponse = false;
5610
5801
  resolve();
5611
5802
  };
5803
+ this.idleRejecter = (error) => {
5804
+ clearTimeout(timeout);
5805
+ this.idleResolver = null;
5806
+ this.idleRejecter = null;
5807
+ this.waitingForResponse = false;
5808
+ reject(error);
5809
+ };
5612
5810
  });
5613
5811
  }
5614
5812
  /**
@@ -5616,18 +5814,19 @@ class AcpBackend {
5616
5814
  */
5617
5815
  emitIdleStatus() {
5618
5816
  this.emit({ type: "status", status: "idle" });
5619
- if (this.idleResolver) {
5620
- api.logger.debug("[AcpBackend] Resolving idle waiter");
5621
- this.idleResolver();
5622
- }
5817
+ this.settleResponseWaiter({ kind: "resolved" });
5623
5818
  }
5624
5819
  async cancel(sessionId) {
5820
+ const cancelError = createAcpAbortError("Cancelled by user");
5821
+ this.clearIdleTimeoutState();
5822
+ this.clearToolCallTracking();
5823
+ this.settleResponseWaiter({ kind: "rejected", error: cancelError });
5824
+ this.emit({ type: "status", status: "stopped", detail: "Cancelled by user" });
5625
5825
  if (!this.connection || !this.acpSessionId) {
5626
5826
  return;
5627
5827
  }
5628
5828
  try {
5629
5829
  await this.connection.cancel({ sessionId: this.acpSessionId });
5630
- this.emit({ type: "status", status: "stopped", detail: "Cancelled by user" });
5631
5830
  } catch (error) {
5632
5831
  api.logger.debug("[AcpBackend] Error cancelling:", error);
5633
5832
  }
@@ -5655,6 +5854,10 @@ class AcpBackend {
5655
5854
  if (this.disposed) return;
5656
5855
  api.logger.debug("[AcpBackend] Disposing backend");
5657
5856
  this.disposed = true;
5857
+ this.settleResponseWaiter({
5858
+ kind: "rejected",
5859
+ error: createAcpAbortError("ACP backend disposed")
5860
+ });
5658
5861
  if (this.connection && this.acpSessionId) {
5659
5862
  try {
5660
5863
  await Promise.race([
@@ -5683,19 +5886,11 @@ class AcpBackend {
5683
5886
  });
5684
5887
  this.process = null;
5685
5888
  }
5686
- if (this.idleTimeout) {
5687
- clearTimeout(this.idleTimeout);
5688
- this.idleTimeout = null;
5689
- }
5889
+ this.clearIdleTimeoutState();
5690
5890
  this.listeners = [];
5691
5891
  this.connection = null;
5692
5892
  this.acpSessionId = null;
5693
- this.activeToolCalls.clear();
5694
- for (const timeout of this.toolCallTimeouts.values()) {
5695
- clearTimeout(timeout);
5696
- }
5697
- this.toolCallTimeouts.clear();
5698
- this.toolCallStartTimes.clear();
5893
+ this.clearToolCallTracking();
5699
5894
  this.pendingPermissions.clear();
5700
5895
  }
5701
5896
  }
@@ -5711,17 +5906,17 @@ function readGeminiLocalConfig() {
5711
5906
  let googleCloudProject = null;
5712
5907
  let googleCloudProjectEmail = null;
5713
5908
  const possiblePaths = [
5714
- path$1.join(os$1.homedir(), ".gemini", "oauth_creds.json"),
5909
+ path.join(os$1.homedir(), ".gemini", "oauth_creds.json"),
5715
5910
  // Main OAuth credentials file
5716
- path$1.join(os$1.homedir(), ".gemini", "config.json"),
5717
- path$1.join(os$1.homedir(), ".config", "gemini", "config.json"),
5718
- path$1.join(os$1.homedir(), ".gemini", "auth.json"),
5719
- path$1.join(os$1.homedir(), ".config", "gemini", "auth.json")
5911
+ path.join(os$1.homedir(), ".gemini", "config.json"),
5912
+ path.join(os$1.homedir(), ".config", "gemini", "config.json"),
5913
+ path.join(os$1.homedir(), ".gemini", "auth.json"),
5914
+ path.join(os$1.homedir(), ".config", "gemini", "auth.json")
5720
5915
  ];
5721
5916
  for (const configPath of possiblePaths) {
5722
- if (fs$1.existsSync(configPath)) {
5917
+ if (fs.existsSync(configPath)) {
5723
5918
  try {
5724
- const config = JSON.parse(fs$1.readFileSync(configPath, "utf-8"));
5919
+ const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
5725
5920
  if (!token) {
5726
5921
  const foundToken = config.access_token || config.token || config.apiKey || config.GEMINI_API_KEY;
5727
5922
  if (foundToken && typeof foundToken === "string") {
@@ -5793,22 +5988,22 @@ function determineGeminiModel(explicitModel, localConfig) {
5793
5988
  }
5794
5989
  function saveGeminiModelToConfig(model) {
5795
5990
  try {
5796
- const configDir = path$1.join(os$1.homedir(), ".gemini");
5797
- const configPath = path$1.join(configDir, "config.json");
5798
- if (!fs$1.existsSync(configDir)) {
5799
- fs$1.mkdirSync(configDir, { recursive: true });
5991
+ const configDir = path.join(os$1.homedir(), ".gemini");
5992
+ const configPath = path.join(configDir, "config.json");
5993
+ if (!fs.existsSync(configDir)) {
5994
+ fs.mkdirSync(configDir, { recursive: true });
5800
5995
  }
5801
5996
  let config = {};
5802
- if (fs$1.existsSync(configPath)) {
5997
+ if (fs.existsSync(configPath)) {
5803
5998
  try {
5804
- config = JSON.parse(fs$1.readFileSync(configPath, "utf-8"));
5999
+ config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
5805
6000
  } catch (error) {
5806
6001
  api.logger.debug(`[Gemini] Failed to read existing config, creating new one`);
5807
6002
  config = {};
5808
6003
  }
5809
6004
  }
5810
6005
  config.model = model;
5811
- fs$1.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
6006
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
5812
6007
  api.logger.debug(`[Gemini] Saved model "${model}" to ${configPath}`);
5813
6008
  } catch (error) {
5814
6009
  api.logger.debug(`[Gemini] Failed to save model to config:`, error);
@@ -5816,15 +6011,15 @@ function saveGeminiModelToConfig(model) {
5816
6011
  }
5817
6012
  function saveGoogleCloudProjectToConfig(projectId, email) {
5818
6013
  try {
5819
- const configDir = path$1.join(os$1.homedir(), ".gemini");
5820
- const configPath = path$1.join(configDir, "config.json");
5821
- if (!fs$1.existsSync(configDir)) {
5822
- fs$1.mkdirSync(configDir, { recursive: true });
6014
+ const configDir = path.join(os$1.homedir(), ".gemini");
6015
+ const configPath = path.join(configDir, "config.json");
6016
+ if (!fs.existsSync(configDir)) {
6017
+ fs.mkdirSync(configDir, { recursive: true });
5823
6018
  }
5824
6019
  let config = {};
5825
- if (fs$1.existsSync(configPath)) {
6020
+ if (fs.existsSync(configPath)) {
5826
6021
  try {
5827
- config = JSON.parse(fs$1.readFileSync(configPath, "utf-8"));
6022
+ config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
5828
6023
  } catch {
5829
6024
  config = {};
5830
6025
  }
@@ -5833,7 +6028,7 @@ function saveGoogleCloudProjectToConfig(projectId, email) {
5833
6028
  if (email) {
5834
6029
  config.googleCloudProjectEmail = email;
5835
6030
  }
5836
- fs$1.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
6031
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
5837
6032
  api.logger.debug(`[Gemini] Saved Google Cloud Project "${projectId}"${email ? ` for ${email}` : ""} to ${configPath}`);
5838
6033
  } catch (error) {
5839
6034
  api.logger.debug(`[Gemini] Failed to save Google Cloud Project to config:`, error);
@@ -5940,11 +6135,11 @@ function readFirstEnv(...names) {
5940
6135
  return "";
5941
6136
  }
5942
6137
  function normalizeCommandPath(command) {
5943
- if (path.isAbsolute(command)) {
6138
+ if (node_path.isAbsolute(command)) {
5944
6139
  return command;
5945
6140
  }
5946
- const resolved = path.resolve(process.cwd(), command);
5947
- return fs.existsSync(resolved) ? resolved : command;
6141
+ const resolved = node_path.resolve(process.cwd(), command);
6142
+ return node_fs.existsSync(resolved) ? resolved : command;
5948
6143
  }
5949
6144
  function resolveCommandOnPath(command) {
5950
6145
  const pathValue = typeof process.env.PATH === "string" ? process.env.PATH : "";
@@ -5952,13 +6147,13 @@ function resolveCommandOnPath(command) {
5952
6147
  return null;
5953
6148
  }
5954
6149
  const extensions = process.platform === "win32" ? (process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD").split(";").map((value) => value.trim().toLowerCase()).filter(Boolean) : [""];
5955
- for (const dir of pathValue.split(path.delimiter)) {
6150
+ for (const dir of pathValue.split(node_path.delimiter)) {
5956
6151
  const trimmedDir = dir.trim();
5957
6152
  if (!trimmedDir) {
5958
6153
  continue;
5959
6154
  }
5960
- const directCandidate = path.join(trimmedDir, command);
5961
- if (fs.existsSync(directCandidate)) {
6155
+ const directCandidate = node_path.join(trimmedDir, command);
6156
+ if (node_fs.existsSync(directCandidate)) {
5962
6157
  return directCandidate;
5963
6158
  }
5964
6159
  if (process.platform !== "win32") {
@@ -5969,8 +6164,8 @@ function resolveCommandOnPath(command) {
5969
6164
  continue;
5970
6165
  }
5971
6166
  for (const extension of extensions) {
5972
- const candidate = path.join(trimmedDir, `${command}${extension.toLowerCase()}`);
5973
- if (fs.existsSync(candidate)) {
6167
+ const candidate = node_path.join(trimmedDir, `${command}${extension.toLowerCase()}`);
6168
+ if (node_fs.existsSync(candidate)) {
5974
6169
  return candidate;
5975
6170
  }
5976
6171
  }
@@ -6065,8 +6260,8 @@ function validateCodexAcpSpawn(options = {}) {
6065
6260
  const normalizedCommand = spawn.command.trim();
6066
6261
  const commandLower = normalizedCommand.toLowerCase();
6067
6262
  const npxMode = readCodexAcpNpxMode();
6068
- if (path.isAbsolute(normalizedCommand)) {
6069
- if (!fs.existsSync(normalizedCommand)) {
6263
+ if (node_path.isAbsolute(normalizedCommand)) {
6264
+ if (!node_fs.existsSync(normalizedCommand)) {
6070
6265
  return {
6071
6266
  ok: false,
6072
6267
  errorMessage: `Codex ACP is enabled, but the resolved command does not exist: ${normalizedCommand}`
@@ -6336,12 +6531,12 @@ async function ensureUnifiedDaemonStarted() {
6336
6531
  async function executeUnifiedProvider(opts) {
6337
6532
  const credentials = await ensureUnifiedRuntimePrerequisites(opts.credentials);
6338
6533
  if (opts.provider === "claude") {
6339
- const { runClaude } = await Promise.resolve().then(function () { return require('./runClaude-B-GNEkKg.cjs'); });
6534
+ const { runClaude } = await Promise.resolve().then(function () { return require('./runClaude-Dz-PCSvb.cjs'); });
6340
6535
  await runClaude(credentials, opts.claudeOptions ?? {});
6341
6536
  return;
6342
6537
  }
6343
6538
  if (opts.provider === "codex") {
6344
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-CPHyGwj9.cjs'); });
6539
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-BtZplK1R.cjs'); });
6345
6540
  await runCodex({
6346
6541
  credentials,
6347
6542
  startedBy: opts.startedBy,
@@ -6351,7 +6546,7 @@ async function executeUnifiedProvider(opts) {
6351
6546
  return;
6352
6547
  }
6353
6548
  if (opts.provider === "gemini") {
6354
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-DaDz1bzQ.cjs'); });
6549
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-DUyH311Z.cjs'); });
6355
6550
  await runGemini({
6356
6551
  credentials,
6357
6552
  startedBy: opts.startedBy
@@ -6393,7 +6588,7 @@ function shouldRunMainClaudeFlow(opts) {
6393
6588
  return;
6394
6589
  } else if (subcommand === "runtime") {
6395
6590
  if (args[1] === "providers") {
6396
- const { renderRuntimeProviders } = await Promise.resolve().then(function () { return require('./command-CVldr51S.cjs'); });
6591
+ const { renderRuntimeProviders } = await Promise.resolve().then(function () { return require('./command-CPlJKXDn.cjs'); });
6397
6592
  console.log(renderRuntimeProviders());
6398
6593
  return;
6399
6594
  }
@@ -6571,8 +6766,8 @@ function shouldRunMainClaudeFlow(opts) {
6571
6766
  const projectId = args[3];
6572
6767
  try {
6573
6768
  const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return config; });
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; });
6769
+ const { readCredentials: readCredentials2 } = await Promise.resolve().then(function () { return require('./persistence-BeFVx6kI.cjs'); });
6770
+ const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./api-CyJG1mr6.cjs'); }).then(function (n) { return n.api; });
6576
6771
  let userEmail = void 0;
6577
6772
  try {
6578
6773
  const credentials = await readCredentials2();
@@ -6735,7 +6930,7 @@ function shouldRunMainClaudeFlow(opts) {
6735
6930
  if (latest) {
6736
6931
  console.error(`Latest daemon log: ${latest.path}`);
6737
6932
  try {
6738
- const logContent = fs.readFileSync(latest.path, "utf-8");
6933
+ const logContent = node_fs.readFileSync(latest.path, "utf-8");
6739
6934
  if (logContent.includes("EADDRINUSE")) {
6740
6935
  console.error("Daemon control port is already in use. Retry after stopping the stale daemon or run `hicloud doctor clean`.");
6741
6936
  }