@zonease/happy 0.6.55 → 0.6.56

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 (83) hide show
  1. package/dist/{api-BH3mam5i.mjs → api-9wvM_aF-.mjs} +79 -67
  2. package/dist/{api-DvnXQWOp.cjs → api-BGc484qf.cjs} +73 -61
  3. package/dist/{auth-bwfaLx_V.cjs → auth-B6vskzfm.cjs} +2 -2
  4. package/dist/{auth-CpHjpbeh.mjs → auth-BnEa31tI.mjs} +2 -2
  5. package/dist/{auth-ByKWFjMR.cjs → auth-CPfJalJM.cjs} +4 -4
  6. package/dist/{auth-Pnzzbn_J.mjs → auth-DqAM-lIh.mjs} +4 -4
  7. package/dist/{browser-cQ-qyFyK.mjs → browser-CkQP96Zi.mjs} +1 -1
  8. package/dist/{browser-DFeQQh1Z.cjs → browser-CnxzD1lA.cjs} +1 -1
  9. package/dist/{claudeLocal-janZsvba.mjs → claudeLocal-B5uxtoit.mjs} +1 -1
  10. package/dist/{claudeLocal-BbxgreMw.cjs → claudeLocal-CV4fT0Gg.cjs} +1 -1
  11. package/dist/{config-DtmZpgs-.mjs → config-C9hdBdfj.mjs} +1 -1
  12. package/dist/{config-t5BrZndM.cjs → config-C__p7EWC.cjs} +1 -1
  13. package/dist/{connect-BLdoTnbu.mjs → connect-BeORCRXq.mjs} +5 -5
  14. package/dist/{connect-UD5a4ksC.cjs → connect-DQjpjfYn.cjs} +5 -5
  15. package/dist/{controlClient-DnZ5KouD.cjs → controlClient-DWBW6jRF.cjs} +1 -1
  16. package/dist/{controlClient-G7DPgAo_.mjs → controlClient-VY0CGL8k.mjs} +1 -1
  17. package/dist/{cursorApprovalHook-PYPX20zh.cjs → cursorApprovalHook-BuDSRM-6.cjs} +2 -2
  18. package/dist/{cursorApprovalHook-CTMySu-X.mjs → cursorApprovalHook-D_8btpsY.mjs} +2 -2
  19. package/dist/{cursorApprovalServer-D4A8D345.mjs → cursorApprovalServer-BOUd2-Fg.mjs} +1 -1
  20. package/dist/{cursorApprovalServer-GS3zs6kT.cjs → cursorApprovalServer-j9RphnEG.cjs} +1 -1
  21. package/dist/{deviceKeys-Cm1y7_pz.mjs → deviceKeys-DvfaTff3.mjs} +2 -2
  22. package/dist/{deviceKeys-U6p6bcVn.cjs → deviceKeys-c_sN01Mm.cjs} +2 -2
  23. package/dist/{doctor-CkqjpUrt.cjs → doctor-CD46A-_Y.cjs} +2 -2
  24. package/dist/{doctor-B95V4_1U.mjs → doctor-DQtQbfG-.mjs} +2 -2
  25. package/dist/{downloadImage-B3U4jFKu.mjs → downloadImage-B6A4x8Jw.mjs} +1 -1
  26. package/dist/{downloadImage-Bii91OZ_.cjs → downloadImage-DGdHCFi3.cjs} +1 -1
  27. package/dist/{enroll-CLUgsuwD.mjs → enroll-CyHWNKNt.mjs} +3 -3
  28. package/dist/{enroll-Cm8yPrRX.cjs → enroll-D9CEuRI_.cjs} +3 -3
  29. package/dist/{evidence-CVl2OOtE.mjs → evidence-BuYebdrN.mjs} +1 -1
  30. package/dist/{evidence-BaGuA4HW.cjs → evidence-CCrpzsTA.cjs} +1 -1
  31. package/dist/{formatImageMessage-Bel4ENzm.mjs → formatImageMessage-5qaaT_Wq.mjs} +1 -1
  32. package/dist/{formatImageMessage-Bv1f9KNc.cjs → formatImageMessage-DttKW75w.cjs} +1 -1
  33. package/dist/index.cjs +46 -46
  34. package/dist/index.mjs +46 -46
  35. package/dist/{install-ClBwOf9d.mjs → install-1Y6dAcMp.mjs} +1 -1
  36. package/dist/{install-D7tsFl0K.cjs → install-B0hT_tLv.cjs} +2 -2
  37. package/dist/{install-B9pgfnme.cjs → install-C4cwObCN.cjs} +1 -1
  38. package/dist/{install-cTiFm69E.mjs → install-eIXFuZbC.mjs} +2 -2
  39. package/dist/lib.cjs +6 -6
  40. package/dist/lib.mjs +6 -6
  41. package/dist/{loadableToolOutput-Dht_jeLW.mjs → loadableToolOutput-BKDTnyoF.mjs} +2 -2
  42. package/dist/{loadableToolOutput-BhhbJ2eK.cjs → loadableToolOutput-Cb-18__b.cjs} +2 -2
  43. package/dist/{persistence-uOLA4_LW.cjs → persistence-CNXsXPLm.cjs} +1 -1
  44. package/dist/{persistence-P3x0-3CX.mjs → persistence-IdEuIeMz.mjs} +1 -1
  45. package/dist/{push-avfOm7WX.cjs → push-XL6Sb0Vw.cjs} +6 -6
  46. package/dist/{push-xSbf2VWB.mjs → push-tXs96IyG.mjs} +6 -6
  47. package/dist/{registerKillSessionHandler-CPr_DB4J.cjs → registerKillSessionHandler-D9tmPdw5.cjs} +3 -3
  48. package/dist/{registerKillSessionHandler-CH06n_hZ.mjs → registerKillSessionHandler-vF5c8YZF.mjs} +3 -3
  49. package/dist/{run-DCo-Pmdx.cjs → run-BKfeeheJ.cjs} +8 -8
  50. package/dist/{run-B8aBVINE.mjs → run-BvpCwXkt.mjs} +8 -8
  51. package/dist/{runClaude-BJVGCnIq.mjs → runClaude-BiVqZQOm.mjs} +15 -15
  52. package/dist/{runClaude-CCb9FHWd.cjs → runClaude-DDsG7eMR.cjs} +16 -16
  53. package/dist/{runCodex-BhMBu81A.cjs → runCodex-Bh519-dW.cjs} +15 -15
  54. package/dist/{runCodex-LNIgWEiI.mjs → runCodex-C-8SvnpP.mjs} +15 -15
  55. package/dist/{runCursor-CSpoYRGe.mjs → runCursor-3AFNF0y2.mjs} +16 -16
  56. package/dist/{runCursor-C-FiInj_.cjs → runCursor-CYbvOqUa.cjs} +16 -16
  57. package/dist/{runGemini-DIPkJiUE.mjs → runGemini-Dh2JRfOJ.mjs} +19 -19
  58. package/dist/{runGemini-0H1Ug_k9.cjs → runGemini-ExHXGZBY.cjs} +19 -19
  59. package/dist/{runOneShot-BOkwPhAq.cjs → runOneShot-CEVKtkx_.cjs} +2 -2
  60. package/dist/{runOneShot-WB4vGRvF.mjs → runOneShot-CVcw-K0_.mjs} +2 -2
  61. package/dist/{serve-BTYQTNwH.mjs → serve-C4dOQ0jP.mjs} +6 -6
  62. package/dist/{serve-C-lQRc8J.cjs → serve-D0IhhySV.cjs} +6 -6
  63. package/dist/{session-BicrgWsg.mjs → session-CwMxRPXS.mjs} +5 -5
  64. package/dist/{session-CklyM25y.cjs → session-DK9eudJT.cjs} +5 -5
  65. package/dist/{sessionKeyCache-B_rg3Wj3.mjs → sessionKeyCache-DDzTs7E5.mjs} +1 -1
  66. package/dist/{sessionKeyCache-CCvSFqv3.cjs → sessionKeyCache-JjjYAxdf.cjs} +1 -1
  67. package/dist/{sessionList-BByWxuNb.cjs → sessionList-DZmmAP3q.cjs} +2 -2
  68. package/dist/{sessionList-D3G9cpfU.mjs → sessionList-IYAtPIev.mjs} +2 -2
  69. package/dist/{sessionSummary-B6L3dSgX.mjs → sessionSummary-CQQyTHRC.mjs} +3 -3
  70. package/dist/{sessionSummary-CvrWLmYX.cjs → sessionSummary-CsIfkyZA.cjs} +3 -3
  71. package/dist/{setupOfflineReconnection-Cw5gqUuo.mjs → setupOfflineReconnection-C1yzDMt6.mjs} +3 -3
  72. package/dist/{setupOfflineReconnection-wVhiCoQD.cjs → setupOfflineReconnection-DwtIEUeJ.cjs} +3 -3
  73. package/dist/{spawnHappyCLI-BjJuWvpg.cjs → spawnHappyCLI-BbMkZhMk.cjs} +1 -1
  74. package/dist/{spawnHappyCLI-Cf5Ox5XH.mjs → spawnHappyCLI-DlTg87jS.mjs} +1 -1
  75. package/dist/{ssh-KFiFQj5X.cjs → ssh-D31o750w.cjs} +5 -5
  76. package/dist/{ssh-O7AfLDRX.mjs → ssh-DSVjanff.mjs} +5 -5
  77. package/dist/{task-DKmGE82d.cjs → task--Apxd9oF.cjs} +6 -6
  78. package/dist/{task-CgYFAvIQ.mjs → task-D9ZjWCcw.mjs} +6 -6
  79. package/dist/{uninstall-DLXRIcDr.mjs → uninstall-Bo2uaLRP.mjs} +2 -2
  80. package/dist/{uninstall-24vmR3hW.cjs → uninstall-CZJcoC06.cjs} +2 -2
  81. package/dist/{update-Dv5yhg2A.mjs → update-BiV4YqG3.mjs} +3 -3
  82. package/dist/{update-CIbNnkrB.cjs → update-D-bTjP2k.cjs} +3 -3
  83. package/package.json +1 -1
@@ -1,20 +1,21 @@
1
1
  import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import axios from 'axios';
2
- import { l as logger, c as configuration, e as encodeBase64, f as encrypt, g as decrypt, h as decodeBase64, i as isDebug, B as encryptLegacy, a as readSettings, C as getRandomBytes, D as libsodiumEncryptForPublicKey } from './persistence-P3x0-3CX.mjs';
2
+ import { l as logger, c as configuration, e as encodeBase64, f as encrypt, g as decrypt, h as decodeBase64, i as isDebug, B as encryptLegacy, a as readSettings, C as getRandomBytes, D as libsodiumEncryptForPublicKey } from './persistence-IdEuIeMz.mjs';
3
3
  import { EventEmitter } from 'node:events';
4
4
  import { io } from 'socket.io-client';
5
5
  import { z } from 'zod';
6
6
  import './index-7P6T8CE4.mjs';
7
7
  import { b as backoff, e as exponentialBackoffDelay } from './time-DgsBLJA_.mjs';
8
8
  import { randomUUID, createHash } from 'node:crypto';
9
- import fs, { existsSync, readFileSync, writeFileSync, mkdirSync, statSync, readdirSync, mkdtempSync, chmodSync, createReadStream, createWriteStream, unlink as unlink$2, rmdirSync } from 'node:fs';
10
- import path, { join, dirname, resolve as resolve$1, basename } from 'node:path';
9
+ import path, { dirname, join, resolve as resolve$1, basename } from 'node:path';
10
+ import fs, { existsSync, createReadStream, statSync, readdirSync, mkdtempSync, writeFileSync, chmodSync, createWriteStream, unlink as unlink$2, rmdirSync } from 'node:fs';
11
+ import { mkdir, appendFile, readFile, rm, open, writeFile as writeFile$1, rename as rename$1, unlink as unlink$1, stat as stat$1, readdir as readdir$1, copyFile, cp } from 'node:fs/promises';
12
+ import { createInterface } from 'node:readline';
11
13
  import { spawn, execFile, execSync, execFileSync } from 'node:child_process';
12
- import { readFile, rm, open, writeFile as writeFile$1, rename as rename$1, unlink as unlink$1, stat as stat$1, readdir as readdir$1, copyFile, mkdir as mkdir$1, appendFile as appendFile$1, cp } from 'node:fs/promises';
13
14
  import os, { tmpdir, homedir } from 'node:os';
14
15
  import { promisify } from 'node:util';
15
16
  import { spawn as spawn$1, exec } from 'child_process';
16
17
  import { promisify as promisify$1 } from 'util';
17
- import { readFile as readFile$1, writeFile, mkdir, rm as rm$1, stat, appendFile, rename, lstat, unlink, readdir } from 'fs/promises';
18
+ import { readFile as readFile$1, writeFile, mkdir as mkdir$1, rm as rm$1, stat, appendFile as appendFile$1, rename, lstat, unlink, readdir } from 'fs/promises';
18
19
  import { resolve, join as join$1, dirname as dirname$1, sep } from 'path';
19
20
  import { p as projectPath } from './projectPath-BTBIMB57.mjs';
20
21
  import { createRequire } from 'node:module';
@@ -22,9 +23,8 @@ import WebSocket from 'ws';
22
23
  import { randomUUID as randomUUID$1 } from 'crypto';
23
24
  import tweetnacl from 'tweetnacl';
24
25
  import { encode, decode } from '@stablelib/base64';
25
- import { createInterface } from 'node:readline';
26
26
  import { Expo } from 'expo-server-sdk';
27
- import { c as cacheSessionKey } from './sessionKeyCache-B_rg3Wj3.mjs';
27
+ import { c as cacheSessionKey } from './sessionKeyCache-DDzTs7E5.mjs';
28
28
  import chalk from 'chalk';
29
29
 
30
30
  z.object({
@@ -232,41 +232,70 @@ class InvalidateSync {
232
232
  };
233
233
  }
234
234
 
235
- const diffsDir = join(configuration.happyHomeDir, "diffs");
236
- function ensureDiffsDir() {
237
- if (!existsSync(diffsDir)) {
238
- mkdirSync(diffsDir, { recursive: true });
239
- }
240
- }
241
- function getFilePath$1(sessionId) {
242
- return join(diffsDir, `${sessionId}.json`);
235
+ const pendingAppends = /* @__PURE__ */ new Map();
236
+ async function appendJsonLines(filePath, records) {
237
+ const data = records.map((record) => `${JSON.stringify(record)}
238
+ `).join("");
239
+ const previous = pendingAppends.get(filePath) ?? Promise.resolve();
240
+ const current = previous.then(async () => {
241
+ await mkdir(dirname(filePath), { recursive: true });
242
+ await appendFile(filePath, data, "utf-8");
243
+ });
244
+ const settled = current.catch(() => {
245
+ });
246
+ pendingAppends.set(filePath, settled);
247
+ void settled.then(() => {
248
+ if (pendingAppends.get(filePath) === settled) pendingAppends.delete(filePath);
249
+ });
250
+ return current;
243
251
  }
244
- function saveDiffRecords(sessionId, records) {
245
- if (records.length === 0) return;
252
+ async function findJsonLine(filePath, needle, match) {
253
+ await pendingAppends.get(filePath);
254
+ if (!existsSync(filePath)) return null;
255
+ const fileStream = createReadStream(filePath, { encoding: "utf8" });
256
+ const rl = createInterface({
257
+ input: fileStream,
258
+ crlfDelay: Infinity
259
+ });
246
260
  try {
247
- ensureDiffsDir();
248
- const filePath = getFilePath$1(sessionId);
249
- let existing = [];
250
- if (existsSync(filePath)) {
261
+ for await (const line of rl) {
262
+ if (!line.includes(needle)) continue;
251
263
  try {
252
- existing = JSON.parse(readFileSync(filePath, "utf-8"));
264
+ const record = JSON.parse(line);
265
+ if (match(record)) return record;
253
266
  } catch {
254
- existing = [];
255
267
  }
256
268
  }
257
- existing.push(...records);
258
- writeFileSync(filePath, JSON.stringify(existing), "utf-8");
259
- logger.debug(`[DiffStore] Saved ${records.length} record(s) for session ${sessionId}`);
260
- } catch (error) {
261
- logger.warn(`[DiffStore] Failed to save diff records:`, error);
269
+ return null;
270
+ } finally {
271
+ rl.close();
272
+ fileStream.destroy();
262
273
  }
263
274
  }
264
- function getDiffDetail(sessionId, callId, filePath) {
275
+ async function findInJsonArrayFile(filePath, match) {
276
+ if (!existsSync(filePath)) return null;
277
+ const records = JSON.parse(await readFile(filePath, "utf-8"));
278
+ return records.find(match) ?? null;
279
+ }
280
+
281
+ const diffsDir = join(configuration.happyHomeDir, "diffs");
282
+ function getFilePath$1(sessionId) {
283
+ return join(diffsDir, `${sessionId}.jsonl`);
284
+ }
285
+ function getLegacyFilePath$1(sessionId) {
286
+ return join(diffsDir, `${sessionId}.json`);
287
+ }
288
+ function saveDiffRecords(sessionId, records) {
289
+ if (records.length === 0) return;
290
+ appendJsonLines(getFilePath$1(sessionId), records).then(
291
+ () => logger.debug(`[DiffStore] Saved ${records.length} record(s) for session ${sessionId}`),
292
+ (error) => logger.warn(`[DiffStore] Failed to save diff records:`, error)
293
+ );
294
+ }
295
+ async function getDiffDetail(sessionId, callId, filePath) {
265
296
  try {
266
- const file = getFilePath$1(sessionId);
267
- if (!existsSync(file)) return null;
268
- const records = JSON.parse(readFileSync(file, "utf-8"));
269
- const record = records.find((r) => r.callId === callId && r.filePath === filePath);
297
+ const match = (r) => r.callId === callId && r.filePath === filePath;
298
+ const record = await findJsonLine(getFilePath$1(sessionId), JSON.stringify(callId), match) ?? await findInJsonArrayFile(getLegacyFilePath$1(sessionId), match);
270
299
  if (!record) return null;
271
300
  return { diff: record.diff, additions: record.additions, deletions: record.deletions };
272
301
  } catch (error) {
@@ -276,39 +305,22 @@ function getDiffDetail(sessionId, callId, filePath) {
276
305
  }
277
306
 
278
307
  const toolOutputsDir = join(configuration.happyHomeDir, "tool-outputs");
279
- function ensureToolOutputsDir() {
280
- if (!existsSync(toolOutputsDir)) {
281
- mkdirSync(toolOutputsDir, { recursive: true });
282
- }
283
- }
284
308
  function getFilePath(sessionId) {
309
+ return join(toolOutputsDir, `${sessionId}.jsonl`);
310
+ }
311
+ function getLegacyFilePath(sessionId) {
285
312
  return join(toolOutputsDir, `${sessionId}.json`);
286
313
  }
287
314
  function saveToolOutputRecord(sessionId, record) {
288
- try {
289
- ensureToolOutputsDir();
290
- const filePath = getFilePath(sessionId);
291
- let existing = [];
292
- if (existsSync(filePath)) {
293
- try {
294
- existing = JSON.parse(readFileSync(filePath, "utf-8"));
295
- } catch {
296
- existing = [];
297
- }
298
- }
299
- existing.push(record);
300
- writeFileSync(filePath, JSON.stringify(existing), "utf-8");
301
- logger.debug(`[ToolOutputStore] Saved output for ${record.toolName} (${record.callId}) in session ${sessionId}`);
302
- } catch (error) {
303
- logger.warn("[ToolOutputStore] Failed to save tool output record:", error);
304
- }
315
+ appendJsonLines(getFilePath(sessionId), [record]).then(
316
+ () => logger.debug(`[ToolOutputStore] Saved output for ${record.toolName} (${record.callId}) in session ${sessionId}`),
317
+ (error) => logger.warn("[ToolOutputStore] Failed to save tool output record:", error)
318
+ );
305
319
  }
306
- function getToolOutputRecord(sessionId, callId) {
320
+ async function getToolOutputRecord(sessionId, callId) {
307
321
  try {
308
- const filePath = getFilePath(sessionId);
309
- if (!existsSync(filePath)) return null;
310
- const records = JSON.parse(readFileSync(filePath, "utf-8"));
311
- return records.find((record) => record.callId === callId) || null;
322
+ const match = (record) => record.callId === callId;
323
+ return await findJsonLine(getFilePath(sessionId), JSON.stringify(callId), match) ?? await findInJsonArrayFile(getLegacyFilePath(sessionId), match);
312
324
  } catch (error) {
313
325
  logger.warn("[ToolOutputStore] Failed to get tool output record:", error);
314
326
  return null;
@@ -1846,7 +1858,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
1846
1858
  return { success: false, error: `Path '${paths.absolutePath}' is on the system write deny-list` };
1847
1859
  }
1848
1860
  try {
1849
- await mkdir(paths.directory, { recursive: true });
1861
+ await mkdir$1(paths.directory, { recursive: true });
1850
1862
  await rm$1(paths.tempAbsolutePath, { force: true });
1851
1863
  await rm$1(paths.absolutePath, { force: true });
1852
1864
  await writeFile(paths.tempAbsolutePath, Buffer.alloc(0));
@@ -1883,7 +1895,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
1883
1895
  if (currentSize + chunk.length > MAX_SESSION_UPLOAD_FILE_BYTES) {
1884
1896
  return { success: false, error: "File exceeds 100MB limit" };
1885
1897
  }
1886
- await appendFile(paths.tempAbsolutePath, chunk);
1898
+ await appendFile$1(paths.tempAbsolutePath, chunk);
1887
1899
  return {
1888
1900
  success: true,
1889
1901
  relativePath: paths.relativePath,
@@ -2080,7 +2092,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
2080
2092
  return { success: false, error: `Path '${absPath}' is on the system write deny-list` };
2081
2093
  }
2082
2094
  try {
2083
- await mkdir(absPath);
2095
+ await mkdir$1(absPath);
2084
2096
  logger.info("[createDirectory] path=%s ok=%s", absPath, true);
2085
2097
  return { success: true };
2086
2098
  } catch (error) {
@@ -2244,7 +2256,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
2244
2256
  if (sessionId) {
2245
2257
  rpcHandlerManager.registerHandler("getDiffDetail", async (data) => {
2246
2258
  logger.debug("getDiffDetail request:", data.callId, data.filePath);
2247
- const result = getDiffDetail(sessionId, data.callId, data.filePath);
2259
+ const result = await getDiffDetail(sessionId, data.callId, data.filePath);
2248
2260
  if (!result) {
2249
2261
  return { success: false, error: "not_found" };
2250
2262
  }
@@ -2257,7 +2269,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
2257
2269
  });
2258
2270
  rpcHandlerManager.registerHandler("getToolOutput", async (data) => {
2259
2271
  logger.debug("getToolOutput request:", data.callId);
2260
- const record = getToolOutputRecord(sessionId, data.callId);
2272
+ const record = await getToolOutputRecord(sessionId, data.callId);
2261
2273
  if (!record) {
2262
2274
  return { success: false, error: "not_found" };
2263
2275
  }
@@ -5261,7 +5273,7 @@ class GeminiSessionWriter {
5261
5273
  }
5262
5274
  async init(meta) {
5263
5275
  try {
5264
- await mkdir$1(getGeminiSessionsDir(), { recursive: true });
5276
+ await mkdir(getGeminiSessionsDir(), { recursive: true });
5265
5277
  this.appendLine({
5266
5278
  type: "meta",
5267
5279
  key: "sessionStart",
@@ -5328,7 +5340,7 @@ class GeminiSessionWriter {
5328
5340
  * Errors are logged but never thrown — persistence is best-effort.
5329
5341
  */
5330
5342
  appendLine(line) {
5331
- this.writePromise = this.writePromise.then(() => appendFile$1(this.filePath, JSON.stringify(line) + "\n", "utf-8")).catch((error) => {
5343
+ this.writePromise = this.writePromise.then(() => appendFile(this.filePath, JSON.stringify(line) + "\n", "utf-8")).catch((error) => {
5332
5344
  logger.debug(`[GeminiSessionWriter] Write failed:`, error);
5333
5345
  });
5334
5346
  }
@@ -1,17 +1,18 @@
1
1
  'use strict';
2
2
 
3
3
  var axios = require('axios');
4
- var logger = require('./persistence-uOLA4_LW.cjs');
4
+ var logger = require('./persistence-CNXsXPLm.cjs');
5
5
  var node_events = require('node:events');
6
6
  var socket_ioClient = require('socket.io-client');
7
7
  var z = require('zod');
8
8
  require('./index-DBev4hhV.cjs');
9
9
  var time = require('./time-Bj2HRkKH.cjs');
10
10
  var node_crypto = require('node:crypto');
11
- var fs = require('node:fs');
12
11
  var path = require('node:path');
13
- var node_child_process = require('node:child_process');
12
+ var fs = require('node:fs');
14
13
  var promises = require('node:fs/promises');
14
+ var node_readline = require('node:readline');
15
+ var node_child_process = require('node:child_process');
15
16
  var os = require('node:os');
16
17
  var node_util = require('node:util');
17
18
  var child_process = require('child_process');
@@ -24,9 +25,8 @@ var WebSocket = require('ws');
24
25
  var crypto = require('crypto');
25
26
  var tweetnacl = require('tweetnacl');
26
27
  var base64 = require('@stablelib/base64');
27
- var node_readline = require('node:readline');
28
28
  var expoServerSdk = require('expo-server-sdk');
29
- var sessionKeyCache = require('./sessionKeyCache-CCvSFqv3.cjs');
29
+ var sessionKeyCache = require('./sessionKeyCache-JjjYAxdf.cjs');
30
30
  var chalk = require('chalk');
31
31
 
32
32
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
@@ -235,41 +235,70 @@ class InvalidateSync {
235
235
  };
236
236
  }
237
237
 
238
- const diffsDir = path.join(logger.configuration.happyHomeDir, "diffs");
239
- function ensureDiffsDir() {
240
- if (!fs.existsSync(diffsDir)) {
241
- fs.mkdirSync(diffsDir, { recursive: true });
242
- }
243
- }
244
- function getFilePath$1(sessionId) {
245
- return path.join(diffsDir, `${sessionId}.json`);
238
+ const pendingAppends = /* @__PURE__ */ new Map();
239
+ async function appendJsonLines(filePath, records) {
240
+ const data = records.map((record) => `${JSON.stringify(record)}
241
+ `).join("");
242
+ const previous = pendingAppends.get(filePath) ?? Promise.resolve();
243
+ const current = previous.then(async () => {
244
+ await promises.mkdir(path.dirname(filePath), { recursive: true });
245
+ await promises.appendFile(filePath, data, "utf-8");
246
+ });
247
+ const settled = current.catch(() => {
248
+ });
249
+ pendingAppends.set(filePath, settled);
250
+ void settled.then(() => {
251
+ if (pendingAppends.get(filePath) === settled) pendingAppends.delete(filePath);
252
+ });
253
+ return current;
246
254
  }
247
- function saveDiffRecords(sessionId, records) {
248
- if (records.length === 0) return;
255
+ async function findJsonLine(filePath, needle, match) {
256
+ await pendingAppends.get(filePath);
257
+ if (!fs.existsSync(filePath)) return null;
258
+ const fileStream = fs.createReadStream(filePath, { encoding: "utf8" });
259
+ const rl = node_readline.createInterface({
260
+ input: fileStream,
261
+ crlfDelay: Infinity
262
+ });
249
263
  try {
250
- ensureDiffsDir();
251
- const filePath = getFilePath$1(sessionId);
252
- let existing = [];
253
- if (fs.existsSync(filePath)) {
264
+ for await (const line of rl) {
265
+ if (!line.includes(needle)) continue;
254
266
  try {
255
- existing = JSON.parse(fs.readFileSync(filePath, "utf-8"));
267
+ const record = JSON.parse(line);
268
+ if (match(record)) return record;
256
269
  } catch {
257
- existing = [];
258
270
  }
259
271
  }
260
- existing.push(...records);
261
- fs.writeFileSync(filePath, JSON.stringify(existing), "utf-8");
262
- logger.logger.debug(`[DiffStore] Saved ${records.length} record(s) for session ${sessionId}`);
263
- } catch (error) {
264
- logger.logger.warn(`[DiffStore] Failed to save diff records:`, error);
272
+ return null;
273
+ } finally {
274
+ rl.close();
275
+ fileStream.destroy();
265
276
  }
266
277
  }
267
- function getDiffDetail(sessionId, callId, filePath) {
278
+ async function findInJsonArrayFile(filePath, match) {
279
+ if (!fs.existsSync(filePath)) return null;
280
+ const records = JSON.parse(await promises.readFile(filePath, "utf-8"));
281
+ return records.find(match) ?? null;
282
+ }
283
+
284
+ const diffsDir = path.join(logger.configuration.happyHomeDir, "diffs");
285
+ function getFilePath$1(sessionId) {
286
+ return path.join(diffsDir, `${sessionId}.jsonl`);
287
+ }
288
+ function getLegacyFilePath$1(sessionId) {
289
+ return path.join(diffsDir, `${sessionId}.json`);
290
+ }
291
+ function saveDiffRecords(sessionId, records) {
292
+ if (records.length === 0) return;
293
+ appendJsonLines(getFilePath$1(sessionId), records).then(
294
+ () => logger.logger.debug(`[DiffStore] Saved ${records.length} record(s) for session ${sessionId}`),
295
+ (error) => logger.logger.warn(`[DiffStore] Failed to save diff records:`, error)
296
+ );
297
+ }
298
+ async function getDiffDetail(sessionId, callId, filePath) {
268
299
  try {
269
- const file = getFilePath$1(sessionId);
270
- if (!fs.existsSync(file)) return null;
271
- const records = JSON.parse(fs.readFileSync(file, "utf-8"));
272
- const record = records.find((r) => r.callId === callId && r.filePath === filePath);
300
+ const match = (r) => r.callId === callId && r.filePath === filePath;
301
+ const record = await findJsonLine(getFilePath$1(sessionId), JSON.stringify(callId), match) ?? await findInJsonArrayFile(getLegacyFilePath$1(sessionId), match);
273
302
  if (!record) return null;
274
303
  return { diff: record.diff, additions: record.additions, deletions: record.deletions };
275
304
  } catch (error) {
@@ -279,39 +308,22 @@ function getDiffDetail(sessionId, callId, filePath) {
279
308
  }
280
309
 
281
310
  const toolOutputsDir = path.join(logger.configuration.happyHomeDir, "tool-outputs");
282
- function ensureToolOutputsDir() {
283
- if (!fs.existsSync(toolOutputsDir)) {
284
- fs.mkdirSync(toolOutputsDir, { recursive: true });
285
- }
286
- }
287
311
  function getFilePath(sessionId) {
312
+ return path.join(toolOutputsDir, `${sessionId}.jsonl`);
313
+ }
314
+ function getLegacyFilePath(sessionId) {
288
315
  return path.join(toolOutputsDir, `${sessionId}.json`);
289
316
  }
290
317
  function saveToolOutputRecord(sessionId, record) {
291
- try {
292
- ensureToolOutputsDir();
293
- const filePath = getFilePath(sessionId);
294
- let existing = [];
295
- if (fs.existsSync(filePath)) {
296
- try {
297
- existing = JSON.parse(fs.readFileSync(filePath, "utf-8"));
298
- } catch {
299
- existing = [];
300
- }
301
- }
302
- existing.push(record);
303
- fs.writeFileSync(filePath, JSON.stringify(existing), "utf-8");
304
- logger.logger.debug(`[ToolOutputStore] Saved output for ${record.toolName} (${record.callId}) in session ${sessionId}`);
305
- } catch (error) {
306
- logger.logger.warn("[ToolOutputStore] Failed to save tool output record:", error);
307
- }
318
+ appendJsonLines(getFilePath(sessionId), [record]).then(
319
+ () => logger.logger.debug(`[ToolOutputStore] Saved output for ${record.toolName} (${record.callId}) in session ${sessionId}`),
320
+ (error) => logger.logger.warn("[ToolOutputStore] Failed to save tool output record:", error)
321
+ );
308
322
  }
309
- function getToolOutputRecord(sessionId, callId) {
323
+ async function getToolOutputRecord(sessionId, callId) {
310
324
  try {
311
- const filePath = getFilePath(sessionId);
312
- if (!fs.existsSync(filePath)) return null;
313
- const records = JSON.parse(fs.readFileSync(filePath, "utf-8"));
314
- return records.find((record) => record.callId === callId) || null;
325
+ const match = (record) => record.callId === callId;
326
+ return await findJsonLine(getFilePath(sessionId), JSON.stringify(callId), match) ?? await findInJsonArrayFile(getLegacyFilePath(sessionId), match);
315
327
  } catch (error) {
316
328
  logger.logger.warn("[ToolOutputStore] Failed to get tool output record:", error);
317
329
  return null;
@@ -1395,7 +1407,7 @@ function resolveToolsDir() {
1395
1407
  }
1396
1408
  function findToolsDir() {
1397
1409
  try {
1398
- const manifest = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('api-DvnXQWOp.cjs', document.baseURI).href))).resolve(`${toolsPackageName()}/package.json`);
1410
+ const manifest = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('api-BGc484qf.cjs', document.baseURI).href))).resolve(`${toolsPackageName()}/package.json`);
1399
1411
  return path.dirname(manifest);
1400
1412
  } catch {
1401
1413
  }
@@ -2247,7 +2259,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
2247
2259
  if (sessionId) {
2248
2260
  rpcHandlerManager.registerHandler("getDiffDetail", async (data) => {
2249
2261
  logger.logger.debug("getDiffDetail request:", data.callId, data.filePath);
2250
- const result = getDiffDetail(sessionId, data.callId, data.filePath);
2262
+ const result = await getDiffDetail(sessionId, data.callId, data.filePath);
2251
2263
  if (!result) {
2252
2264
  return { success: false, error: "not_found" };
2253
2265
  }
@@ -2260,7 +2272,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
2260
2272
  });
2261
2273
  rpcHandlerManager.registerHandler("getToolOutput", async (data) => {
2262
2274
  logger.logger.debug("getToolOutput request:", data.callId);
2263
- const record = getToolOutputRecord(sessionId, data.callId);
2275
+ const record = await getToolOutputRecord(sessionId, data.callId);
2264
2276
  if (!record) {
2265
2277
  return { success: false, error: "not_found" };
2266
2278
  }
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var logger = require('./persistence-uOLA4_LW.cjs');
3
+ var logger = require('./persistence-CNXsXPLm.cjs');
4
4
  var node_crypto = require('node:crypto');
5
5
  var tweetnacl = require('tweetnacl');
6
6
  var axios = require('axios');
7
7
  var qrcode = require('qrcode-terminal');
8
8
  var time = require('./time-Bj2HRkKH.cjs');
9
- var browser = require('./browser-DFeQQh1Z.cjs');
9
+ var browser = require('./browser-CnxzD1lA.cjs');
10
10
  var React = require('react');
11
11
  var ink = require('ink');
12
12
  require('node:fs/promises');
@@ -1,10 +1,10 @@
1
- import { e as encodeBase64, c as configuration, l as logger, r as readCredentials, u as updateSettings, i as isDebug, s as encodeBase64Url, h as decodeBase64, t as writeCredentialsLegacy, w as writeCredentialsDataKey } from './persistence-P3x0-3CX.mjs';
1
+ import { e as encodeBase64, c as configuration, l as logger, r as readCredentials, u as updateSettings, i as isDebug, s as encodeBase64Url, h as decodeBase64, t as writeCredentialsLegacy, w as writeCredentialsDataKey } from './persistence-IdEuIeMz.mjs';
2
2
  import { randomBytes, randomUUID } from 'node:crypto';
3
3
  import tweetnacl from 'tweetnacl';
4
4
  import axios from 'axios';
5
5
  import qrcode from 'qrcode-terminal';
6
6
  import { d as delay } from './time-DgsBLJA_.mjs';
7
- import { o as openBrowser } from './browser-cQ-qyFyK.mjs';
7
+ import { o as openBrowser } from './browser-CkQP96Zi.mjs';
8
8
  import React, { useState } from 'react';
9
9
  import { useInput, Box, Text, render } from 'ink';
10
10
  import 'node:fs/promises';
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
3
  var chalk = require('chalk');
4
- var logger = require('./persistence-uOLA4_LW.cjs');
5
- var auth = require('./auth-bwfaLx_V.cjs');
4
+ var logger = require('./persistence-CNXsXPLm.cjs');
5
+ var auth = require('./auth-B6vskzfm.cjs');
6
6
  var fs = require('node:fs');
7
7
  var node_readline = require('node:readline');
8
- var controlClient = require('./controlClient-DnZ5KouD.cjs');
8
+ var controlClient = require('./controlClient-DWBW6jRF.cjs');
9
9
  var os = require('node:os');
10
10
  require('node:fs/promises');
11
11
  require('node:path');
@@ -16,7 +16,7 @@ require('fs');
16
16
  require('axios');
17
17
  require('qrcode-terminal');
18
18
  require('./time-Bj2HRkKH.cjs');
19
- require('./browser-DFeQQh1Z.cjs');
19
+ require('./browser-CnxzD1lA.cjs');
20
20
  require('open');
21
21
  require('react');
22
22
  require('ink');
@@ -1,9 +1,9 @@
1
1
  import chalk from 'chalk';
2
- import { r as readCredentials, a as readSettings, c as configuration, l as logger, b as clearCredentials, d as clearMachineId } from './persistence-P3x0-3CX.mjs';
3
- import { authAndSetupMachineIfNeeded } from './auth-CpHjpbeh.mjs';
2
+ import { r as readCredentials, a as readSettings, c as configuration, l as logger, b as clearCredentials, d as clearMachineId } from './persistence-IdEuIeMz.mjs';
3
+ import { authAndSetupMachineIfNeeded } from './auth-BnEa31tI.mjs';
4
4
  import { existsSync, rmSync } from 'node:fs';
5
5
  import { createInterface } from 'node:readline';
6
- import { checkIfDaemonRunningAndCleanupStaleState, stopDaemon } from './controlClient-G7DPgAo_.mjs';
6
+ import { checkIfDaemonRunningAndCleanupStaleState, stopDaemon } from './controlClient-VY0CGL8k.mjs';
7
7
  import os from 'node:os';
8
8
  import 'node:fs/promises';
9
9
  import 'node:path';
@@ -14,7 +14,7 @@ import 'fs';
14
14
  import 'axios';
15
15
  import 'qrcode-terminal';
16
16
  import './time-DgsBLJA_.mjs';
17
- import './browser-cQ-qyFyK.mjs';
17
+ import './browser-CkQP96Zi.mjs';
18
18
  import 'open';
19
19
  import 'react';
20
20
  import 'ink';
@@ -1,5 +1,5 @@
1
1
  import open from 'open';
2
- import { l as logger } from './persistence-P3x0-3CX.mjs';
2
+ import { l as logger } from './persistence-IdEuIeMz.mjs';
3
3
 
4
4
  async function openBrowser(url) {
5
5
  try {
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var open = require('open');
4
- var logger = require('./persistence-uOLA4_LW.cjs');
4
+ var logger = require('./persistence-CNXsXPLm.cjs');
5
5
 
6
6
  async function openBrowser(url) {
7
7
  try {
@@ -3,7 +3,7 @@ import { resolve, join } from 'node:path';
3
3
  import { createInterface } from 'node:readline';
4
4
  import { existsSync, readFileSync, readdirSync, statSync, mkdirSync } from 'node:fs';
5
5
  import { randomUUID } from 'node:crypto';
6
- import { l as logger } from './persistence-P3x0-3CX.mjs';
6
+ import { l as logger } from './persistence-IdEuIeMz.mjs';
7
7
  import { homedir } from 'node:os';
8
8
  import { p as projectPath } from './projectPath-BTBIMB57.mjs';
9
9
  import { g as getBaseSystemPrompt } from './prompt-BsAZsPbo.mjs';
@@ -5,7 +5,7 @@ var path = require('node:path');
5
5
  var node_readline = require('node:readline');
6
6
  var fs = require('node:fs');
7
7
  var node_crypto = require('node:crypto');
8
- var logger = require('./persistence-uOLA4_LW.cjs');
8
+ var logger = require('./persistence-CNXsXPLm.cjs');
9
9
  var os = require('node:os');
10
10
  var projectPath = require('./projectPath-ChLhdOyt.cjs');
11
11
  var prompt = require('./prompt-BTWDZZO0.cjs');
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import { homedir } from 'os';
4
4
  import { execSync } from 'child_process';
5
- import { l as logger } from './persistence-P3x0-3CX.mjs';
5
+ import { l as logger } from './persistence-IdEuIeMz.mjs';
6
6
  import { D as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './constants-pmXZGibX.mjs';
7
7
  import 'node:fs/promises';
8
8
  import 'node:fs';
@@ -4,7 +4,7 @@ var fs = require('fs');
4
4
  var path = require('path');
5
5
  var os = require('os');
6
6
  var child_process = require('child_process');
7
- var logger = require('./persistence-uOLA4_LW.cjs');
7
+ var logger = require('./persistence-CNXsXPLm.cjs');
8
8
  var constants = require('./constants-E_UWYTo3.cjs');
9
9
  require('node:fs/promises');
10
10
  require('node:fs');
@@ -2,11 +2,11 @@ import chalk from 'chalk';
2
2
  import { existsSync, mkdirSync, writeFileSync } from 'fs';
3
3
  import { homedir } from 'os';
4
4
  import { join } from 'path';
5
- import { r as readCredentials } from './persistence-P3x0-3CX.mjs';
6
- import { A as ApiClient } from './api-BH3mam5i.mjs';
5
+ import { r as readCredentials } from './persistence-IdEuIeMz.mjs';
6
+ import { A as ApiClient } from './api-9wvM_aF-.mjs';
7
7
  import { createServer } from 'http';
8
8
  import { randomBytes, createHash } from 'crypto';
9
- import { o as openBrowser } from './browser-cQ-qyFyK.mjs';
9
+ import { o as openBrowser } from './browser-CkQP96Zi.mjs';
10
10
  import { exec } from 'child_process';
11
11
  import { promisify } from 'util';
12
12
  import 'node:fs/promises';
@@ -22,6 +22,7 @@ import 'socket.io-client';
22
22
  import './index-7P6T8CE4.mjs';
23
23
  import '@paralleldrive/cuid2';
24
24
  import './time-DgsBLJA_.mjs';
25
+ import 'node:readline';
25
26
  import 'node:child_process';
26
27
  import 'node:util';
27
28
  import 'fs/promises';
@@ -30,9 +31,8 @@ import 'url';
30
31
  import 'node:module';
31
32
  import 'ws';
32
33
  import '@stablelib/base64';
33
- import 'node:readline';
34
34
  import 'expo-server-sdk';
35
- import './sessionKeyCache-B_rg3Wj3.mjs';
35
+ import './sessionKeyCache-DDzTs7E5.mjs';
36
36
  import 'open';
37
37
 
38
38
  const CLIENT_ID$2 = "app_EMoamEEZ73f0CkXaXp7hrann";