chatlab-cli 0.31.1 → 0.31.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/{chat-command-MOETAGU5.mjs → chat-command-V6NYTTPD.mjs} +8 -8
  2. package/dist/{chunk-ZVWUR7ET.mjs → chunk-54GVCXHZ.mjs} +2 -2
  3. package/dist/{chunk-KCPGEILH.mjs → chunk-5G2INROS.mjs} +483 -356
  4. package/dist/chunk-5G2INROS.mjs.map +1 -0
  5. package/dist/{chunk-SZEBCNBB.mjs → chunk-67HNEIKY.mjs} +2084 -1924
  6. package/dist/chunk-67HNEIKY.mjs.map +1 -0
  7. package/dist/{chunk-VOVLPSG6.mjs → chunk-7TDYBU5L.mjs} +4 -4
  8. package/dist/{chunk-LJXSUN25.mjs → chunk-HUKZ2PBC.mjs} +2 -2
  9. package/dist/{chunk-3VMKS7PU.mjs → chunk-LWC7JQ2W.mjs} +2 -2
  10. package/dist/{chunk-N5AGDT7I.mjs → chunk-OIZ64ET3.mjs} +3 -3
  11. package/dist/{chunk-E6W2RURS.mjs → chunk-SJQVAKFA.mjs} +5 -4
  12. package/dist/chunk-SJQVAKFA.mjs.map +1 -0
  13. package/dist/{chunk-2IXPWPLR.mjs → chunk-WL2ISRYH.mjs} +11 -11
  14. package/dist/{chunk-DQ45LDKZ.mjs → chunk-XZ5FFDLX.mjs} +125 -136
  15. package/dist/chunk-XZ5FFDLX.mjs.map +1 -0
  16. package/dist/{chunk-7HBVGVOB.mjs → chunk-ZF67S6RY.mjs} +2 -2
  17. package/dist/cli.mjs +8 -8
  18. package/dist/contacts-worker.mjs +2 -2
  19. package/dist/global-insight-worker.mjs +1 -1
  20. package/dist/{http-M6NHWJZD.mjs → http-AMDWRKOH.mjs} +11 -11
  21. package/dist/{import-SEYHFXS5.mjs → import-WIJHB4LH.mjs} +7 -7
  22. package/dist/index.mjs +11 -11
  23. package/dist/{mcp-MIPFYRLV.mjs → mcp-NC5YNTM5.mjs} +8 -8
  24. package/dist/people-relationships-worker.mjs +2 -2
  25. package/dist/semantic-index-worker.mjs +1 -1
  26. package/dist/{src-7OD6RD5V.mjs → src-UY4GCVNF.mjs} +22 -6
  27. package/dist/{stream-import-AWEHGQJY.mjs → stream-import-JKQYRISL.mjs} +7 -7
  28. package/dist/{worker-runtime-TGYMASIE.mjs → worker-runtime-KKUOJJTN.mjs} +5 -5
  29. package/dist-web/assets/{ActionToolsPanel-fAio70bI.css → ActionToolsPanel-BL0GQR6r.css} +1 -1
  30. package/dist-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-DVdpZpfD.js +110 -0
  31. package/dist-web/assets/{BufferResource-CHI62pIA.js → BufferResource-i1amDJTV.js} +1 -1
  32. package/dist-web/assets/{CanvasRenderer-OZRoiF0j.js → CanvasRenderer-DGa7AjdC.js} +1 -1
  33. package/dist-web/assets/EChartWordcloud-BXC_4nUP.js +1 -0
  34. package/dist-web/assets/{Filter-DNb5VErW.js → Filter-BTlq0yU-.js} +1 -1
  35. package/dist-web/assets/LoadingState.vue_vue_type_script_setup_true_lang-B2KAoiMG.js +1 -0
  36. package/dist-web/assets/MessageExportModal-D9C5t_zF.js +1 -0
  37. package/dist-web/assets/PageHeader-BEWr2vsg.js +1 -0
  38. package/dist-web/assets/{RelationshipGalaxyCanvas-ioRNObb5.js → RelationshipGalaxyCanvas-CSgPNRif.js} +4 -4
  39. package/dist-web/assets/{RelationshipGalaxyThreeCanvas-L1Y43p1A.js → RelationshipGalaxyThreeCanvas-CBAnU8vN.js} +1 -1
  40. package/dist-web/assets/{RenderTargetSystem-fJ7D7Chv.js → RenderTargetSystem-Ctlu222X.js} +1 -1
  41. package/dist-web/assets/ThemeCard.vue_vue_type_script_setup_true_lang-BWJ6kuSC.js +1 -0
  42. package/dist-web/assets/TimeSelect.vue_vue_type_script_setup_true_lang-D5vov0eO.js +1 -0
  43. package/dist-web/assets/{WebGLRenderer-BD3ZUtxH.js → WebGLRenderer-D2Zvhmcw.js} +1 -1
  44. package/dist-web/assets/{WebGPURenderer-DZXYsT6D.js → WebGPURenderer-BOtP6h9o.js} +1 -1
  45. package/dist-web/assets/annual-summary-time-range-CK0IIPsY.js +1 -0
  46. package/dist-web/assets/{base-DTElkJcC.js → base-BMjDSaj6.js} +1 -1
  47. package/dist-web/assets/{browserAll-ChT6N6a9.js → browserAll-BhwLvWQY.js} +1 -1
  48. package/dist-web/assets/dateFormat-dteP1INW.js +1 -0
  49. package/dist-web/assets/{electron-CIzyGxH_.js → electron-DCgfulPE.js} +1 -1
  50. package/dist-web/assets/{fetch-CuiQUcO_.js → fetch-6q7oz7ZO.js} +1 -1
  51. package/dist-web/assets/{fetch-Avtnh8cJ.js → fetch-B_0HIxs5.js} +1 -1
  52. package/dist-web/assets/{fetch-DnGx-1_t.js → fetch-BbU4MPPu.js} +1 -1
  53. package/dist-web/assets/{fetch-Dd6t3p1r.js → fetch-BxHdB6X1.js} +1 -1
  54. package/dist-web/assets/{fetch-qC7om4QG.js → fetch-CpvfCafG.js} +1 -1
  55. package/dist-web/assets/{fetch-wSSfDBdV.js → fetch-CubnKpLG.js} +1 -1
  56. package/dist-web/assets/{fetch-CyKILLnB.js → fetch-D5BrGna5.js} +1 -1
  57. package/dist-web/assets/{fetch-C9rx2isC.js → fetch-DgXWr9nB.js} +1 -1
  58. package/dist-web/assets/{fetch-Ccq_0ecb.js → fetch-DvZuLuTE.js} +1 -1
  59. package/dist-web/assets/{fetch-BFnrBahy.js → fetch-rJA9qLvd.js} +1 -1
  60. package/dist-web/assets/index-BfGKlkx3.js +2 -0
  61. package/dist-web/assets/index-BoalB6nB.js +1 -0
  62. package/dist-web/assets/index-Bp5VKUF9.js +1 -0
  63. package/dist-web/assets/index-Bs15Yc7I.js +1 -0
  64. package/dist-web/assets/index-CAjUCtGD.css +1 -0
  65. package/dist-web/assets/index-CLijvqy3.js +173 -0
  66. package/dist-web/assets/{index-DXHYzIIj.js → index-CUzFFw5b.js} +1 -1
  67. package/dist-web/assets/index-Cj2GU1SR.js +1 -0
  68. package/dist-web/assets/{index-y7cxH1Et.css → index-CsqMIyA9.css} +1 -1
  69. package/dist-web/assets/index-CtmXho1w.css +1 -0
  70. package/dist-web/assets/index-D7aKwT6w.js +64 -0
  71. package/dist-web/assets/index-DXcFBsM1.js +24 -0
  72. package/dist-web/assets/index-DaZnh1zP.js +2 -0
  73. package/dist-web/assets/index-DeV8SAiM.js +25 -0
  74. package/dist-web/assets/index-WJCmqKnh.js +1 -0
  75. package/dist-web/assets/index-t6s0nOlb.js +1 -0
  76. package/dist-web/assets/people-page-header-D93GTPBO.js +1 -0
  77. package/dist-web/assets/vendor-nuxt-ui-DUpPmItD.js +15 -0
  78. package/dist-web/assets/vendor-reka-ui-BLnO2MqY.js +15 -0
  79. package/dist-web/assets/vendor-snapdom--nZvo8Sg.js +8 -0
  80. package/dist-web/assets/web-BoTDL3HM.js +1 -0
  81. package/dist-web/assets/{webworkerAll-C3dAOQj4.js → webworkerAll-c0ZvpENM.js} +1 -1
  82. package/dist-web/index.html +5 -5
  83. package/package.json +1 -1
  84. package/dist/chunk-DQ45LDKZ.mjs.map +0 -1
  85. package/dist/chunk-E6W2RURS.mjs.map +0 -1
  86. package/dist/chunk-KCPGEILH.mjs.map +0 -1
  87. package/dist/chunk-SZEBCNBB.mjs.map +0 -1
  88. package/dist-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-CkDGVRXe.js +0 -110
  89. package/dist-web/assets/EChartWordcloud-DU3ZYdgz.js +0 -1
  90. package/dist-web/assets/LoadingState.vue_vue_type_script_setup_true_lang-DACMroOe.js +0 -1
  91. package/dist-web/assets/MessageExportModal-CqP-w7HP.js +0 -1
  92. package/dist-web/assets/PageHeader-Ck8ULyZH.js +0 -1
  93. package/dist-web/assets/ThemeCard.vue_vue_type_script_setup_true_lang-BoZyssJF.js +0 -1
  94. package/dist-web/assets/TimeSelect.vue_vue_type_script_setup_true_lang-7SEaCxDL.js +0 -1
  95. package/dist-web/assets/annual-summary-time-range-DVLXK1r4.js +0 -1
  96. package/dist-web/assets/dateFormat-D9WibwOu.js +0 -1
  97. package/dist-web/assets/index-BH9jI5kV.js +0 -173
  98. package/dist-web/assets/index-BWtNqcYK.js +0 -22
  99. package/dist-web/assets/index-Bkq7-GBp.js +0 -1
  100. package/dist-web/assets/index-Bqr-LkS1.css +0 -1
  101. package/dist-web/assets/index-C6qtsaP7.js +0 -1
  102. package/dist-web/assets/index-C_0GHEcb.css +0 -1
  103. package/dist-web/assets/index-ChFGuu70.js +0 -1
  104. package/dist-web/assets/index-CiS20iAR.js +0 -24
  105. package/dist-web/assets/index-CqD6u57u.js +0 -1
  106. package/dist-web/assets/index-CzDG8LVr.js +0 -2
  107. package/dist-web/assets/index-D0Euk-vQ.js +0 -1
  108. package/dist-web/assets/index-D26BWhHz.js +0 -1
  109. package/dist-web/assets/index-Dq8u7gMb.js +0 -2
  110. package/dist-web/assets/index-u_UH6rDY.js +0 -64
  111. package/dist-web/assets/people-page-header-BdKM1qhX.js +0 -1
  112. package/dist-web/assets/vendor-nuxt-ui-CS1uxE9C.js +0 -15
  113. package/dist-web/assets/vendor-reka-ui-Cta6JPvN.js +0 -11
  114. package/dist-web/assets/vendor-snapdom-XnBoh1gd.js +0 -8
  115. package/dist-web/assets/web-BDBdpdK7.js +0 -1
  116. /package/dist/{chat-command-MOETAGU5.mjs.map → chat-command-V6NYTTPD.mjs.map} +0 -0
  117. /package/dist/{chunk-ZVWUR7ET.mjs.map → chunk-54GVCXHZ.mjs.map} +0 -0
  118. /package/dist/{chunk-VOVLPSG6.mjs.map → chunk-7TDYBU5L.mjs.map} +0 -0
  119. /package/dist/{chunk-LJXSUN25.mjs.map → chunk-HUKZ2PBC.mjs.map} +0 -0
  120. /package/dist/{chunk-3VMKS7PU.mjs.map → chunk-LWC7JQ2W.mjs.map} +0 -0
  121. /package/dist/{chunk-N5AGDT7I.mjs.map → chunk-OIZ64ET3.mjs.map} +0 -0
  122. /package/dist/{chunk-2IXPWPLR.mjs.map → chunk-WL2ISRYH.mjs.map} +0 -0
  123. /package/dist/{chunk-7HBVGVOB.mjs.map → chunk-ZF67S6RY.mjs.map} +0 -0
  124. /package/dist/{http-M6NHWJZD.mjs.map → http-AMDWRKOH.mjs.map} +0 -0
  125. /package/dist/{import-SEYHFXS5.mjs.map → import-WIJHB4LH.mjs.map} +0 -0
  126. /package/dist/{mcp-MIPFYRLV.mjs.map → mcp-NC5YNTM5.mjs.map} +0 -0
  127. /package/dist/{src-7OD6RD5V.mjs.map → src-UY4GCVNF.mjs.map} +0 -0
  128. /package/dist/{stream-import-AWEHGQJY.mjs.map → stream-import-JKQYRISL.mjs.map} +0 -0
  129. /package/dist/{worker-runtime-TGYMASIE.mjs.map → worker-runtime-KKUOJJTN.mjs.map} +0 -0
@@ -9,7 +9,7 @@ import {
9
9
  createEmptyContactsDiagnostics,
10
10
  normalizeContactsTimeRangePreset,
11
11
  resolveContactsTimeRange
12
- } from "./chunk-7HBVGVOB.mjs";
12
+ } from "./chunk-ZF67S6RY.mjs";
13
13
  import {
14
14
  PEOPLE_RELATIONSHIPS_ALGORITHM_VERSION,
15
15
  buildPeopleRelationshipsNeighborhoodGraph,
@@ -18,7 +18,7 @@ import {
18
18
  computePeopleRelationshipsSnapshot,
19
19
  normalizePeopleRelationshipsTimeRangePreset,
20
20
  resolvePeopleRelationshipsTimeRange
21
- } from "./chunk-LJXSUN25.mjs";
21
+ } from "./chunk-HUKZ2PBC.mjs";
22
22
  import {
23
23
  ANNUAL_SUMMARY_ALGORITHM_VERSION
24
24
  } from "./chunk-YAQLYL52.mjs";
@@ -42,7 +42,9 @@ import {
42
42
  clearSessionIndex,
43
43
  collectPosTagStats,
44
44
  deleteAnnualSummarySnapshots,
45
+ deleteAuthProfile,
45
46
  deleteMember,
47
+ deleteMembers,
46
48
  generateIncrementalSessionIndex,
47
49
  generateMessageKey,
48
50
  generateSessionIndex,
@@ -93,7 +95,7 @@ import {
93
95
  updateSessionOwnerId,
94
96
  writeAnnualSummarySnapshot,
95
97
  writeAuthProfile
96
- } from "./chunk-DQ45LDKZ.mjs";
98
+ } from "./chunk-XZ5FFDLX.mjs";
97
99
  import {
98
100
  __commonJS,
99
101
  __export,
@@ -709,8 +711,8 @@ var require_FilterBase = __commonJS({
709
711
  var FilterBase = class _FilterBase extends Transform {
710
712
  static stringFilter(string, separator) {
711
713
  return (stack) => {
712
- const path31 = stack.join(separator);
713
- return path31.length === string.length && path31 === string || path31.length > string.length && path31.substr(0, string.length) === string && path31.substr(string.length, separator.length) === separator;
714
+ const path33 = stack.join(separator);
715
+ return path33.length === string.length && path33 === string || path33.length > string.length && path33.substr(0, string.length) === string && path33.substr(string.length, separator.length) === separator;
714
716
  };
715
717
  }
716
718
  static regExpFilter(regExp, separator) {
@@ -1164,12 +1166,12 @@ var require_Assembler = __commonJS({
1164
1166
  return (this.stack.length >> 1) + (this.done ? 0 : 1);
1165
1167
  }
1166
1168
  get path() {
1167
- const path31 = [];
1169
+ const path33 = [];
1168
1170
  for (let i = 0; i < this.stack.length; i += 2) {
1169
1171
  const key = this.stack[i + 1];
1170
- path31.push(key === null ? this.stack[i].length : key);
1172
+ path33.push(key === null ? this.stack[i].length : key);
1171
1173
  }
1172
- return path31;
1174
+ return path33;
1173
1175
  }
1174
1176
  dropToLevel(level) {
1175
1177
  if (level < this.depth) {
@@ -1451,7 +1453,7 @@ var require_pend = __commonJS({
1451
1453
  var require_fd_slicer = __commonJS({
1452
1454
  "../../packages/node-runtime/node_modules/yauzl/fd-slicer.js"(exports) {
1453
1455
  "use strict";
1454
- var fs35 = __require("fs");
1456
+ var fs37 = __require("fs");
1455
1457
  var util = __require("util");
1456
1458
  var stream = __require("stream");
1457
1459
  var Readable = stream.Readable;
@@ -1471,7 +1473,7 @@ var require_fd_slicer = __commonJS({
1471
1473
  FdSlicer.prototype.read = function(buffer, offset, length, position, callback) {
1472
1474
  var self = this;
1473
1475
  self.pend.go(function(cb) {
1474
- fs35.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer2) {
1476
+ fs37.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer2) {
1475
1477
  cb();
1476
1478
  callback(err, bytesRead, buffer2);
1477
1479
  });
@@ -1488,7 +1490,7 @@ var require_fd_slicer = __commonJS({
1488
1490
  self.refCount -= 1;
1489
1491
  if (self.refCount < 0) throw new Error("invalid unref");
1490
1492
  if (self.refCount > 0) return;
1491
- fs35.close(self.fd, onCloseDone);
1493
+ fs37.close(self.fd, onCloseDone);
1492
1494
  function onCloseDone(err) {
1493
1495
  if (err) {
1494
1496
  self.emit("error", err);
@@ -1520,7 +1522,7 @@ var require_fd_slicer = __commonJS({
1520
1522
  }
1521
1523
  self.context.pend.go(function(cb) {
1522
1524
  var buffer = Buffer.allocUnsafe(toRead);
1523
- fs35.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
1525
+ fs37.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
1524
1526
  if (err) {
1525
1527
  self.destroy(err);
1526
1528
  } else if (bytesRead === 0) {
@@ -1882,7 +1884,7 @@ var require_crc32 = __commonJS({
1882
1884
  var require_yauzl = __commonJS({
1883
1885
  "../../packages/node-runtime/node_modules/yauzl/index.js"(exports) {
1884
1886
  "use strict";
1885
- var fs35 = __require("fs");
1887
+ var fs37 = __require("fs");
1886
1888
  var zlib = __require("zlib");
1887
1889
  var fd_slicer = require_fd_slicer();
1888
1890
  var util = __require("util");
@@ -1907,39 +1909,39 @@ var require_yauzl = __commonJS({
1907
1909
  exports.Entry = Entry;
1908
1910
  exports.LocalFileHeader = LocalFileHeader;
1909
1911
  exports.RandomAccessReader = RandomAccessReader;
1910
- function openPromise2(path31, options2) {
1911
- return new Promise((resolve2, reject) => {
1912
- open(path31, { ...options2, lazyEntries: true }, function(err, zipfile) {
1912
+ function openPromise2(path33, options2) {
1913
+ return new Promise((resolve4, reject) => {
1914
+ open(path33, { ...options2, lazyEntries: true }, function(err, zipfile) {
1913
1915
  if (err) return reject(err);
1914
- resolve2(zipfile);
1916
+ resolve4(zipfile);
1915
1917
  });
1916
1918
  });
1917
1919
  }
1918
1920
  function fromFdPromise(fd, options2) {
1919
- return new Promise((resolve2, reject) => {
1921
+ return new Promise((resolve4, reject) => {
1920
1922
  fromFd(fd, { ...options2, lazyEntries: true }, function(err, zipfile) {
1921
1923
  if (err) return reject(err);
1922
- resolve2(zipfile);
1924
+ resolve4(zipfile);
1923
1925
  });
1924
1926
  });
1925
1927
  }
1926
1928
  function fromBufferPromise(buffer, options2) {
1927
- return new Promise((resolve2, reject) => {
1929
+ return new Promise((resolve4, reject) => {
1928
1930
  fromBuffer(buffer, { ...options2, lazyEntries: true }, function(err, zipfile) {
1929
1931
  if (err) return reject(err);
1930
- resolve2(zipfile);
1932
+ resolve4(zipfile);
1931
1933
  });
1932
1934
  });
1933
1935
  }
1934
1936
  function fromRandomAccessReaderPromise(reader, totalSize, options2) {
1935
- return new Promise((resolve2, reject) => {
1937
+ return new Promise((resolve4, reject) => {
1936
1938
  fromRandomAccessReader(reader, totalSize, { ...options2, lazyEntries: true }, function(err, zipfile) {
1937
1939
  if (err) return reject(err);
1938
- resolve2(zipfile);
1940
+ resolve4(zipfile);
1939
1941
  });
1940
1942
  });
1941
1943
  }
1942
- function open(path31, options2, callback) {
1944
+ function open(path33, options2, callback) {
1943
1945
  if (typeof options2 === "function") {
1944
1946
  callback = options2;
1945
1947
  options2 = null;
@@ -1951,10 +1953,10 @@ var require_yauzl = __commonJS({
1951
1953
  if (options2.validateEntrySizes == null) options2.validateEntrySizes = true;
1952
1954
  if (options2.strictFileNames == null) options2.strictFileNames = false;
1953
1955
  if (callback == null) callback = defaultCallback;
1954
- fs35.open(path31, "r", function(err, fd) {
1956
+ fs37.open(path33, "r", function(err, fd) {
1955
1957
  if (err) return callback(err);
1956
1958
  fromFd(fd, options2, function(err2, zipfile) {
1957
- if (err2) fs35.close(fd, defaultCallback);
1959
+ if (err2) fs37.close(fd, defaultCallback);
1958
1960
  callback(err2, zipfile);
1959
1961
  });
1960
1962
  });
@@ -1971,7 +1973,7 @@ var require_yauzl = __commonJS({
1971
1973
  if (options2.validateEntrySizes == null) options2.validateEntrySizes = true;
1972
1974
  if (options2.strictFileNames == null) options2.strictFileNames = false;
1973
1975
  if (callback == null) callback = defaultCallback;
1974
- fs35.fstat(fd, function(err, stats) {
1976
+ fs37.fstat(fd, function(err, stats) {
1975
1977
  if (err) return callback(err);
1976
1978
  var reader = new fd_slicer.FdSlicer(fd);
1977
1979
  fromRandomAccessReader(reader, stats.size, options2, callback);
@@ -2219,15 +2221,15 @@ var require_yauzl = __commonJS({
2219
2221
  if (self.autoClose) self.close();
2220
2222
  }
2221
2223
  function onEntry(entry) {
2222
- let { resolve: resolve2 } = pendingResolveReject;
2224
+ let { resolve: resolve4 } = pendingResolveReject;
2223
2225
  pendingResolveReject = null;
2224
- resolve2({ value: entry });
2226
+ resolve4({ value: entry });
2225
2227
  }
2226
2228
  function onEnd() {
2227
- let { resolve: resolve2 } = pendingResolveReject;
2229
+ let { resolve: resolve4 } = pendingResolveReject;
2228
2230
  pendingResolveReject = null;
2229
2231
  cleanup();
2230
- resolve2({ done: true });
2232
+ resolve4({ done: true });
2231
2233
  }
2232
2234
  function onError(err) {
2233
2235
  let { reject } = pendingResolveReject;
@@ -2240,9 +2242,9 @@ var require_yauzl = __commonJS({
2240
2242
  return this;
2241
2243
  },
2242
2244
  next() {
2243
- const promise = new Promise((resolve2, reject) => {
2245
+ const promise = new Promise((resolve4, reject) => {
2244
2246
  if (pendingResolveReject != null) throw new Error("next() called before previous Promise was resolved.");
2245
- pendingResolveReject = { resolve: resolve2, reject };
2247
+ pendingResolveReject = { resolve: resolve4, reject };
2246
2248
  });
2247
2249
  self.readEntry();
2248
2250
  return promise;
@@ -2431,26 +2433,26 @@ var require_yauzl = __commonJS({
2431
2433
  });
2432
2434
  };
2433
2435
  ZipFile.prototype.openReadStreamPromise = function(entry, options2) {
2434
- return new Promise((resolve2, reject) => {
2436
+ return new Promise((resolve4, reject) => {
2435
2437
  this.openReadStream(entry, options2, function(err, readStream) {
2436
2438
  if (err) return reject(err);
2437
- resolve2(readStream);
2439
+ resolve4(readStream);
2438
2440
  });
2439
2441
  });
2440
2442
  };
2441
2443
  ZipFile.prototype.openReadStreamLowLevelPromise = function(fileDataStart, compressedSize, relativeStart, relativeEnd, decompress, uncompressedSize) {
2442
- return new Promise((resolve2, reject) => {
2444
+ return new Promise((resolve4, reject) => {
2443
2445
  this.openReadStream(fileDataStart, compressedSize, relativeStart, relativeEnd, decompress, uncompressedSize, function(err, readStream) {
2444
2446
  if (err) return reject(err);
2445
- resolve2(readStream);
2447
+ resolve4(readStream);
2446
2448
  });
2447
2449
  });
2448
2450
  };
2449
2451
  ZipFile.prototype.readLocalFileHeaderPromise = function(entry, options2) {
2450
- return new Promise((resolve2, reject) => {
2452
+ return new Promise((resolve4, reject) => {
2451
2453
  this.readLocalFileHeader(entry, options2, function(err, localFileHeader) {
2452
2454
  if (err) return reject(err);
2453
- resolve2(localFileHeader);
2455
+ resolve4(localFileHeader);
2454
2456
  });
2455
2457
  });
2456
2458
  };
@@ -2738,6 +2740,73 @@ var require_yauzl = __commonJS({
2738
2740
  }
2739
2741
  });
2740
2742
 
2743
+ // ../../packages/node-runtime/src/temp-workspace.ts
2744
+ import * as fs from "fs";
2745
+ import * as os from "os";
2746
+ import * as path from "path";
2747
+ var CHATLAB_TEMP_ROOT_ENV = "CHATLAB_TEMP_ROOT";
2748
+ var CHATLAB_TEMP_SCOPES = /* @__PURE__ */ new Set(["tests", "runtime", "imports", "merge", "sync", "parser", "build", "bench"]);
2749
+ function optionsEnv(options2) {
2750
+ return options2.env ?? process.env;
2751
+ }
2752
+ function resolveChatLabTempRoot(options2 = {}) {
2753
+ const envRoot = optionsEnv(options2)[CHATLAB_TEMP_ROOT_ENV]?.trim();
2754
+ if (envRoot) return path.resolve(envRoot);
2755
+ const platform2 = options2.platform ?? process.platform;
2756
+ const systemTempDir = options2.systemTempDir ?? os.tmpdir();
2757
+ return path.resolve(platform2 === "darwin" ? "/private/tmp/chatlab" : path.join(systemTempDir, "chatlab"));
2758
+ }
2759
+ function ensurePrivateOwnedDirectory(dirPath, label) {
2760
+ fs.mkdirSync(dirPath, { recursive: true, mode: 448 });
2761
+ const stats = fs.lstatSync(dirPath);
2762
+ if (stats.isSymbolicLink()) {
2763
+ throw new Error(`${label} must not be a symbolic link: ${dirPath}`);
2764
+ }
2765
+ if (!stats.isDirectory()) {
2766
+ throw new Error(`${label} must be a directory: ${dirPath}`);
2767
+ }
2768
+ if (typeof process.getuid === "function" && stats.uid !== process.getuid()) {
2769
+ throw new Error(`${label} is owned by another user: ${dirPath}`);
2770
+ }
2771
+ if (process.platform !== "win32") {
2772
+ fs.chmodSync(dirPath, 448);
2773
+ }
2774
+ }
2775
+ function ensureChatLabTempRoot(options2 = {}) {
2776
+ const root = resolveChatLabTempRoot(options2);
2777
+ ensurePrivateOwnedDirectory(root, "ChatLab temp root");
2778
+ optionsEnv(options2)[CHATLAB_TEMP_ROOT_ENV] = root;
2779
+ return root;
2780
+ }
2781
+ function assertValidScope(scope) {
2782
+ if (!CHATLAB_TEMP_SCOPES.has(scope)) {
2783
+ throw new Error(`Invalid ChatLab temp scope: ${scope}`);
2784
+ }
2785
+ }
2786
+ function assertValidPrefix(prefix) {
2787
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(prefix)) {
2788
+ throw new Error(`Invalid ChatLab temp prefix: ${prefix}`);
2789
+ }
2790
+ }
2791
+ function getChatLabTempScopeDir(scope, options2 = {}) {
2792
+ assertValidScope(scope);
2793
+ const scopeDir = path.join(ensureChatLabTempRoot(options2), scope);
2794
+ ensurePrivateOwnedDirectory(scopeDir, "ChatLab temp scope");
2795
+ return scopeDir;
2796
+ }
2797
+ function createChatLabTempDir(scope, prefix, options2 = {}) {
2798
+ assertValidPrefix(prefix);
2799
+ return fs.mkdtempSync(path.join(getChatLabTempScopeDir(scope, options2), prefix));
2800
+ }
2801
+ function removeChatLabTempDir(dirPath, scope, options2 = {}) {
2802
+ const scopeDir = path.resolve(getChatLabTempScopeDir(scope, options2));
2803
+ const resolvedDir = path.resolve(dirPath);
2804
+ if (path.dirname(resolvedDir) !== scopeDir) {
2805
+ throw new Error(`Refusing to remove non-owned ChatLab temp directory: ${resolvedDir}`);
2806
+ }
2807
+ fs.rmSync(resolvedDir, { recursive: true, force: true });
2808
+ }
2809
+
2741
2810
  // ../../packages/node-runtime/src/import/write-parse-result.ts
2742
2811
  function writeParseResultToDb(db, meta, members, messages) {
2743
2812
  let messageCount = 0;
@@ -2852,28 +2921,28 @@ function writeParseResultToDb(db, meta, members, messages) {
2852
2921
  }
2853
2922
 
2854
2923
  // ../../packages/parser/src/index.ts
2855
- import * as fs17 from "fs";
2856
- import * as path13 from "path";
2924
+ import * as fs18 from "fs";
2925
+ import * as path14 from "path";
2857
2926
 
2858
2927
  // ../../packages/parser/src/sniffer.ts
2859
- import * as fs from "fs";
2860
- import * as path from "path";
2928
+ import * as fs2 from "fs";
2929
+ import * as path2 from "path";
2861
2930
  var HEAD_SIZE = 64 * 1024;
2862
2931
  function readFileHead(filePath, size = HEAD_SIZE) {
2863
- const fd = fs.openSync(filePath, "r");
2932
+ const fd = fs2.openSync(filePath, "r");
2864
2933
  const buffer = Buffer.alloc(size);
2865
- const bytesRead = fs.readSync(fd, buffer, 0, size, 0);
2866
- fs.closeSync(fd);
2934
+ const bytesRead = fs2.readSync(fd, buffer, 0, size, 0);
2935
+ fs2.closeSync(fd);
2867
2936
  return buffer.slice(0, bytesRead).toString("utf-8");
2868
2937
  }
2869
2938
  function getExtension(filePath) {
2870
- return path.extname(filePath).toLowerCase();
2939
+ return path2.extname(filePath).toLowerCase();
2871
2940
  }
2872
2941
  function matchHeadSignatures(headContent, patterns) {
2873
2942
  return patterns.some((pattern) => pattern.test(headContent));
2874
2943
  }
2875
2944
  function matchFilenameSignatures(filePath, patterns) {
2876
- const filename = path.basename(filePath);
2945
+ const filename = path2.basename(filePath);
2877
2946
  return patterns.some((pattern) => pattern.test(filename));
2878
2947
  }
2879
2948
  function matchRequiredFields(headContent, fields) {
@@ -3021,18 +3090,18 @@ var import_stream_json = __toESM(require_stream_json(), 1);
3021
3090
  var import_Pick = __toESM(require_Pick(), 1);
3022
3091
  var import_StreamValues = __toESM(require_StreamValues(), 1);
3023
3092
  var import_stream_chain = __toESM(require_stream_chain(), 1);
3024
- import * as fs3 from "fs";
3093
+ import * as fs4 from "fs";
3025
3094
 
3026
3095
  // ../../packages/parser/src/utils.ts
3027
- import * as fs2 from "fs";
3096
+ import * as fs3 from "fs";
3028
3097
  function getFileSize(filePath) {
3029
- return fs2.statSync(filePath).size;
3098
+ return fs3.statSync(filePath).size;
3030
3099
  }
3031
3100
  function readFileHeadBytes(filePath, size) {
3032
- const fd = fs2.openSync(filePath, "r");
3101
+ const fd = fs3.openSync(filePath, "r");
3033
3102
  const buffer = Buffer.alloc(size);
3034
- const bytesRead = fs2.readSync(fd, buffer, 0, size, 0);
3035
- fs2.closeSync(fd);
3103
+ const bytesRead = fs3.readSync(fd, buffer, 0, size, 0);
3104
+ fs3.closeSync(fd);
3036
3105
  return buffer.slice(0, bytesRead).toString("utf-8");
3037
3106
  }
3038
3107
  var createProgress = (stage, bytesRead, totalBytes, messagesProcessed, message) => {
@@ -3062,7 +3131,7 @@ function isValidYear(timestampSeconds) {
3062
3131
  }
3063
3132
 
3064
3133
  // ../../packages/parser/src/formats/chatlab.ts
3065
- import * as path2 from "path";
3134
+ import * as path3 from "path";
3066
3135
 
3067
3136
  // ../../packages/parser/src/native/loader.ts
3068
3137
  import { createRequire } from "module";
@@ -3145,7 +3214,7 @@ async function* pumpNativeParser(adapter, options2, parser11, fallback) {
3145
3214
  if (!batch) break;
3146
3215
  messagesProcessed += batch.length;
3147
3216
  yield { type: "messages", data: batch.map((message) => adapter.mapMessage(message, metaJson)) };
3148
- await new Promise((resolve2) => setImmediate(resolve2));
3217
+ await new Promise((resolve4) => setImmediate(resolve4));
3149
3218
  }
3150
3219
  const doneProgress = createProgress("done", totalBytes, totalBytes, messagesProcessed, "");
3151
3220
  yield { type: "progress", data: doneProgress };
@@ -3243,7 +3312,7 @@ var { pick } = import_Pick.default;
3243
3312
  var { streamValues } = import_StreamValues.default;
3244
3313
  var { chain } = import_stream_chain.default;
3245
3314
  function extractNameFromFilePath(filePath) {
3246
- const basename13 = path2.basename(filePath);
3315
+ const basename13 = path3.basename(filePath);
3247
3316
  const name = basename13.replace(/\.json$/i, "");
3248
3317
  return name || "\u672A\u77E5\u7FA4\u804A";
3249
3318
  }
@@ -3317,8 +3386,8 @@ async function* parseChatLab(options2) {
3317
3386
  const members = [];
3318
3387
  const memberMapFromMessages = /* @__PURE__ */ new Map();
3319
3388
  const messageBatch = [];
3320
- await new Promise((resolve2, reject) => {
3321
- const readStream = fs3.createReadStream(filePath, { encoding: "utf-8" });
3389
+ await new Promise((resolve4, reject) => {
3390
+ const readStream = fs4.createReadStream(filePath, { encoding: "utf-8" });
3322
3391
  readStream.on("data", (chunk) => {
3323
3392
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
3324
3393
  });
@@ -3372,7 +3441,7 @@ async function* parseChatLab(options2) {
3372
3441
  if (batchCollector.length > 0) {
3373
3442
  messageBatch.push(...batchCollector);
3374
3443
  }
3375
- resolve2();
3444
+ resolve4();
3376
3445
  });
3377
3446
  pipeline2.on("error", reject);
3378
3447
  });
@@ -3410,11 +3479,11 @@ var module_ = {
3410
3479
  var chatlab_default = module_;
3411
3480
 
3412
3481
  // ../../packages/parser/src/formats/chatlab-jsonl.ts
3413
- import * as fs4 from "fs";
3482
+ import * as fs5 from "fs";
3414
3483
  import * as readline from "readline";
3415
- import * as path3 from "path";
3484
+ import * as path4 from "path";
3416
3485
  function extractNameFromFilePath2(filePath) {
3417
- const basename13 = path3.basename(filePath);
3486
+ const basename13 = path4.basename(filePath);
3418
3487
  const name = basename13.replace(/\.jsonl$/i, "");
3419
3488
  return name || "\u672A\u77E5\u7FA4\u804A";
3420
3489
  }
@@ -3455,7 +3524,7 @@ async function* parseChatLabJsonl(options2) {
3455
3524
  const messageBatch = [];
3456
3525
  let meta = null;
3457
3526
  let headerParsed = false;
3458
- const fileStream = fs4.createReadStream(filePath, { encoding: "utf-8" });
3527
+ const fileStream = fs5.createReadStream(filePath, { encoding: "utf-8" });
3459
3528
  const rl = readline.createInterface({
3460
3529
  input: fileStream,
3461
3530
  crlfDelay: Infinity
@@ -3580,28 +3649,30 @@ var import_stream_json3 = __toESM(require_stream_json(), 1);
3580
3649
  var import_Pick3 = __toESM(require_Pick(), 1);
3581
3650
  var import_StreamValues3 = __toESM(require_StreamValues(), 1);
3582
3651
  var import_stream_chain3 = __toESM(require_stream_chain(), 1);
3583
- import * as fs6 from "fs";
3584
- import * as path5 from "path";
3652
+ import * as fs7 from "fs";
3653
+ import * as path6 from "path";
3585
3654
 
3586
3655
  // ../../packages/parser/src/formats/shuakami-qq-preprocessor.ts
3587
3656
  var import_stream_json2 = __toESM(require_stream_json(), 1);
3588
3657
  var import_Pick2 = __toESM(require_Pick(), 1);
3589
3658
  var import_StreamValues2 = __toESM(require_StreamValues(), 1);
3590
3659
  var import_stream_chain2 = __toESM(require_stream_chain(), 1);
3591
- import * as fs5 from "fs";
3592
- import * as path4 from "path";
3593
- import * as os from "os";
3660
+ import * as fs6 from "fs";
3661
+ import * as path5 from "path";
3662
+ import * as os2 from "os";
3594
3663
  var { parser: parser3 } = import_stream_json2.default;
3595
3664
  var { pick: pick2 } = import_Pick2.default;
3596
3665
  var { streamValues: streamValues2 } = import_StreamValues2.default;
3597
3666
  var { chain: chain2 } = import_stream_chain2.default;
3598
3667
  var PREPROCESS_THRESHOLD = 50 * 1024 * 1024;
3599
3668
  function getTempDir() {
3600
- return path4.join(os.tmpdir(), "chatlab");
3669
+ const configuredRoot = process.env.CHATLAB_TEMP_ROOT?.trim();
3670
+ const root = configuredRoot ? path5.resolve(configuredRoot) : path5.resolve(process.platform === "darwin" ? "/private/tmp/chatlab" : path5.join(os2.tmpdir(), "chatlab"));
3671
+ return path5.join(root, "parser");
3601
3672
  }
3602
3673
  function ensureDir(dir) {
3603
- if (!fs5.existsSync(dir)) {
3604
- fs5.mkdirSync(dir, { recursive: true });
3674
+ if (!fs6.existsSync(dir)) {
3675
+ fs6.mkdirSync(dir, { recursive: true, mode: 448 });
3605
3676
  }
3606
3677
  }
3607
3678
  function extractJsonObject(content, key) {
@@ -3643,12 +3714,12 @@ function extractJsonObject(content, key) {
3643
3714
  }
3644
3715
  function readAvatarsFromFile(filePath) {
3645
3716
  try {
3646
- const stats = fs5.statSync(filePath);
3717
+ const stats = fs6.statSync(filePath);
3647
3718
  const tailSize = Math.min(stats.size, 5e6);
3648
- const fd = fs5.openSync(filePath, "r");
3719
+ const fd = fs6.openSync(filePath, "r");
3649
3720
  const buffer = Buffer.alloc(tailSize);
3650
- fs5.readSync(fd, buffer, 0, tailSize, stats.size - tailSize);
3651
- fs5.closeSync(fd);
3721
+ fs6.readSync(fd, buffer, 0, tailSize, stats.size - tailSize);
3722
+ fs6.closeSync(fd);
3652
3723
  const tailContent = buffer.toString("utf-8");
3653
3724
  return extractJsonObject(tailContent, "avatars");
3654
3725
  } catch {
@@ -3707,15 +3778,15 @@ async function preprocessQQJson(inputPath, onProgress) {
3707
3778
  let messagesProcessed = 0;
3708
3779
  const tempDir = getTempDir();
3709
3780
  ensureDir(tempDir);
3710
- const outputFilename = `slim_${Date.now()}_${path4.basename(inputPath)}`;
3711
- const outputPath = path4.join(tempDir, outputFilename);
3781
+ const outputFilename = `slim_${Date.now()}_${path5.basename(inputPath)}`;
3782
+ const outputPath = path5.join(tempDir, outputFilename);
3712
3783
  onProgress?.(createProgress("parsing", 0, totalBytes, 0, ""));
3713
3784
  const avatarsStr = readAvatarsFromFile(inputPath);
3714
- return new Promise((resolve2, reject) => {
3785
+ return new Promise((resolve4, reject) => {
3715
3786
  const headChunks = [];
3716
3787
  let headSize = 0;
3717
3788
  const maxHeadSize = 1e5;
3718
- const headStream = fs5.createReadStream(inputPath, { encoding: "utf-8" });
3789
+ const headStream = fs6.createReadStream(inputPath, { encoding: "utf-8" });
3719
3790
  let chatInfo = { name: "\u672A\u77E5\u7FA4\u804A", type: "group" };
3720
3791
  let metadata;
3721
3792
  let statistics;
@@ -3752,8 +3823,8 @@ async function preprocessQQJson(inputPath, onProgress) {
3752
3823
  } catch {
3753
3824
  }
3754
3825
  onProgress?.(createProgress("parsing", 0, totalBytes, 0, ""));
3755
- const readStream = fs5.createReadStream(inputPath, { encoding: "utf-8" });
3756
- const writeStream = fs5.createWriteStream(outputPath, { encoding: "utf-8" });
3826
+ const readStream = fs6.createReadStream(inputPath, { encoding: "utf-8" });
3827
+ const writeStream = fs6.createWriteStream(outputPath, { encoding: "utf-8" });
3757
3828
  readStream.on("data", (chunk) => {
3758
3829
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
3759
3830
  });
@@ -3793,13 +3864,13 @@ async function preprocessQQJson(inputPath, onProgress) {
3793
3864
  writeStream.end();
3794
3865
  writeStream.on("finish", () => {
3795
3866
  onProgress?.(createProgress("done", totalBytes, totalBytes, messagesProcessed, ""));
3796
- resolve2(outputPath);
3867
+ resolve4(outputPath);
3797
3868
  });
3798
3869
  });
3799
3870
  pipeline2.on("error", (err) => {
3800
3871
  writeStream.destroy();
3801
- if (fs5.existsSync(outputPath)) {
3802
- fs5.unlinkSync(outputPath);
3872
+ if (fs6.existsSync(outputPath)) {
3873
+ fs6.unlinkSync(outputPath);
3803
3874
  }
3804
3875
  onProgress?.(createProgress("error", bytesRead, totalBytes, messagesProcessed, err.message));
3805
3876
  reject(err);
@@ -3810,8 +3881,8 @@ async function preprocessQQJson(inputPath, onProgress) {
3810
3881
  }
3811
3882
  function cleanupTempFile(filePath) {
3812
3883
  try {
3813
- if (fs5.existsSync(filePath) && filePath.includes(getTempDir())) {
3814
- fs5.unlinkSync(filePath);
3884
+ if (fs6.existsSync(filePath) && path5.dirname(path5.resolve(filePath)) === path5.resolve(getTempDir())) {
3885
+ fs6.unlinkSync(filePath);
3815
3886
  }
3816
3887
  } catch {
3817
3888
  }
@@ -3878,7 +3949,7 @@ function extractJsonObject2(content, key) {
3878
3949
  return null;
3879
3950
  }
3880
3951
  function extractNameFromFilePath3(filePath) {
3881
- const basename13 = path5.basename(filePath);
3952
+ const basename13 = path6.basename(filePath);
3882
3953
  return basename13.replace(/\.json$/i, "") || "\u672A\u77E5\u7FA4\u804A";
3883
3954
  }
3884
3955
  function isPlaceholderSenderId(id) {
@@ -3975,8 +4046,8 @@ async function* parseV4(options2) {
3975
4046
  yield { type: "meta", data: meta };
3976
4047
  const memberMap = /* @__PURE__ */ new Map();
3977
4048
  const messageBatch = [];
3978
- await new Promise((resolve2, reject) => {
3979
- const readStream = fs6.createReadStream(filePath, { encoding: "utf-8" });
4049
+ await new Promise((resolve4, reject) => {
4050
+ const readStream = fs7.createReadStream(filePath, { encoding: "utf-8" });
3980
4051
  readStream.on("data", (chunk) => {
3981
4052
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
3982
4053
  });
@@ -4031,17 +4102,17 @@ async function* parseV4(options2) {
4031
4102
  onProgress?.(progress);
4032
4103
  }
4033
4104
  });
4034
- pipeline2.on("end", resolve2);
4105
+ pipeline2.on("end", resolve4);
4035
4106
  pipeline2.on("error", reject);
4036
4107
  });
4037
4108
  const avatarsMap = /* @__PURE__ */ new Map();
4038
4109
  try {
4039
- const stats = fs6.statSync(filePath);
4110
+ const stats = fs7.statSync(filePath);
4040
4111
  const tailSize = Math.min(stats.size, 5e6);
4041
- const fd = fs6.openSync(filePath, "r");
4112
+ const fd = fs7.openSync(filePath, "r");
4042
4113
  const buffer = Buffer.alloc(tailSize);
4043
- fs6.readSync(fd, buffer, 0, tailSize, stats.size - tailSize);
4044
- fs6.closeSync(fd);
4114
+ fs7.readSync(fd, buffer, 0, tailSize, stats.size - tailSize);
4115
+ fs7.closeSync(fd);
4045
4116
  const tailContent = buffer.toString("utf-8");
4046
4117
  const avatarsStr = extractJsonObject2(tailContent, "avatars");
4047
4118
  if (avatarsStr) {
@@ -4093,8 +4164,8 @@ var module_3 = {
4093
4164
  var shuakami_qq_exporter_default = module_3;
4094
4165
 
4095
4166
  // ../../packages/parser/src/formats/shuakami-qq-exporter-chunked.ts
4096
- import * as fs7 from "fs";
4097
- import * as path6 from "path";
4167
+ import * as fs8 from "fs";
4168
+ import * as path7 from "path";
4098
4169
  import * as readline2 from "readline";
4099
4170
  var feature4 = {
4100
4171
  id: "shuakami-qq-exporter-chunked",
@@ -4143,7 +4214,7 @@ function convertMessageType2(msgType, content, isRecalled) {
4143
4214
  return 0 /* TEXT */;
4144
4215
  }
4145
4216
  function readManifest(manifestPath) {
4146
- const content = fs7.readFileSync(manifestPath, "utf-8");
4217
+ const content = fs8.readFileSync(manifestPath, "utf-8");
4147
4218
  return JSON.parse(content);
4148
4219
  }
4149
4220
  function getChunkRelativePath(chunk) {
@@ -4161,9 +4232,9 @@ function calculateTotalBytes(manifest, baseDir) {
4161
4232
  let total = 0;
4162
4233
  for (const chunk of manifest.chunked.chunks) {
4163
4234
  const relativePath = getChunkRelativePath(chunk);
4164
- const chunkPath = path6.join(baseDir, relativePath);
4165
- if (fs7.existsSync(chunkPath)) {
4166
- total += fs7.statSync(chunkPath).size;
4235
+ const chunkPath = path7.join(baseDir, relativePath);
4236
+ if (fs8.existsSync(chunkPath)) {
4237
+ total += fs8.statSync(chunkPath).size;
4167
4238
  }
4168
4239
  }
4169
4240
  return total;
@@ -4171,10 +4242,10 @@ function calculateTotalBytes(manifest, baseDir) {
4171
4242
  function readAvatars(baseDir, avatarsInfo) {
4172
4243
  const avatarsMap = /* @__PURE__ */ new Map();
4173
4244
  if (!avatarsInfo?.file) return avatarsMap;
4174
- const avatarsPath = path6.join(baseDir, avatarsInfo.file);
4175
- if (!fs7.existsSync(avatarsPath)) return avatarsMap;
4245
+ const avatarsPath = path7.join(baseDir, avatarsInfo.file);
4246
+ if (!fs8.existsSync(avatarsPath)) return avatarsMap;
4176
4247
  try {
4177
- const content = fs7.readFileSync(avatarsPath, "utf-8");
4248
+ const content = fs8.readFileSync(avatarsPath, "utf-8");
4178
4249
  const avatars = JSON.parse(content);
4179
4250
  for (const [uin, avatar] of Object.entries(avatars)) {
4180
4251
  if (avatar && typeof avatar === "string" && avatar.startsWith("data:image/")) {
@@ -4192,7 +4263,7 @@ async function* readJsonlFile(filePath, onParseError) {
4192
4263
  let parseErrorCount = 0;
4193
4264
  const MAX_PARSE_ERRORS_TO_LOG = 10;
4194
4265
  try {
4195
- fileStream = fs7.createReadStream(filePath, { encoding: "utf-8" });
4266
+ fileStream = fs8.createReadStream(filePath, { encoding: "utf-8" });
4196
4267
  rl = readline2.createInterface({
4197
4268
  input: fileStream,
4198
4269
  crlfDelay: Infinity
@@ -4223,7 +4294,7 @@ async function* readJsonlFile(filePath, onParseError) {
4223
4294
  async function* parseChunkedJsonl(options2) {
4224
4295
  const { filePath, batchSize = 5e3, onProgress, onLog } = options2;
4225
4296
  const manifestPath = filePath;
4226
- const baseDir = path6.dirname(manifestPath);
4297
+ const baseDir = path7.dirname(manifestPath);
4227
4298
  onLog?.("info", `\u5F00\u59CB\u89E3\u6790 manifest: ${manifestPath}`);
4228
4299
  onLog?.("info", `\u57FA\u7840\u76EE\u5F55: ${baseDir}`);
4229
4300
  let manifest;
@@ -4277,13 +4348,13 @@ async function* parseChunkedJsonl(options2) {
4277
4348
  for (let chunkIndex = 0; chunkIndex < manifest.chunked.chunks.length; chunkIndex++) {
4278
4349
  const chunkInfo = manifest.chunked.chunks[chunkIndex];
4279
4350
  const relativePath = getChunkRelativePath(chunkInfo);
4280
- const chunkPath = path6.join(baseDir, relativePath);
4351
+ const chunkPath = path7.join(baseDir, relativePath);
4281
4352
  const chunkMessageCount = getChunkMessageCount(chunkInfo);
4282
- if (!fs7.existsSync(chunkPath)) {
4353
+ if (!fs8.existsSync(chunkPath)) {
4283
4354
  onLog?.("error", `\u5206\u5757\u6587\u4EF6\u4E0D\u5B58\u5728: ${chunkPath}`);
4284
4355
  continue;
4285
4356
  }
4286
- const chunkSize = fs7.statSync(chunkPath).size;
4357
+ const chunkSize = fs8.statSync(chunkPath).size;
4287
4358
  let chunkMessagesRead = 0;
4288
4359
  let chunkParseErrors = 0;
4289
4360
  onLog?.(
@@ -4405,8 +4476,8 @@ var import_stream_json4 = __toESM(require_stream_json(), 1);
4405
4476
  var import_Pick4 = __toESM(require_Pick(), 1);
4406
4477
  var import_StreamValues4 = __toESM(require_StreamValues(), 1);
4407
4478
  var import_stream_chain4 = __toESM(require_stream_chain(), 1);
4408
- import * as fs8 from "fs";
4409
- import * as path7 from "path";
4479
+ import * as fs9 from "fs";
4480
+ import * as path8 from "path";
4410
4481
 
4411
4482
  // ../../packages/parser/src/native/weflow-native.ts
4412
4483
  var weflowAdapter = {
@@ -4479,7 +4550,7 @@ var { pick: pick4 } = import_Pick4.default;
4479
4550
  var { streamValues: streamValues4 } = import_StreamValues4.default;
4480
4551
  var { chain: chain4 } = import_stream_chain4.default;
4481
4552
  function extractNameFromFilePath4(filePath) {
4482
- const basename13 = path7.basename(filePath);
4553
+ const basename13 = path8.basename(filePath);
4483
4554
  const name = basename13.replace(/\.json$/i, "");
4484
4555
  return name || "\u672A\u77E5\u804A\u5929";
4485
4556
  }
@@ -4547,8 +4618,8 @@ async function* parseWeFlow(options2) {
4547
4618
  const headContent = readFileHeadBytes(filePath, 5e3);
4548
4619
  let session = null;
4549
4620
  try {
4550
- await new Promise((resolve2) => {
4551
- const sessionStream = fs8.createReadStream(filePath, { encoding: "utf-8" });
4621
+ await new Promise((resolve4) => {
4622
+ const sessionStream = fs9.createReadStream(filePath, { encoding: "utf-8" });
4552
4623
  let sessionContent = "";
4553
4624
  let inSession = false;
4554
4625
  let braceDepth = 0;
@@ -4599,9 +4670,9 @@ async function* parseWeFlow(options2) {
4599
4670
  } catch {
4600
4671
  }
4601
4672
  }
4602
- resolve2();
4673
+ resolve4();
4603
4674
  });
4604
- sessionStream.on("error", () => resolve2());
4675
+ sessionStream.on("error", () => resolve4());
4605
4676
  });
4606
4677
  } catch {
4607
4678
  }
@@ -4670,8 +4741,8 @@ async function* parseWeFlow(options2) {
4670
4741
  }
4671
4742
  if (avatarsMap.size === 0) {
4672
4743
  try {
4673
- await new Promise((resolve2) => {
4674
- const avatarStream = fs8.createReadStream(filePath, { encoding: "utf-8" });
4744
+ await new Promise((resolve4) => {
4745
+ const avatarStream = fs9.createReadStream(filePath, { encoding: "utf-8" });
4675
4746
  let avatarsContent = "";
4676
4747
  let inAvatars = false;
4677
4748
  let braceDepth = 0;
@@ -4727,9 +4798,9 @@ async function* parseWeFlow(options2) {
4727
4798
  } catch {
4728
4799
  }
4729
4800
  }
4730
- resolve2();
4801
+ resolve4();
4731
4802
  });
4732
- avatarStream.on("error", () => resolve2());
4803
+ avatarStream.on("error", () => resolve4());
4733
4804
  });
4734
4805
  } catch {
4735
4806
  }
@@ -4737,8 +4808,8 @@ async function* parseWeFlow(options2) {
4737
4808
  const groupAvatar = sessionData?.avatar || (groupId ? avatarsMap.get(groupId) : void 0);
4738
4809
  let ownerId;
4739
4810
  try {
4740
- await new Promise((resolve2) => {
4741
- const scanStream = fs8.createReadStream(filePath, { encoding: "utf-8" });
4811
+ await new Promise((resolve4) => {
4812
+ const scanStream = fs9.createReadStream(filePath, { encoding: "utf-8" });
4742
4813
  const scanPipeline = chain4([scanStream, parser5(), pick4({ filter: /^messages\.\d+$/ }), streamValues4()]);
4743
4814
  scanPipeline.on("data", ({ value }) => {
4744
4815
  if (value.isSend === 1 && value.senderUsername && !value.senderUsername.endsWith("@chatroom")) {
@@ -4746,9 +4817,9 @@ async function* parseWeFlow(options2) {
4746
4817
  scanStream.destroy();
4747
4818
  }
4748
4819
  });
4749
- scanStream.on("close", () => resolve2());
4750
- scanPipeline.on("end", () => resolve2());
4751
- scanPipeline.on("error", () => resolve2());
4820
+ scanStream.on("close", () => resolve4());
4821
+ scanPipeline.on("end", () => resolve4());
4822
+ scanPipeline.on("error", () => resolve4());
4752
4823
  });
4753
4824
  } catch {
4754
4825
  }
@@ -4763,8 +4834,8 @@ async function* parseWeFlow(options2) {
4763
4834
  yield { type: "meta", data: meta };
4764
4835
  const memberMap = /* @__PURE__ */ new Map();
4765
4836
  const messageBatch = [];
4766
- await new Promise((resolve2, reject) => {
4767
- const readStream = fs8.createReadStream(filePath, { encoding: "utf-8" });
4837
+ await new Promise((resolve4, reject) => {
4838
+ const readStream = fs9.createReadStream(filePath, { encoding: "utf-8" });
4768
4839
  readStream.on("data", (chunk) => {
4769
4840
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
4770
4841
  });
@@ -4836,7 +4907,7 @@ async function* parseWeFlow(options2) {
4836
4907
  if (batchCollector.length > 0) {
4837
4908
  messageBatch.push(...batchCollector);
4838
4909
  }
4839
- resolve2();
4910
+ resolve4();
4840
4911
  });
4841
4912
  pipeline2.on("error", reject);
4842
4913
  });
@@ -4901,7 +4972,7 @@ var import_stream_json5 = __toESM(require_stream_json(), 1);
4901
4972
  var import_Pick5 = __toESM(require_Pick(), 1);
4902
4973
  var import_StreamValues5 = __toESM(require_StreamValues(), 1);
4903
4974
  var import_stream_chain5 = __toESM(require_stream_chain(), 1);
4904
- import * as fs9 from "fs";
4975
+ import * as fs10 from "fs";
4905
4976
  var { parser: parser6 } = import_stream_json5.default;
4906
4977
  var { pick: pick5 } = import_Pick5.default;
4907
4978
  var { streamValues: streamValues5 } = import_StreamValues5.default;
@@ -5050,8 +5121,8 @@ async function* parseDiscordExporter(options2) {
5050
5121
  onLog?.("info", `\u7FA4\u804A\u540D\u79F0: ${chatName}`);
5051
5122
  const memberMap = /* @__PURE__ */ new Map();
5052
5123
  const messageBatch = [];
5053
- await new Promise((resolve2, reject) => {
5054
- const readStream = fs9.createReadStream(filePath, { encoding: "utf-8" });
5124
+ await new Promise((resolve4, reject) => {
5125
+ const readStream = fs10.createReadStream(filePath, { encoding: "utf-8" });
5055
5126
  readStream.on("data", (chunk) => {
5056
5127
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
5057
5128
  });
@@ -5129,7 +5200,7 @@ ${stickerTexts.join("\n")}` : stickerTexts.join("\n");
5129
5200
  if (batchCollector.length > 0) {
5130
5201
  messageBatch.push(...batchCollector);
5131
5202
  }
5132
- resolve2();
5203
+ resolve4();
5133
5204
  });
5134
5205
  pipeline2.on("error", reject);
5135
5206
  });
@@ -5167,7 +5238,7 @@ var import_stream_chain6 = __toESM(require_stream_chain(), 1);
5167
5238
  var import_stream_json6 = __toESM(require_stream_json(), 1);
5168
5239
  var import_Pick6 = __toESM(require_Pick(), 1);
5169
5240
  var import_StreamValues6 = __toESM(require_StreamValues(), 1);
5170
- import * as fs10 from "fs";
5241
+ import * as fs11 from "fs";
5171
5242
 
5172
5243
  // ../../packages/parser/src/formats/utils/telegram-utils.ts
5173
5244
  function mapChatType(telegramType) {
@@ -5252,8 +5323,8 @@ var feature8 = {
5252
5323
  };
5253
5324
  async function scanChats(filePath) {
5254
5325
  const chats = [];
5255
- return new Promise((resolve2, reject) => {
5256
- const readStream = fs10.createReadStream(filePath, { encoding: "utf-8" });
5326
+ return new Promise((resolve4, reject) => {
5327
+ const readStream = fs11.createReadStream(filePath, { encoding: "utf-8" });
5257
5328
  const pipeline2 = chain6([readStream, parser7(), pick6({ filter: /^chats\.list\.\d+$/ }), streamValues6()]);
5258
5329
  pipeline2.on("data", ({ value }) => {
5259
5330
  const chat = value;
@@ -5266,7 +5337,7 @@ async function scanChats(filePath) {
5266
5337
  });
5267
5338
  });
5268
5339
  pipeline2.on("end", () => {
5269
- resolve2(chats);
5340
+ resolve4(chats);
5270
5341
  });
5271
5342
  pipeline2.on("error", (err) => {
5272
5343
  reject(new Error(`\u626B\u63CF Telegram \u6587\u4EF6\u5931\u8D25: ${err.message}`));
@@ -5285,8 +5356,8 @@ async function* parseTelegram(options2) {
5285
5356
  onLog?.("info", `\u5F00\u59CB\u89E3\u6790 Telegram JSON \u6587\u4EF6\uFF0C\u5927\u5C0F: ${(totalBytes / 1024 / 1024).toFixed(2)} MB`);
5286
5357
  onLog?.("info", `\u76EE\u6807\u804A\u5929\u7D22\u5F15: ${chatIndex}`);
5287
5358
  const chatPathFilter = `chats.list.${chatIndex}`;
5288
- const chatData = await new Promise((resolve2, reject) => {
5289
- const readStream = fs10.createReadStream(filePath, { encoding: "utf-8" });
5359
+ const chatData = await new Promise((resolve4, reject) => {
5360
+ const readStream = fs11.createReadStream(filePath, { encoding: "utf-8" });
5290
5361
  readStream.on("data", (chunk) => {
5291
5362
  bytesRead += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
5292
5363
  });
@@ -5299,10 +5370,10 @@ async function* parseTelegram(options2) {
5299
5370
  let found = false;
5300
5371
  pipeline2.on("data", ({ value }) => {
5301
5372
  found = true;
5302
- resolve2(value);
5373
+ resolve4(value);
5303
5374
  });
5304
5375
  pipeline2.on("end", () => {
5305
- if (!found) resolve2(null);
5376
+ if (!found) resolve4(null);
5306
5377
  });
5307
5378
  pipeline2.on("error", reject);
5308
5379
  });
@@ -5394,7 +5465,7 @@ var telegram_native_default = module_8;
5394
5465
  var import_stream_chain7 = __toESM(require_stream_chain(), 1);
5395
5466
  var import_stream_json7 = __toESM(require_stream_json(), 1);
5396
5467
  var import_StreamValues7 = __toESM(require_StreamValues(), 1);
5397
- import * as fs11 from "fs";
5468
+ import * as fs12 from "fs";
5398
5469
  var { chain: chain7 } = import_stream_chain7.default;
5399
5470
  var { parser: parser8 } = import_stream_json7.default;
5400
5471
  var { streamValues: streamValues7 } = import_StreamValues7.default;
@@ -5423,18 +5494,18 @@ async function* parseTelegramSingle(options2) {
5423
5494
  yield { type: "progress", data: initialProgress };
5424
5495
  onProgress?.(initialProgress);
5425
5496
  onLog?.("info", `\u5F00\u59CB\u89E3\u6790 Telegram \u5355\u804A\u5929 JSON \u6587\u4EF6\uFF0C\u5927\u5C0F: ${(totalBytes / 1024 / 1024).toFixed(2)} MB`);
5426
- const chatData = await new Promise((resolve2, reject) => {
5427
- const readStream = fs11.createReadStream(filePath, { encoding: "utf-8" });
5497
+ const chatData = await new Promise((resolve4, reject) => {
5498
+ const readStream = fs12.createReadStream(filePath, { encoding: "utf-8" });
5428
5499
  const pipeline2 = chain7([readStream, parser8(), streamValues7()]);
5429
5500
  let found = false;
5430
5501
  pipeline2.on("data", ({ value }) => {
5431
5502
  if (!found) {
5432
5503
  found = true;
5433
- resolve2(value);
5504
+ resolve4(value);
5434
5505
  }
5435
5506
  });
5436
5507
  pipeline2.on("end", () => {
5437
- if (!found) resolve2(null);
5508
+ if (!found) resolve4(null);
5438
5509
  });
5439
5510
  pipeline2.on("error", reject);
5440
5511
  });
@@ -5522,11 +5593,11 @@ var module_9 = {
5522
5593
  var telegram_native_single_default = module_9;
5523
5594
 
5524
5595
  // ../../packages/parser/src/formats/whatsapp-native-txt.ts
5525
- import * as fs12 from "fs";
5526
- import * as path8 from "path";
5596
+ import * as fs13 from "fs";
5597
+ import * as path9 from "path";
5527
5598
  import * as readline3 from "readline";
5528
5599
  function extractNameFromFilePath5(filePath) {
5529
- const basename13 = path8.basename(filePath);
5600
+ const basename13 = path9.basename(filePath);
5530
5601
  const matchZhCn = basename13.match(/^与(.+?)的\s*WhatsApp\s*聊天\.txt$/i);
5531
5602
  if (matchZhCn) return matchZhCn[1].trim();
5532
5603
  const matchZhTw = basename13.match(/^與(.+?)的\s*WhatsApp\s*對話\.txt$/i);
@@ -5534,7 +5605,7 @@ function extractNameFromFilePath5(filePath) {
5534
5605
  return basename13.replace(/\.txt$/i, "") || "\u672A\u77E5\u804A\u5929";
5535
5606
  }
5536
5607
  function shouldInferPrivateChatName(filePath, fallbackName) {
5537
- const basename13 = path8.basename(filePath);
5608
+ const basename13 = path9.basename(filePath);
5538
5609
  return /^_chat\.txt$/i.test(basename13) || /^whatsapp(?:[-_\s].*)?$/i.test(fallbackName);
5539
5610
  }
5540
5611
  function inferPrivateChatName(memberMap, fallbackName) {
@@ -5713,7 +5784,7 @@ async function* parseWhatsApp(options2) {
5713
5784
  messagesProcessed++;
5714
5785
  }
5715
5786
  };
5716
- const fileStream = fs12.createReadStream(filePath, { encoding: "utf-8" });
5787
+ const fileStream = fs13.createReadStream(filePath, { encoding: "utf-8" });
5717
5788
  const rl = readline3.createInterface({
5718
5789
  input: fileStream,
5719
5790
  crlfDelay: Infinity
@@ -5834,11 +5905,11 @@ var module_10 = {
5834
5905
  var whatsapp_native_txt_default = module_10;
5835
5906
 
5836
5907
  // ../../packages/parser/src/formats/qq-native-txt.ts
5837
- import * as fs13 from "fs";
5838
- import * as path9 from "path";
5908
+ import * as fs14 from "fs";
5909
+ import * as path10 from "path";
5839
5910
  import * as readline4 from "readline";
5840
5911
  function extractNameFromFilePath6(filePath) {
5841
- const basename13 = path9.basename(filePath);
5912
+ const basename13 = path10.basename(filePath);
5842
5913
  const name = basename13.replace(/\.txt$/i, "");
5843
5914
  return name || "\u672A\u77E5\u7FA4\u804A";
5844
5915
  }
@@ -5920,7 +5991,7 @@ async function* parseTxt(options2) {
5920
5991
  messagesProcessed++;
5921
5992
  }
5922
5993
  };
5923
- const fileStream = fs13.createReadStream(filePath, { encoding: "utf-8" });
5994
+ const fileStream = fs14.createReadStream(filePath, { encoding: "utf-8" });
5924
5995
  const rl = readline4.createInterface({
5925
5996
  input: fileStream,
5926
5997
  crlfDelay: Infinity
@@ -6020,8 +6091,8 @@ var module_11 = {
6020
6091
  var qq_native_txt_default = module_11;
6021
6092
 
6022
6093
  // ../../packages/parser/src/formats/instagram-native.ts
6023
- import * as fs14 from "fs";
6024
- import * as path10 from "path";
6094
+ import * as fs15 from "fs";
6095
+ import * as path11 from "path";
6025
6096
  var feature12 = {
6026
6097
  id: "instagram-native",
6027
6098
  name: "Instagram \u5B98\u65B9\u5BFC\u51FA",
@@ -6047,7 +6118,7 @@ function decodeInstagramText(text) {
6047
6118
  }
6048
6119
  }
6049
6120
  function extractNameFromFilePath7(filePath) {
6050
- const basename13 = path10.basename(filePath);
6121
+ const basename13 = path11.basename(filePath);
6051
6122
  return basename13.replace(/\.json$/i, "") || "\u672A\u77E5\u5BF9\u8BDD";
6052
6123
  }
6053
6124
  function isSystemMessage2(content) {
@@ -6116,7 +6187,7 @@ async function* parseInstagram(options2) {
6116
6187
  onLog?.("info", `\u5F00\u59CB\u89E3\u6790 Instagram \u804A\u5929\u8BB0\u5F55\uFF0C\u5927\u5C0F: ${(totalBytes / 1024 / 1024).toFixed(2)} MB`);
6117
6188
  let data;
6118
6189
  try {
6119
- const content = fs14.readFileSync(filePath, "utf-8");
6190
+ const content = fs15.readFileSync(filePath, "utf-8");
6120
6191
  data = JSON.parse(content);
6121
6192
  } catch (error) {
6122
6193
  const err = new Error(`\u65E0\u6CD5\u89E3\u6790 Instagram JSON \u6587\u4EF6: ${error}`);
@@ -6211,8 +6282,8 @@ var import_stream_chain8 = __toESM(require_stream_chain(), 1);
6211
6282
  var import_stream_json8 = __toESM(require_stream_json(), 1);
6212
6283
  var import_Pick7 = __toESM(require_Pick(), 1);
6213
6284
  var import_StreamValues8 = __toESM(require_StreamValues(), 1);
6214
- import * as fs15 from "fs";
6215
- import * as path11 from "path";
6285
+ import * as fs16 from "fs";
6286
+ import * as path12 from "path";
6216
6287
  var { chain: chain8 } = import_stream_chain8.default;
6217
6288
  var { parser: parser9 } = import_stream_json8.default;
6218
6289
  var { pick: pick7 } = import_Pick7.default;
@@ -6295,12 +6366,12 @@ function normalizeIdentity(user) {
6295
6366
  };
6296
6367
  }
6297
6368
  function readJson(filePath) {
6298
- return JSON.parse(fs15.readFileSync(filePath, "utf8"));
6369
+ return JSON.parse(fs16.readFileSync(filePath, "utf8"));
6299
6370
  }
6300
6371
  function resolveManifestFile(manifestDir, relativePath) {
6301
- const resolved = path11.resolve(manifestDir, relativePath);
6302
- const relative2 = path11.relative(manifestDir, resolved);
6303
- if (relative2.startsWith("..") || path11.isAbsolute(relative2)) {
6372
+ const resolved = path12.resolve(manifestDir, relativePath);
6373
+ const relative2 = path12.relative(manifestDir, resolved);
6374
+ if (relative2.startsWith("..") || path12.isAbsolute(relative2)) {
6304
6375
  throw new Error(`Google Chat manifest path escapes its directory: ${relativePath}`);
6305
6376
  }
6306
6377
  return resolved;
@@ -6313,7 +6384,7 @@ function readManifest2(filePath) {
6313
6384
  if (manifest.chatType !== "private" && manifest.chatType !== "group") {
6314
6385
  throw new Error("Invalid Google Chat chat type");
6315
6386
  }
6316
- const manifestDir = path11.dirname(filePath);
6387
+ const manifestDir = path12.dirname(filePath);
6317
6388
  return {
6318
6389
  manifest,
6319
6390
  userInfoPath: resolveManifestFile(manifestDir, manifest.userInfoFile),
@@ -6391,7 +6462,7 @@ async function* parseGoogleChat(options2) {
6391
6462
  });
6392
6463
  }
6393
6464
  yield { type: "members", data: Array.from(memberMap.values()) };
6394
- const readStream = fs15.createReadStream(messagesPath, { encoding: "utf8" });
6465
+ const readStream = fs16.createReadStream(messagesPath, { encoding: "utf8" });
6395
6466
  let bytesRead = 0;
6396
6467
  let messagesProcessed = 0;
6397
6468
  readStream.on("data", (chunk) => {
@@ -6444,8 +6515,8 @@ var module_13 = {
6444
6515
  var google_chat_takeout_default = module_13;
6445
6516
 
6446
6517
  // ../../packages/parser/src/formats/line-native-txt.ts
6447
- import * as fs16 from "fs";
6448
- import * as path12 from "path";
6518
+ import * as fs17 from "fs";
6519
+ import * as path13 from "path";
6449
6520
  var feature14 = {
6450
6521
  id: "line-native-txt",
6451
6522
  name: "LINE \u5B98\u65B9\u5BFC\u51FA TXT",
@@ -6473,7 +6544,7 @@ var feature14 = {
6473
6544
  }
6474
6545
  };
6475
6546
  function extractNameFromFilePath8(filePath) {
6476
- const basename13 = path12.basename(filePath, ".txt");
6547
+ const basename13 = path13.basename(filePath, ".txt");
6477
6548
  const name = basename13.replace(/^\[LINE\]\s*/i, "").trim();
6478
6549
  return name || "\u672A\u77E5\u804A\u5929";
6479
6550
  }
@@ -6653,7 +6724,7 @@ async function* parseLINE(options2) {
6653
6724
  yield { type: "progress", data: initialProgress };
6654
6725
  onProgress?.(initialProgress);
6655
6726
  onLog?.("info", `\u5F00\u59CB\u89E3\u6790 LINE \u5BFC\u51FA\u6587\u4EF6\uFF0C\u5927\u5C0F: ${(totalBytes / 1024 / 1024).toFixed(2)} MB`);
6656
- const content = fs16.readFileSync(filePath, "utf-8");
6727
+ const content = fs17.readFileSync(filePath, "utf-8");
6657
6728
  const lines = content.split("\n").map((line) => line.replace(/\r$/, ""));
6658
6729
  let currentDate = null;
6659
6730
  let chatName = extractNameFromFilePath8(filePath);
@@ -6961,12 +7032,12 @@ function findEntryFileInDirectory(dirPath, maxDepth = 1) {
6961
7032
  if (depth > maxDepth) return null;
6962
7033
  let entries;
6963
7034
  try {
6964
- entries = fs17.readdirSync(current, { withFileTypes: true });
7035
+ entries = fs18.readdirSync(current, { withFileTypes: true });
6965
7036
  } catch {
6966
7037
  return null;
6967
7038
  }
6968
7039
  for (const entry of entries) {
6969
- const full = path13.join(current, entry.name);
7040
+ const full = path14.join(current, entry.name);
6970
7041
  if (entry.isFile() && entry.name.endsWith(".json")) {
6971
7042
  const format = detectFormat(full);
6972
7043
  if (format) return full;
@@ -6974,7 +7045,7 @@ function findEntryFileInDirectory(dirPath, maxDepth = 1) {
6974
7045
  }
6975
7046
  for (const entry of entries) {
6976
7047
  if (entry.isDirectory()) {
6977
- const found = walk(path13.join(current, entry.name), depth + 1);
7048
+ const found = walk(path14.join(current, entry.name), depth + 1);
6978
7049
  if (found) return found;
6979
7050
  }
6980
7051
  }
@@ -7023,8 +7094,8 @@ function logNativeParserStatus() {
7023
7094
  }
7024
7095
 
7025
7096
  // ../../packages/node-runtime/src/import/perf-logger.ts
7026
- import * as fs18 from "fs";
7027
- import * as path14 from "path";
7097
+ import * as fs19 from "fs";
7098
+ import * as path15 from "path";
7028
7099
  var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
7029
7100
  LogLevel2["ERROR"] = "ERROR";
7030
7101
  LogLevel2["INFO"] = "INFO";
@@ -7036,11 +7107,11 @@ var currentLogFile = null;
7036
7107
  var errorCount = 0;
7037
7108
  function initPerfLog(sessionId, logDir) {
7038
7109
  try {
7039
- if (!fs18.existsSync(logDir)) {
7040
- fs18.mkdirSync(logDir, { recursive: true });
7110
+ if (!fs19.existsSync(logDir)) {
7111
+ fs19.mkdirSync(logDir, { recursive: true });
7041
7112
  }
7042
- currentLogFile = path14.join(logDir, `import_${sessionId}_${Date.now()}.log`);
7043
- fs18.writeFileSync(currentLogFile, `=== Import Log ===
7113
+ currentLogFile = path15.join(logDir, `import_${sessionId}_${Date.now()}.log`);
7114
+ fs19.writeFileSync(currentLogFile, `=== Import Log ===
7044
7115
  Start time: ${(/* @__PURE__ */ new Date()).toISOString()}
7045
7116
 
7046
7117
  `, "utf-8");
@@ -7061,7 +7132,7 @@ function logPerf(event, messagesProcessed, batchSize) {
7061
7132
  const logLine = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${event} | messages: ${messagesProcessed.toLocaleString()} | elapsed: ${duration}ms | speed: ${speed.toLocaleString()}/s | memory: ${memory}MB` + (batchSize ? ` | batch: ${batchSize}` : "") + "\n";
7062
7133
  if (currentLogFile) {
7063
7134
  try {
7064
- fs18.appendFileSync(currentLogFile, logLine, "utf-8");
7135
+ fs19.appendFileSync(currentLogFile, logLine, "utf-8");
7065
7136
  } catch {
7066
7137
  }
7067
7138
  }
@@ -7071,7 +7142,7 @@ function logPerf(event, messagesProcessed, batchSize) {
7071
7142
  function logPerfDetail(detail) {
7072
7143
  if (currentLogFile) {
7073
7144
  try {
7074
- fs18.appendFileSync(currentLogFile, ` ${detail}
7145
+ fs19.appendFileSync(currentLogFile, ` ${detail}
7075
7146
  `, "utf-8");
7076
7147
  } catch {
7077
7148
  }
@@ -7091,7 +7162,7 @@ function writeLogLine(level, message) {
7091
7162
  const logLine = `[${(/* @__PURE__ */ new Date()).toISOString()}] [${level}] ${message}
7092
7163
  `;
7093
7164
  try {
7094
- fs18.appendFileSync(currentLogFile, logLine, "utf-8");
7165
+ fs19.appendFileSync(currentLogFile, logLine, "utf-8");
7095
7166
  } catch {
7096
7167
  }
7097
7168
  }
@@ -7116,7 +7187,7 @@ Total members: ${totalMembers.toLocaleString()}
7116
7187
  Errors: ${errorCount}
7117
7188
  `;
7118
7189
  try {
7119
- fs18.appendFileSync(currentLogFile, summary, "utf-8");
7190
+ fs19.appendFileSync(currentLogFile, summary, "utf-8");
7120
7191
  } catch {
7121
7192
  }
7122
7193
  }
@@ -7215,8 +7286,8 @@ function segmentText(text, locale, minLength) {
7215
7286
  }
7216
7287
 
7217
7288
  // ../../packages/node-runtime/src/nlp/dict-manager.ts
7218
- import * as fs19 from "fs";
7219
- import * as path15 from "path";
7289
+ import * as fs20 from "fs";
7290
+ import * as path16 from "path";
7220
7291
  import { createHash } from "crypto";
7221
7292
  var DICT_DOWNLOAD_URL_BASE = "https://chatlab.fun/assets/nlp";
7222
7293
  var DICT_SHA256 = {
@@ -7228,19 +7299,19 @@ var AVAILABLE_DICTS = [
7228
7299
  { id: "zh-TW", label: "\u7E41\u9AD4\u4E2D\u6587", locale: "zh-TW" }
7229
7300
  ];
7230
7301
  function getDictFilePath(nlpDir, dictId) {
7231
- return path15.join(nlpDir, `${dictId}.dict`);
7302
+ return path16.join(nlpDir, `${dictId}.dict`);
7232
7303
  }
7233
7304
  function isDictDownloaded(nlpDir, dictId) {
7234
- return fs19.existsSync(getDictFilePath(nlpDir, dictId));
7305
+ return fs20.existsSync(getDictFilePath(nlpDir, dictId));
7235
7306
  }
7236
7307
  function getDictList(nlpDir) {
7237
7308
  return AVAILABLE_DICTS.map((d) => {
7238
7309
  const filePath = getDictFilePath(nlpDir, d.id);
7239
- const downloaded = fs19.existsSync(filePath);
7310
+ const downloaded = fs20.existsSync(filePath);
7240
7311
  let fileSize;
7241
7312
  if (downloaded) {
7242
7313
  try {
7243
- fileSize = fs19.statSync(filePath).size;
7314
+ fileSize = fs20.statSync(filePath).size;
7244
7315
  } catch {
7245
7316
  }
7246
7317
  }
@@ -7249,9 +7320,9 @@ function getDictList(nlpDir) {
7249
7320
  }
7250
7321
  function loadDictBuffer(nlpDir, dictId) {
7251
7322
  const filePath = getDictFilePath(nlpDir, dictId);
7252
- if (!fs19.existsSync(filePath)) return null;
7323
+ if (!fs20.existsSync(filePath)) return null;
7253
7324
  try {
7254
- return fs19.readFileSync(filePath);
7325
+ return fs20.readFileSync(filePath);
7255
7326
  } catch (error) {
7256
7327
  console.error(`[NLP DictManager] Failed to read dict file: ${filePath}`, error);
7257
7328
  return null;
@@ -7261,7 +7332,7 @@ async function downloadDict(nlpDir, dictId, onProgress) {
7261
7332
  if (!AVAILABLE_DICTS.find((d) => d.id === dictId)) {
7262
7333
  return { success: false, error: `Unknown dict: ${dictId}` };
7263
7334
  }
7264
- fs19.mkdirSync(nlpDir, { recursive: true });
7335
+ fs20.mkdirSync(nlpDir, { recursive: true });
7265
7336
  const url = `${DICT_DOWNLOAD_URL_BASE}/${dictId}.dict`;
7266
7337
  const filePath = getDictFilePath(nlpDir, dictId);
7267
7338
  const tmpPath = filePath + ".tmp";
@@ -7302,16 +7373,16 @@ async function downloadDict(nlpDir, dictId, onProgress) {
7302
7373
  if (actualSha256 !== expectedSha256) {
7303
7374
  return { success: false, error: "Dictionary integrity check failed (SHA256 mismatch)" };
7304
7375
  }
7305
- fs19.writeFileSync(tmpPath, buffer);
7306
- if (fs19.existsSync(filePath)) fs19.unlinkSync(filePath);
7307
- fs19.renameSync(tmpPath, filePath);
7376
+ fs20.writeFileSync(tmpPath, buffer);
7377
+ if (fs20.existsSync(filePath)) fs20.unlinkSync(filePath);
7378
+ fs20.renameSync(tmpPath, filePath);
7308
7379
  clearJiebaInstance(dictId);
7309
- console.log(`[NLP DictManager] Dict downloaded: ${dictId} (${fs19.statSync(filePath).size} bytes)`);
7380
+ console.log(`[NLP DictManager] Dict downloaded: ${dictId} (${fs20.statSync(filePath).size} bytes)`);
7310
7381
  return { success: true };
7311
7382
  } catch (error) {
7312
- if (fs19.existsSync(tmpPath)) {
7383
+ if (fs20.existsSync(tmpPath)) {
7313
7384
  try {
7314
- fs19.unlinkSync(tmpPath);
7385
+ fs20.unlinkSync(tmpPath);
7315
7386
  } catch {
7316
7387
  }
7317
7388
  }
@@ -7322,9 +7393,9 @@ async function downloadDict(nlpDir, dictId, onProgress) {
7322
7393
  }
7323
7394
  function deleteDict(nlpDir, dictId) {
7324
7395
  const filePath = getDictFilePath(nlpDir, dictId);
7325
- if (!fs19.existsSync(filePath)) return { success: true };
7396
+ if (!fs20.existsSync(filePath)) return { success: true };
7326
7397
  try {
7327
- fs19.unlinkSync(filePath);
7398
+ fs20.unlinkSync(filePath);
7328
7399
  clearJiebaInstance(dictId);
7329
7400
  console.log(`[NLP DictManager] Dict deleted: ${dictId}`);
7330
7401
  return { success: true };
@@ -7424,7 +7495,7 @@ function searchByFts(db, keywords, limit = 1e3, offset = 0) {
7424
7495
  }
7425
7496
 
7426
7497
  // ../../packages/node-runtime/src/import/streaming-importer.ts
7427
- import * as fs20 from "fs";
7498
+ import * as fs21 from "fs";
7428
7499
 
7429
7500
  // ../../packages/node-runtime/src/import/message-deduplicator.ts
7430
7501
  function generateFallbackMessageKey(message) {
@@ -7456,7 +7527,7 @@ function registerMessageAndCheckDuplicate(message, state) {
7456
7527
  // ../../packages/node-runtime/src/import/streaming-importer.ts
7457
7528
  var BATCH_COMMIT_SIZE = 5e4;
7458
7529
  var CHECKPOINT_INTERVAL = 2e5;
7459
- var yieldToEventLoop = () => new Promise((resolve2) => setImmediate(resolve2));
7530
+ var yieldToEventLoop = () => new Promise((resolve4) => setImmediate(resolve4));
7460
7531
  function defaultGenerateSessionId() {
7461
7532
  const ts = Date.now();
7462
7533
  const rand = Math.random().toString(36).substring(2, 8);
@@ -7959,7 +8030,7 @@ async function streamParseFileInfo(filePath, deps) {
7959
8030
  if (!formatFeature) {
7960
8031
  throw new Error("Unrecognized file format");
7961
8032
  }
7962
- const fileSize = fs20.statSync(filePath).size;
8033
+ const fileSize = fs21.statSync(filePath).size;
7963
8034
  deps.onProgress({
7964
8035
  stage: "parsing",
7965
8036
  bytesRead: 0,
@@ -8048,7 +8119,7 @@ async function streamParseFileInfo(filePath, deps) {
8048
8119
  }
8049
8120
  db.close();
8050
8121
  try {
8051
- if (fs20.existsSync(tempDbPath)) fs20.unlinkSync(tempDbPath);
8122
+ if (fs21.existsSync(tempDbPath)) fs21.unlinkSync(tempDbPath);
8052
8123
  } catch {
8053
8124
  }
8054
8125
  throw error;
@@ -8693,8 +8764,8 @@ async function analyzeAutoImportFile(filePath, deps, options2 = {}) {
8693
8764
  }
8694
8765
 
8695
8766
  // ../../packages/node-runtime/src/import/import-lock.ts
8696
- import * as fs21 from "fs";
8697
- import * as path16 from "path";
8767
+ import * as fs22 from "fs";
8768
+ import * as path17 from "path";
8698
8769
  import { randomUUID } from "crypto";
8699
8770
  var IMPORT_LOCK_FILENAME = ".chatlab-import.lock";
8700
8771
  var IMPORT_IN_PROGRESS_ERROR_KEY = "error.import_in_progress";
@@ -8708,7 +8779,7 @@ var ImportInProgressError = class extends Error {
8708
8779
  };
8709
8780
  function parseOwner(lockPath) {
8710
8781
  try {
8711
- const parsed = JSON.parse(fs21.readFileSync(lockPath, "utf-8"));
8782
+ const parsed = JSON.parse(fs22.readFileSync(lockPath, "utf-8"));
8712
8783
  if (typeof parsed.pid !== "number" || !Number.isInteger(parsed.pid) || parsed.pid <= 0 || typeof parsed.token !== "string" || parsed.token.length === 0 || typeof parsed.startedAt !== "number") {
8713
8784
  return null;
8714
8785
  }
@@ -8731,13 +8802,13 @@ function removeStaleLock(lockPath) {
8731
8802
  if (isProcessRunning(owner.pid)) return false;
8732
8803
  } else {
8733
8804
  try {
8734
- if (Date.now() - fs21.statSync(lockPath).mtimeMs < 5e3) return false;
8805
+ if (Date.now() - fs22.statSync(lockPath).mtimeMs < 5e3) return false;
8735
8806
  } catch {
8736
8807
  return true;
8737
8808
  }
8738
8809
  }
8739
8810
  try {
8740
- fs21.unlinkSync(lockPath);
8811
+ fs22.unlinkSync(lockPath);
8741
8812
  appLogger.warn("import-lock", "Removed stale import lock", { ownerPid: owner?.pid });
8742
8813
  return true;
8743
8814
  } catch {
@@ -8746,7 +8817,7 @@ function removeStaleLock(lockPath) {
8746
8817
  }
8747
8818
  function releaseLock(lockPath, fd, owner) {
8748
8819
  try {
8749
- fs21.closeSync(fd);
8820
+ fs22.closeSync(fd);
8750
8821
  } catch (error) {
8751
8822
  appLogger.error("import-lock", "Failed to close import lock", error);
8752
8823
  }
@@ -8755,19 +8826,19 @@ function releaseLock(lockPath, fd, owner) {
8755
8826
  appLogger.warn("import-lock", "Import lock ownership changed before release");
8756
8827
  return;
8757
8828
  }
8758
- fs21.unlinkSync(lockPath);
8829
+ fs22.unlinkSync(lockPath);
8759
8830
  appLogger.info("import-lock", "Import lock released");
8760
8831
  } catch (error) {
8761
8832
  appLogger.error("import-lock", "Failed to release import lock", error);
8762
8833
  }
8763
8834
  }
8764
8835
  async function withDataDirImportLock(userDataDir, task) {
8765
- fs21.mkdirSync(userDataDir, { recursive: true });
8766
- const lockPath = path16.join(userDataDir, IMPORT_LOCK_FILENAME);
8836
+ fs22.mkdirSync(userDataDir, { recursive: true });
8837
+ const lockPath = path17.join(userDataDir, IMPORT_LOCK_FILENAME);
8767
8838
  let fd = null;
8768
8839
  for (let attempt = 0; attempt < 2; attempt++) {
8769
8840
  try {
8770
- fd = fs21.openSync(lockPath, "wx");
8841
+ fd = fs22.openSync(lockPath, "wx");
8771
8842
  break;
8772
8843
  } catch (error) {
8773
8844
  const code = error.code;
@@ -8786,8 +8857,8 @@ async function withDataDirImportLock(userDataDir, task) {
8786
8857
  startedAt: Date.now()
8787
8858
  };
8788
8859
  try {
8789
- fs21.writeFileSync(fd, JSON.stringify(owner), "utf-8");
8790
- fs21.fsyncSync(fd);
8860
+ fs22.writeFileSync(fd, JSON.stringify(owner), "utf-8");
8861
+ fs22.fsyncSync(fd);
8791
8862
  appLogger.info("import-lock", "Import lock acquired");
8792
8863
  return await task();
8793
8864
  } finally {
@@ -8807,8 +8878,8 @@ var ArchiveImportError = class extends Error {
8807
8878
 
8808
8879
  // ../../packages/node-runtime/src/import/archive/archive-reader.ts
8809
8880
  var import_yauzl = __toESM(require_yauzl(), 1);
8810
- import * as fs22 from "fs";
8811
- import * as path17 from "path";
8881
+ import * as fs23 from "fs";
8882
+ import * as path18 from "path";
8812
8883
  import { pipeline } from "stream/promises";
8813
8884
  var DEFAULT_MAX_ENTRIES = 1e5;
8814
8885
  var DEFAULT_MAX_ENTRY_BYTES = 20 * 1024 * 1024 * 1024;
@@ -8927,8 +8998,8 @@ var ZipArchiveReader = class {
8927
8998
  await this.visitEntries(async (entry, openStream) => {
8928
8999
  const destination = targets.get(entry.name);
8929
9000
  if (!destination || entry.isDirectory) return;
8930
- fs22.mkdirSync(path17.dirname(destination), { recursive: true });
8931
- await pipeline(await openStream(), fs22.createWriteStream(destination, { flags: "wx" }));
9001
+ fs23.mkdirSync(path18.dirname(destination), { recursive: true });
9002
+ await pipeline(await openStream(), fs23.createWriteStream(destination, { flags: "wx" }));
8932
9003
  remaining.delete(entry.name);
8933
9004
  });
8934
9005
  if (remaining.size > 0) {
@@ -8945,8 +9016,8 @@ var import_stream_chain9 = __toESM(require_stream_chain(), 1);
8945
9016
  var import_stream_json9 = __toESM(require_stream_json(), 1);
8946
9017
  var import_Pick8 = __toESM(require_Pick(), 1);
8947
9018
  var import_StreamValues9 = __toESM(require_StreamValues(), 1);
8948
- import * as fs23 from "fs";
8949
- import * as path18 from "path";
9019
+ import * as fs24 from "fs";
9020
+ import * as path19 from "path";
8950
9021
  var { chain: chain9 } = import_stream_chain9.default;
8951
9022
  var { parser: parser10 } = import_stream_json9.default;
8952
9023
  var { pick: pick8 } = import_Pick8.default;
@@ -9075,16 +9146,16 @@ var GoogleChatTakeoutResolver = class {
9075
9146
  `Google Chat conversation is missing required files: ${chat.chatId}`
9076
9147
  );
9077
9148
  }
9078
- fs23.mkdirSync(targetDir, { recursive: true });
9149
+ fs24.mkdirSync(targetDir, { recursive: true });
9079
9150
  await reader.pipeEntries(
9080
9151
  /* @__PURE__ */ new Map([
9081
- [userInfoEntry, path18.join(targetDir, "user_info.json")],
9082
- [groupInfoEntry, path18.join(targetDir, "group_info.json")],
9083
- [messagesEntry, path18.join(targetDir, "messages.json")]
9152
+ [userInfoEntry, path19.join(targetDir, "user_info.json")],
9153
+ [groupInfoEntry, path19.join(targetDir, "group_info.json")],
9154
+ [messagesEntry, path19.join(targetDir, "messages.json")]
9084
9155
  ])
9085
9156
  );
9086
- const manifestPath = path18.join(targetDir, "google-chat-import.json");
9087
- fs23.writeFileSync(
9157
+ const manifestPath = path19.join(targetDir, "google-chat-import.json");
9158
+ fs24.writeFileSync(
9088
9159
  manifestPath,
9089
9160
  JSON.stringify(
9090
9161
  {
@@ -9107,8 +9178,8 @@ var GoogleChatTakeoutResolver = class {
9107
9178
  };
9108
9179
 
9109
9180
  // ../../packages/node-runtime/src/import/archive/source-manager.ts
9110
- import * as fs24 from "fs";
9111
- import * as path19 from "path";
9181
+ import * as fs25 from "fs";
9182
+ import * as path20 from "path";
9112
9183
  import { randomUUID as randomUUID2 } from "crypto";
9113
9184
  var DEFAULT_TTL_MS = 30 * 60 * 1e3;
9114
9185
  var ArchiveImportSourceManager = class {
@@ -9119,11 +9190,11 @@ var ArchiveImportSourceManager = class {
9119
9190
  now;
9120
9191
  resolvers;
9121
9192
  constructor(options2 = {}) {
9122
- this.tempRoot = options2.tempRoot ?? path19.join(process.cwd(), ".chatlab-import-sources");
9193
+ this.tempRoot = options2.tempRoot ?? createChatLabTempDir("imports", "sources-");
9123
9194
  this.ttlMs = options2.ttlMs ?? DEFAULT_TTL_MS;
9124
9195
  this.now = options2.now ?? Date.now;
9125
9196
  this.resolvers = options2.resolvers ?? [new GoogleChatTakeoutResolver()];
9126
- fs24.mkdirSync(this.tempRoot, { recursive: true });
9197
+ fs25.mkdirSync(this.tempRoot, { recursive: true });
9127
9198
  }
9128
9199
  prepareLocalArchive(archivePath) {
9129
9200
  return this.prepareArchive(archivePath, false);
@@ -9180,7 +9251,7 @@ var ArchiveImportSourceManager = class {
9180
9251
  `Archive conversation was not found: ${chatId}`
9181
9252
  );
9182
9253
  }
9183
- const materializedDir = fs24.mkdtempSync(path19.join(this.tempRoot, `materialized-${sourceId}-`));
9254
+ const materializedDir = fs25.mkdtempSync(path20.join(this.tempRoot, `materialized-${sourceId}-`));
9184
9255
  try {
9185
9256
  const reader = new ZipArchiveReader(record.archivePath);
9186
9257
  const materialized = await record.resolver.materialize(reader, chat, materializedDir);
@@ -9231,7 +9302,7 @@ var ArchiveImportSourceManager = class {
9231
9302
  }
9232
9303
  removePath(targetPath) {
9233
9304
  try {
9234
- fs24.rmSync(targetPath, { recursive: true, force: true });
9305
+ fs25.rmSync(targetPath, { recursive: true, force: true });
9235
9306
  } catch {
9236
9307
  }
9237
9308
  }
@@ -9301,12 +9372,12 @@ ${rawErrorLabel}: ${details}`;
9301
9372
  }
9302
9373
 
9303
9374
  // ../../packages/node-runtime/src/ai/assistant-parser.ts
9304
- import * as path20 from "path";
9375
+ import * as path21 from "path";
9305
9376
  import matter from "gray-matter";
9306
9377
  function parseAssistantFile(content, filePath) {
9307
9378
  try {
9308
9379
  const { data: fm, content: body } = matter(content);
9309
- const id = fm.id ?? path20.basename(filePath, ".md");
9380
+ const id = fm.id ?? path21.basename(filePath, ".md");
9310
9381
  const name = fm.name;
9311
9382
  if (!name) return null;
9312
9383
  return {
@@ -9385,8 +9456,8 @@ var AssistantManager = class {
9385
9456
  }
9386
9457
  // ==================== Init ====================
9387
9458
  init() {
9388
- const { fs: fs35, assistantsDir } = this.deps;
9389
- fs35.ensureDir(assistantsDir);
9459
+ const { fs: fs37, assistantsDir } = this.deps;
9460
+ fs37.ensureDir(assistantsDir);
9390
9461
  const generalCreated = this.ensureGeneralAssistants();
9391
9462
  this.loadAll();
9392
9463
  this.initialized = true;
@@ -9397,26 +9468,26 @@ var AssistantManager = class {
9397
9468
  return { total: this.cache.size, generalCreated };
9398
9469
  }
9399
9470
  ensureGeneralAssistants() {
9400
- const { fs: fs35, assistantsDir } = this.deps;
9471
+ const { fs: fs37, assistantsDir } = this.deps;
9401
9472
  let anyCreated = false;
9402
9473
  for (const id of this.generalIds) {
9403
9474
  const config = this.getBuiltinConfig(id);
9404
9475
  if (!config) continue;
9405
- const filePath = fs35.joinPath(assistantsDir, `${id}.md`);
9406
- if (fs35.fileExists(filePath)) continue;
9407
- fs35.writeFile(filePath, serializeAssistant({ ...config, builtinId: config.id }));
9476
+ const filePath = fs37.joinPath(assistantsDir, `${id}.md`);
9477
+ if (fs37.fileExists(filePath)) continue;
9478
+ fs37.writeFile(filePath, serializeAssistant({ ...config, builtinId: config.id }));
9408
9479
  anyCreated = true;
9409
9480
  }
9410
9481
  return anyCreated;
9411
9482
  }
9412
9483
  loadAll() {
9413
- const { fs: fs35, assistantsDir } = this.deps;
9484
+ const { fs: fs37, assistantsDir } = this.deps;
9414
9485
  this.cache.clear();
9415
- const files = fs35.listFiles(assistantsDir, ".md");
9486
+ const files = fs37.listFiles(assistantsDir, ".md");
9416
9487
  for (const file of files) {
9417
9488
  try {
9418
- const filePath = fs35.joinPath(assistantsDir, file);
9419
- const content = fs35.readFile(filePath);
9489
+ const filePath = fs37.joinPath(assistantsDir, file);
9490
+ const content = fs37.readFile(filePath);
9420
9491
  const config = parseAssistantFile(content, filePath);
9421
9492
  if (config) {
9422
9493
  this.cache.set(config.id, config);
@@ -9528,12 +9599,12 @@ var AssistantManager = class {
9528
9599
  };
9529
9600
 
9530
9601
  // ../../packages/node-runtime/src/ai/skill-parser.ts
9531
- import * as path21 from "path";
9602
+ import * as path22 from "path";
9532
9603
  import matter2 from "gray-matter";
9533
9604
  function parseSkillFile(content, filePath) {
9534
9605
  try {
9535
9606
  const { data: fm, content: prompt } = matter2(content);
9536
- const id = fm.id ?? path21.basename(filePath, ".md");
9607
+ const id = fm.id ?? path22.basename(filePath, ".md");
9537
9608
  const name = fm.name;
9538
9609
  if (!name) return null;
9539
9610
  return {
@@ -9552,7 +9623,7 @@ function parseSkillFile(content, filePath) {
9552
9623
  function extractSkillId(content, filePath) {
9553
9624
  try {
9554
9625
  const { data: fm } = matter2(content);
9555
- return fm.id ?? path21.basename(filePath, ".md");
9626
+ return fm.id ?? path22.basename(filePath, ".md");
9556
9627
  } catch {
9557
9628
  return null;
9558
9629
  }
@@ -9571,8 +9642,8 @@ function validateChatScope(raw) {
9571
9642
 
9572
9643
  // ../../packages/node-runtime/src/ai/chats.ts
9573
9644
  import Database from "better-sqlite3";
9574
- import * as fs25 from "fs";
9575
- import * as path22 from "path";
9645
+ import * as fs26 from "fs";
9646
+ import * as path23 from "path";
9576
9647
  var DEFAULT_GENERAL_ID = "general_cn";
9577
9648
  var defaultLogger = {
9578
9649
  warn(_category, message, extra) {
@@ -9591,14 +9662,14 @@ var AIChatManager = class {
9591
9662
  this.nativeBinding = options2?.nativeBinding;
9592
9663
  }
9593
9664
  ensureDir(dir) {
9594
- if (!fs25.existsSync(dir)) {
9595
- fs25.mkdirSync(dir, { recursive: true });
9665
+ if (!fs26.existsSync(dir)) {
9666
+ fs26.mkdirSync(dir, { recursive: true });
9596
9667
  }
9597
9668
  }
9598
9669
  getDb() {
9599
9670
  if (this.db) return this.db;
9600
9671
  this.ensureDir(this.aiDataDir);
9601
- const dbPath = path22.join(this.aiDataDir, "conversations.db");
9672
+ const dbPath = path23.join(this.aiDataDir, "conversations.db");
9602
9673
  this.db = this.nativeBinding ? new Database(dbPath, { nativeBinding: this.nativeBinding }) : new Database(dbPath);
9603
9674
  this.db.pragma("journal_mode = WAL");
9604
9675
  this.db.exec(`
@@ -9841,16 +9912,16 @@ var AIChatManager = class {
9841
9912
  if (allRows.length === 0) return [];
9842
9913
  const rowMap = new Map(allRows.map((row) => [row.id, row]));
9843
9914
  let currentId = leafMessageId ?? this.getActiveMessageId(aiChatId);
9844
- const path31 = [];
9915
+ const path33 = [];
9845
9916
  const seen = /* @__PURE__ */ new Set();
9846
9917
  while (currentId && !seen.has(currentId)) {
9847
9918
  seen.add(currentId);
9848
9919
  const row = rowMap.get(currentId);
9849
9920
  if (!row) break;
9850
- path31.push(row);
9921
+ path33.push(row);
9851
9922
  currentId = row.parentId;
9852
9923
  }
9853
- return path31.length > 0 ? path31.reverse() : allRows;
9924
+ return path33.length > 0 ? path33.reverse() : allRows;
9854
9925
  }
9855
9926
  // ==================== 生命周期 ====================
9856
9927
  close() {
@@ -10420,21 +10491,21 @@ var SkillManagerCore = class {
10420
10491
  }
10421
10492
  // ==================== Init ====================
10422
10493
  init() {
10423
- const { fs: fs35, skillsDir } = this.deps;
10424
- fs35.ensureDir(skillsDir);
10494
+ const { fs: fs37, skillsDir } = this.deps;
10495
+ fs37.ensureDir(skillsDir);
10425
10496
  this.loadAll();
10426
10497
  this.initialized = true;
10427
10498
  this.deps.logger?.info("SkillManager", "Initialized", { total: this.cache.size });
10428
10499
  return { total: this.cache.size };
10429
10500
  }
10430
10501
  loadAll() {
10431
- const { fs: fs35, skillsDir } = this.deps;
10502
+ const { fs: fs37, skillsDir } = this.deps;
10432
10503
  this.cache.clear();
10433
- const files = fs35.listFiles(skillsDir, ".md");
10504
+ const files = fs37.listFiles(skillsDir, ".md");
10434
10505
  for (const file of files) {
10435
10506
  try {
10436
- const filePath = fs35.joinPath(skillsDir, file);
10437
- const content = fs35.readFile(filePath);
10507
+ const filePath = fs37.joinPath(skillsDir, file);
10508
+ const content = fs37.readFile(filePath);
10438
10509
  const def = parseSkillFile(content, filePath);
10439
10510
  if (def) {
10440
10511
  this.cache.set(def.id, def);
@@ -10586,8 +10657,8 @@ var SkillManagerCore = class {
10586
10657
  };
10587
10658
 
10588
10659
  // ../../packages/node-runtime/src/ai/skill-manager.ts
10589
- import * as fs26 from "fs";
10590
- import * as path23 from "path";
10660
+ import * as fs27 from "fs";
10661
+ import * as path24 from "path";
10591
10662
  var SKILLS_DIR_NAME = "skills";
10592
10663
  var defaultLogger2 = {
10593
10664
  info: () => {
@@ -10597,26 +10668,26 @@ var defaultLogger2 = {
10597
10668
  };
10598
10669
  var nodeFs = {
10599
10670
  ensureDir(dir) {
10600
- fs26.mkdirSync(dir, { recursive: true });
10671
+ fs27.mkdirSync(dir, { recursive: true });
10601
10672
  },
10602
10673
  listFiles(dir, ext) {
10603
- if (!fs26.existsSync(dir)) return [];
10604
- return fs26.readdirSync(dir).filter((file) => file.endsWith(ext));
10674
+ if (!fs27.existsSync(dir)) return [];
10675
+ return fs27.readdirSync(dir).filter((file) => file.endsWith(ext));
10605
10676
  },
10606
10677
  readFile(filePath) {
10607
- return fs26.readFileSync(filePath, "utf-8");
10678
+ return fs27.readFileSync(filePath, "utf-8");
10608
10679
  },
10609
10680
  writeFile(filePath, content) {
10610
- fs26.writeFileSync(filePath, content, "utf-8");
10681
+ fs27.writeFileSync(filePath, content, "utf-8");
10611
10682
  },
10612
10683
  deleteFile(filePath) {
10613
- fs26.unlinkSync(filePath);
10684
+ fs27.unlinkSync(filePath);
10614
10685
  },
10615
10686
  fileExists(filePath) {
10616
- return fs26.existsSync(filePath);
10687
+ return fs27.existsSync(filePath);
10617
10688
  },
10618
10689
  joinPath(...parts) {
10619
- return path23.join(...parts);
10690
+ return path24.join(...parts);
10620
10691
  }
10621
10692
  };
10622
10693
  var SkillManager = class {
@@ -10626,7 +10697,7 @@ var SkillManager = class {
10626
10697
  this.logger = logger ?? defaultLogger2;
10627
10698
  this.core = new SkillManagerCore({
10628
10699
  fs: nodeFs,
10629
- skillsDir: path23.join(aiDataDir, SKILLS_DIR_NAME),
10700
+ skillsDir: path24.join(aiDataDir, SKILLS_DIR_NAME),
10630
10701
  builtinRawSkills: [],
10631
10702
  logger: {
10632
10703
  info: () => {
@@ -14456,9 +14527,9 @@ var localeMap = {
14456
14527
  "ja-JP": ja_JP_default,
14457
14528
  "zh-TW": zh_TW_default
14458
14529
  };
14459
- function getNestedValue(obj, path31) {
14530
+ function getNestedValue(obj, path33) {
14460
14531
  let current = obj;
14461
- for (const segment2 of path31.split(".")) {
14532
+ for (const segment2 of path33.split(".")) {
14462
14533
  if (current == null || typeof current !== "object") return void 0;
14463
14534
  current = current[segment2];
14464
14535
  }
@@ -14971,6 +15042,49 @@ var LLMConfigStore = class {
14971
15042
  }
14972
15043
  };
14973
15044
 
15045
+ // ../../packages/node-runtime/src/ai/file-config-storage.ts
15046
+ import * as fs28 from "fs";
15047
+ import * as path25 from "path";
15048
+ function createFileConfigStorage(baseDir) {
15049
+ return {
15050
+ readJson(key) {
15051
+ try {
15052
+ return JSON.parse(fs28.readFileSync(path25.join(baseDir, `${key}.json`), "utf-8"));
15053
+ } catch {
15054
+ return null;
15055
+ }
15056
+ },
15057
+ writeJson(key, data) {
15058
+ fs28.mkdirSync(baseDir, { recursive: true });
15059
+ fs28.writeFileSync(path25.join(baseDir, `${key}.json`), JSON.stringify(data, null, 2), "utf-8");
15060
+ }
15061
+ };
15062
+ }
15063
+
15064
+ // ../../packages/node-runtime/src/ai/auth-profile-llm-config-store.ts
15065
+ var defaultDeps = {
15066
+ resolveApiKey: (provider, authProfile) => resolveApiKey(provider, authProfile) || void 0,
15067
+ writeAuthProfile,
15068
+ deleteAuthProfile
15069
+ };
15070
+ function getAuthProfile2(config) {
15071
+ return config.authProfile;
15072
+ }
15073
+ function createAuthProfileLlmConfigStore(storage, deps = defaultDeps) {
15074
+ return new LLMConfigStore(storage, {
15075
+ resolveApiKey: deps.resolveApiKey,
15076
+ onApiKeyCreated: (config, apiKey) => {
15077
+ const profileName = config.name?.toLowerCase().replace(/\s+/g, "-") || config.provider;
15078
+ deps.writeAuthProfile(profileName, { type: "api_key", provider: config.provider, key: apiKey });
15079
+ return profileName;
15080
+ },
15081
+ onApiKeyDeleted: (config) => {
15082
+ const profileName = getAuthProfile2(config);
15083
+ if (profileName) deps.deleteAuthProfile(profileName);
15084
+ }
15085
+ });
15086
+ }
15087
+
14974
15088
  // ../../packages/node-runtime/src/ai/custom-store.ts
14975
15089
  function generateCustomId() {
14976
15090
  return `custom:${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
@@ -15790,8 +15904,8 @@ function exportWithFormat(params, openDatabase) {
15790
15904
  }
15791
15905
 
15792
15906
  // ../../packages/node-runtime/src/merger/temp-db.ts
15793
- import * as fs27 from "fs";
15794
- import * as path24 from "path";
15907
+ import * as fs29 from "fs";
15908
+ import * as path26 from "path";
15795
15909
  var TEMP_DB_SCHEMA = `
15796
15910
  CREATE TABLE IF NOT EXISTS meta (
15797
15911
  name TEXT NOT NULL,
@@ -16036,21 +16150,21 @@ function exportSessionToJson(db) {
16036
16150
  }
16037
16151
  function deleteTempDatabase(dbPath) {
16038
16152
  try {
16039
- if (fs27.existsSync(dbPath)) fs27.unlinkSync(dbPath);
16153
+ if (fs29.existsSync(dbPath)) fs29.unlinkSync(dbPath);
16040
16154
  const walPath = dbPath + "-wal";
16041
16155
  const shmPath = dbPath + "-shm";
16042
- if (fs27.existsSync(walPath)) fs27.unlinkSync(walPath);
16043
- if (fs27.existsSync(shmPath)) fs27.unlinkSync(shmPath);
16156
+ if (fs29.existsSync(walPath)) fs29.unlinkSync(walPath);
16157
+ if (fs29.existsSync(shmPath)) fs29.unlinkSync(shmPath);
16044
16158
  } catch {
16045
16159
  }
16046
16160
  }
16047
16161
  function cleanupTempDatabases(tempDir) {
16048
16162
  try {
16049
- if (!fs27.existsSync(tempDir)) return;
16050
- const files = fs27.readdirSync(tempDir);
16163
+ if (!fs29.existsSync(tempDir)) return;
16164
+ const files = fs29.readdirSync(tempDir);
16051
16165
  for (const file of files) {
16052
16166
  if (file.startsWith("merge_") && file.endsWith(".db")) {
16053
- deleteTempDatabase(path24.join(tempDir, file));
16167
+ deleteTempDatabase(path26.join(tempDir, file));
16054
16168
  }
16055
16169
  }
16056
16170
  } catch {
@@ -16129,6 +16243,7 @@ function deleteSession(adapter, sessionId) {
16129
16243
  var member_service_exports = {};
16130
16244
  __export(member_service_exports, {
16131
16245
  deleteMember: () => deleteMember2,
16246
+ deleteMembers: () => deleteMembers2,
16132
16247
  getMemberNameHistory: () => getMemberNameHistory2,
16133
16248
  getMembers: () => getMembers,
16134
16249
  getMembersPaginated: () => getMembersPaginated2,
@@ -16162,6 +16277,10 @@ function deleteMember2(adapter, sessionId, memberId) {
16162
16277
  const db = adapter.ensureWritable(sessionId);
16163
16278
  return deleteMember(db, memberId);
16164
16279
  }
16280
+ function deleteMembers2(adapter, sessionId, memberIds) {
16281
+ const db = adapter.ensureWritable(sessionId);
16282
+ return deleteMembers(db, memberIds);
16283
+ }
16165
16284
  function getMemberNameHistory2(adapter, sessionId, memberId) {
16166
16285
  const db = adapter.ensureReadonly(sessionId);
16167
16286
  return getMemberNameHistory(db, memberId);
@@ -16430,8 +16549,8 @@ function clearSessionOwner(adapter, sessionId) {
16430
16549
  }
16431
16550
 
16432
16551
  // ../../packages/node-runtime/src/services/contacts/overrides.ts
16433
- import fs28 from "fs";
16434
- import path25 from "path";
16552
+ import fs30 from "fs";
16553
+ import path27 from "path";
16435
16554
  var CONTACT_OVERRIDES_FILE_NAME = "contact-overrides.json";
16436
16555
  var CONTACT_OVERRIDES_TMP_PREFIX = "contact-overrides.tmp-";
16437
16556
  var CONTACT_OVERRIDES_VERSION = 1;
@@ -16442,23 +16561,23 @@ function createEmptyContactOverridesFile() {
16442
16561
  };
16443
16562
  }
16444
16563
  function getContactOverridesPath(snapshotDir) {
16445
- return path25.join(snapshotDir, CONTACT_OVERRIDES_FILE_NAME);
16564
+ return path27.join(snapshotDir, CONTACT_OVERRIDES_FILE_NAME);
16446
16565
  }
16447
16566
  function readContactOverrides(snapshotDir) {
16448
16567
  const filePath = getContactOverridesPath(snapshotDir);
16449
- if (!fs28.existsSync(filePath)) return createEmptyContactOverridesFile();
16568
+ if (!fs30.existsSync(filePath)) return createEmptyContactOverridesFile();
16450
16569
  try {
16451
- return normalizeContactOverrides(JSON.parse(fs28.readFileSync(filePath, "utf-8")));
16570
+ return normalizeContactOverrides(JSON.parse(fs30.readFileSync(filePath, "utf-8")));
16452
16571
  } catch (error) {
16453
16572
  appLogger.warn("contacts", "contact overrides file is unreadable", error);
16454
16573
  return createEmptyContactOverridesFile();
16455
16574
  }
16456
16575
  }
16457
16576
  function writeContactOverrides(snapshotDir, overrides) {
16458
- if (!fs28.existsSync(snapshotDir)) fs28.mkdirSync(snapshotDir, { recursive: true });
16459
- const tmpPath = path25.join(snapshotDir, `${CONTACT_OVERRIDES_TMP_PREFIX}${process.pid}-${Date.now()}`);
16460
- fs28.writeFileSync(tmpPath, JSON.stringify(normalizeContactOverrides(overrides), null, 2), "utf-8");
16461
- fs28.renameSync(tmpPath, getContactOverridesPath(snapshotDir));
16577
+ if (!fs30.existsSync(snapshotDir)) fs30.mkdirSync(snapshotDir, { recursive: true });
16578
+ const tmpPath = path27.join(snapshotDir, `${CONTACT_OVERRIDES_TMP_PREFIX}${process.pid}-${Date.now()}`);
16579
+ fs30.writeFileSync(tmpPath, JSON.stringify(normalizeContactOverrides(overrides), null, 2), "utf-8");
16580
+ fs30.renameSync(tmpPath, getContactOverridesPath(snapshotDir));
16462
16581
  }
16463
16582
  function normalizeContactOverrides(value) {
16464
16583
  const input = isRecord2(value) ? value : {};
@@ -16493,23 +16612,23 @@ function buildContactsSignature(adapter, timeRangePreset) {
16493
16612
  }
16494
16613
 
16495
16614
  // ../../packages/node-runtime/src/services/contacts/snapshot.ts
16496
- import fs29 from "fs";
16497
- import path26 from "path";
16615
+ import fs31 from "fs";
16616
+ import path28 from "path";
16498
16617
  var CONTACTS_SNAPSHOT_TMP_PREFIX = "contacts-snapshot.tmp-";
16499
16618
  function getContactsSnapshotPath(snapshotDir, timeRangePreset) {
16500
16619
  const preset = normalizeContactsTimeRangePreset(timeRangePreset);
16501
- return path26.join(snapshotDir, `contacts-snapshot-${preset}.json`);
16620
+ return path28.join(snapshotDir, `contacts-snapshot-${preset}.json`);
16502
16621
  }
16503
16622
  function readContactsSnapshot(snapshotDir, timeRangePreset, options2 = {}) {
16504
16623
  const snapshotPath = getContactsSnapshotPath(snapshotDir, timeRangePreset);
16505
- if (!fs29.existsSync(snapshotPath)) return null;
16624
+ if (!fs31.existsSync(snapshotPath)) return null;
16506
16625
  try {
16507
- return JSON.parse(fs29.readFileSync(snapshotPath, "utf-8"));
16626
+ return JSON.parse(fs31.readFileSync(snapshotPath, "utf-8"));
16508
16627
  } catch (error) {
16509
16628
  const ts = options2.now?.() ?? Date.now();
16510
- const backupPath = path26.join(snapshotDir, `contacts-snapshot.corrupt-${ts}.json`);
16629
+ const backupPath = path28.join(snapshotDir, `contacts-snapshot.corrupt-${ts}.json`);
16511
16630
  try {
16512
- fs29.renameSync(snapshotPath, backupPath);
16631
+ fs31.renameSync(snapshotPath, backupPath);
16513
16632
  } catch (renameError) {
16514
16633
  appLogger.warn("contacts", "failed to backup corrupt contacts snapshot", renameError);
16515
16634
  }
@@ -16518,17 +16637,17 @@ function readContactsSnapshot(snapshotDir, timeRangePreset, options2 = {}) {
16518
16637
  }
16519
16638
  }
16520
16639
  function writeContactsSnapshot(snapshotDir, snapshot) {
16521
- if (!fs29.existsSync(snapshotDir)) fs29.mkdirSync(snapshotDir, { recursive: true });
16522
- const tmpPath = path26.join(snapshotDir, `${CONTACTS_SNAPSHOT_TMP_PREFIX}${process.pid}-${Date.now()}`);
16523
- fs29.writeFileSync(tmpPath, JSON.stringify(snapshot, null, 2), "utf-8");
16524
- fs29.renameSync(tmpPath, getContactsSnapshotPath(snapshotDir, snapshot.timeRange.preset));
16640
+ if (!fs31.existsSync(snapshotDir)) fs31.mkdirSync(snapshotDir, { recursive: true });
16641
+ const tmpPath = path28.join(snapshotDir, `${CONTACTS_SNAPSHOT_TMP_PREFIX}${process.pid}-${Date.now()}`);
16642
+ fs31.writeFileSync(tmpPath, JSON.stringify(snapshot, null, 2), "utf-8");
16643
+ fs31.renameSync(tmpPath, getContactsSnapshotPath(snapshotDir, snapshot.timeRange.preset));
16525
16644
  }
16526
16645
  function cleanupContactsSnapshotTempFiles(snapshotDir) {
16527
- if (!fs29.existsSync(snapshotDir)) return;
16528
- for (const name of fs29.readdirSync(snapshotDir)) {
16646
+ if (!fs31.existsSync(snapshotDir)) return;
16647
+ for (const name of fs31.readdirSync(snapshotDir)) {
16529
16648
  if (!name.startsWith(CONTACTS_SNAPSHOT_TMP_PREFIX)) continue;
16530
16649
  try {
16531
- fs29.rmSync(path26.join(snapshotDir, name), { force: true });
16650
+ fs31.rmSync(path28.join(snapshotDir, name), { force: true });
16532
16651
  } catch (error) {
16533
16652
  appLogger.warn("contacts", "failed to remove contacts snapshot temp file", error);
16534
16653
  }
@@ -16566,7 +16685,7 @@ function createWorker(workerData, entryUrlInput) {
16566
16685
  return new Worker(bootstrap, options2);
16567
16686
  }
16568
16687
  function createContactsWorkerRunner(options2) {
16569
- return ({ signature, timeRangePreset, signal, onProgress }) => new Promise((resolve2, reject) => {
16688
+ return ({ signature, timeRangePreset, signal, onProgress }) => new Promise((resolve4, reject) => {
16570
16689
  if (signal.aborted) {
16571
16690
  reject(createAbortError());
16572
16691
  return;
@@ -16597,7 +16716,7 @@ function createContactsWorkerRunner(options2) {
16597
16716
  if (message.type === "success" && message.snapshot) {
16598
16717
  settled = true;
16599
16718
  signal.removeEventListener("abort", abort);
16600
- resolve2(message.snapshot);
16719
+ resolve4(message.snapshot);
16601
16720
  void worker.terminate();
16602
16721
  return;
16603
16722
  }
@@ -17026,23 +17145,23 @@ function buildPeopleRelationshipsSignature(adapter, timeRangePreset) {
17026
17145
  }
17027
17146
 
17028
17147
  // ../../packages/node-runtime/src/services/people/relationships/snapshot.ts
17029
- import fs30 from "fs";
17030
- import path27 from "path";
17148
+ import fs32 from "fs";
17149
+ import path29 from "path";
17031
17150
  var PEOPLE_RELATIONSHIPS_SNAPSHOT_TMP_PREFIX = "people-relationships-snapshot.tmp-";
17032
17151
  function getPeopleRelationshipsSnapshotPath(snapshotDir, timeRangePreset) {
17033
17152
  const preset = normalizePeopleRelationshipsTimeRangePreset(timeRangePreset);
17034
- return path27.join(snapshotDir, `graph-snapshot-${preset}.json`);
17153
+ return path29.join(snapshotDir, `graph-snapshot-${preset}.json`);
17035
17154
  }
17036
17155
  function readPeopleRelationshipsSnapshot(snapshotDir, timeRangePreset, options2 = {}) {
17037
17156
  const snapshotPath = getPeopleRelationshipsSnapshotPath(snapshotDir, timeRangePreset);
17038
- if (!fs30.existsSync(snapshotPath)) return null;
17157
+ if (!fs32.existsSync(snapshotPath)) return null;
17039
17158
  try {
17040
- return JSON.parse(fs30.readFileSync(snapshotPath, "utf-8"));
17159
+ return JSON.parse(fs32.readFileSync(snapshotPath, "utf-8"));
17041
17160
  } catch (error) {
17042
17161
  const ts = options2.now?.() ?? Date.now();
17043
- const backupPath = path27.join(snapshotDir, `graph-snapshot.corrupt-${ts}.json`);
17162
+ const backupPath = path29.join(snapshotDir, `graph-snapshot.corrupt-${ts}.json`);
17044
17163
  try {
17045
- fs30.renameSync(snapshotPath, backupPath);
17164
+ fs32.renameSync(snapshotPath, backupPath);
17046
17165
  } catch (renameError) {
17047
17166
  appLogger.warn("people-relationships", "failed to backup corrupt people relationships snapshot", renameError);
17048
17167
  }
@@ -17051,17 +17170,17 @@ function readPeopleRelationshipsSnapshot(snapshotDir, timeRangePreset, options2
17051
17170
  }
17052
17171
  }
17053
17172
  function writePeopleRelationshipsSnapshot(snapshotDir, snapshot) {
17054
- if (!fs30.existsSync(snapshotDir)) fs30.mkdirSync(snapshotDir, { recursive: true });
17055
- const tmpPath = path27.join(snapshotDir, `${PEOPLE_RELATIONSHIPS_SNAPSHOT_TMP_PREFIX}${process.pid}-${Date.now()}`);
17056
- fs30.writeFileSync(tmpPath, JSON.stringify(snapshot, null, 2), "utf-8");
17057
- fs30.renameSync(tmpPath, getPeopleRelationshipsSnapshotPath(snapshotDir, snapshot.timeRange.preset));
17173
+ if (!fs32.existsSync(snapshotDir)) fs32.mkdirSync(snapshotDir, { recursive: true });
17174
+ const tmpPath = path29.join(snapshotDir, `${PEOPLE_RELATIONSHIPS_SNAPSHOT_TMP_PREFIX}${process.pid}-${Date.now()}`);
17175
+ fs32.writeFileSync(tmpPath, JSON.stringify(snapshot, null, 2), "utf-8");
17176
+ fs32.renameSync(tmpPath, getPeopleRelationshipsSnapshotPath(snapshotDir, snapshot.timeRange.preset));
17058
17177
  }
17059
17178
  function cleanupPeopleRelationshipsSnapshotTempFiles(snapshotDir) {
17060
- if (!fs30.existsSync(snapshotDir)) return;
17061
- for (const name of fs30.readdirSync(snapshotDir)) {
17179
+ if (!fs32.existsSync(snapshotDir)) return;
17180
+ for (const name of fs32.readdirSync(snapshotDir)) {
17062
17181
  if (!name.startsWith(PEOPLE_RELATIONSHIPS_SNAPSHOT_TMP_PREFIX)) continue;
17063
17182
  try {
17064
- fs30.rmSync(path27.join(snapshotDir, name), { force: true });
17183
+ fs32.rmSync(path29.join(snapshotDir, name), { force: true });
17065
17184
  } catch (error) {
17066
17185
  appLogger.warn("people-relationships", "failed to remove people relationships snapshot temp file", error);
17067
17186
  }
@@ -17099,7 +17218,7 @@ function createWorker2(workerData, entryUrlInput) {
17099
17218
  return new Worker2(bootstrap, options2);
17100
17219
  }
17101
17220
  function createPeopleRelationshipsWorkerRunner(options2) {
17102
- return ({ signature, timeRangePreset, signal, onProgress }) => new Promise((resolve2, reject) => {
17221
+ return ({ signature, timeRangePreset, signal, onProgress }) => new Promise((resolve4, reject) => {
17103
17222
  if (signal.aborted) {
17104
17223
  reject(createAbortError2());
17105
17224
  return;
@@ -17130,7 +17249,7 @@ function createPeopleRelationshipsWorkerRunner(options2) {
17130
17249
  if (message.type === "success" && message.snapshot) {
17131
17250
  settled = true;
17132
17251
  signal.removeEventListener("abort", abort);
17133
- resolve2(message.snapshot);
17252
+ resolve4(message.snapshot);
17134
17253
  void worker.terminate();
17135
17254
  return;
17136
17255
  }
@@ -17583,7 +17702,7 @@ __export(relationships_exports, {
17583
17702
  });
17584
17703
 
17585
17704
  // ../../packages/node-runtime/src/services/global-insight/service.ts
17586
- import fs31 from "fs";
17705
+ import fs33 from "fs";
17587
17706
 
17588
17707
  // ../../packages/node-runtime/src/services/global-insight/signature.ts
17589
17708
  function buildAnnualSummarySignature(adapter, range) {
@@ -17610,7 +17729,7 @@ function resolveDefaultAnnualSummaryWorkerEntryUrl(currentModuleUrl = import.met
17610
17729
  return entryExists(sibling) ? sibling : new URL("./global-insight-worker.js", moduleUrl);
17611
17730
  }
17612
17731
  function createAnnualSummaryWorkerRunner(options2) {
17613
- return ({ signature, range, signal, onProgress }) => new Promise((resolve2, reject) => {
17732
+ return ({ signature, range, signal, onProgress }) => new Promise((resolve4, reject) => {
17614
17733
  if (signal.aborted) {
17615
17734
  reject(new Error("annual summary worker aborted"));
17616
17735
  return;
@@ -17641,7 +17760,7 @@ function createAnnualSummaryWorkerRunner(options2) {
17641
17760
  if (message.type === "success" && message.snapshot) {
17642
17761
  settled = true;
17643
17762
  signal.removeEventListener("abort", abort);
17644
- resolve2(message.snapshot);
17763
+ resolve4(message.snapshot);
17645
17764
  void worker.terminate();
17646
17765
  return;
17647
17766
  }
@@ -17836,7 +17955,7 @@ var DefaultGlobalInsightService = class {
17836
17955
  }
17837
17956
  getSnapshot(range) {
17838
17957
  const key = toAnnualSummaryRangeKey(range);
17839
- if (this.snapshots.has(key) && !fs31.existsSync(getAnnualSummarySnapshotPath(this.snapshotDir, range))) {
17958
+ if (this.snapshots.has(key) && !fs33.existsSync(getAnnualSummarySnapshotPath(this.snapshotDir, range))) {
17840
17959
  this.snapshots.delete(key);
17841
17960
  }
17842
17961
  if (!this.snapshots.has(key)) {
@@ -17884,8 +18003,8 @@ __export(global_insight_exports, {
17884
18003
  });
17885
18004
 
17886
18005
  // ../../packages/node-runtime/src/semantic-index/config.ts
17887
- import fs32 from "fs";
17888
- import path28 from "path";
18006
+ import fs34 from "fs";
18007
+ import path30 from "path";
17889
18008
  var DEFAULT_SEMANTIC_INDEX_MODEL_DOWNLOAD_SOURCE = "huggingface";
17890
18009
  var SEMANTIC_INDEX_CONFIG_VERSION = 1;
17891
18010
  var SEARCH_MAX_RESULTS_DEFAULT = 10;
@@ -17974,9 +18093,9 @@ var SemanticIndexConfigStore = class {
17974
18093
  return this.set({ ...this.get(), enabled });
17975
18094
  }
17976
18095
  get() {
17977
- if (!fs32.existsSync(this.filePath)) return defaultSemanticIndexConfig();
18096
+ if (!fs34.existsSync(this.filePath)) return defaultSemanticIndexConfig();
17978
18097
  try {
17979
- const raw = JSON.parse(fs32.readFileSync(this.filePath, "utf-8"));
18098
+ const raw = JSON.parse(fs34.readFileSync(this.filePath, "utf-8"));
17980
18099
  return normalizeConfig(raw);
17981
18100
  } catch {
17982
18101
  return defaultSemanticIndexConfig();
@@ -17984,9 +18103,9 @@ var SemanticIndexConfigStore = class {
17984
18103
  }
17985
18104
  set(config) {
17986
18105
  const normalized = normalizeConfig(config);
17987
- const dir = path28.dirname(this.filePath);
17988
- if (!fs32.existsSync(dir)) fs32.mkdirSync(dir, { recursive: true });
17989
- fs32.writeFileSync(this.filePath, JSON.stringify(normalized, null, 2), "utf-8");
18106
+ const dir = path30.dirname(this.filePath);
18107
+ if (!fs34.existsSync(dir)) fs34.mkdirSync(dir, { recursive: true });
18108
+ fs34.writeFileSync(this.filePath, JSON.stringify(normalized, null, 2), "utf-8");
17990
18109
  return normalized;
17991
18110
  }
17992
18111
  resolveModelId() {
@@ -17995,7 +18114,7 @@ var SemanticIndexConfigStore = class {
17995
18114
  };
17996
18115
 
17997
18116
  // ../../packages/node-runtime/src/semantic-index/service.ts
17998
- import path29 from "path";
18117
+ import path31 from "path";
17999
18118
 
18000
18119
  // ../../packages/node-runtime/src/semantic-index/chunker-config.ts
18001
18120
  import { createHash as createHash2 } from "crypto";
@@ -18316,8 +18435,8 @@ function createEmbedder(config, deps = {}) {
18316
18435
  if (!config.api || !config.api.baseUrl || !config.api.model) {
18317
18436
  throw new Error("semantic index API config incomplete: baseUrl and model are required");
18318
18437
  }
18319
- const resolve2 = deps.resolveApiKey ?? resolveApiKey;
18320
- const apiKey = resolve2("", config.api.authProfile);
18438
+ const resolve4 = deps.resolveApiKey ?? resolveApiKey;
18439
+ const apiKey = resolve4("", config.api.authProfile);
18321
18440
  return new OpenAICompatibleEmbeddingProvider(
18322
18441
  { baseUrl: config.api.baseUrl, apiKey, model: config.api.model },
18323
18442
  { fetchFn: deps.fetchFn }
@@ -18354,8 +18473,8 @@ function extensionSuffix(platform2) {
18354
18473
  return "so";
18355
18474
  }
18356
18475
  function platformPackageName(platform2, arch2) {
18357
- const os2 = platform2 === "win32" ? "windows" : platform2;
18358
- return `${BASE_PACKAGE_NAME}-${os2}-${arch2}`;
18476
+ const os3 = platform2 === "win32" ? "windows" : platform2;
18477
+ return `${BASE_PACKAGE_NAME}-${os3}-${arch2}`;
18359
18478
  }
18360
18479
  function getLoadablePath() {
18361
18480
  if (!validPlatform(platform, arch)) {
@@ -18854,7 +18973,7 @@ var SemanticIndexJobQueue = class {
18854
18973
  /** 等待队列清空(含当前任务) */
18855
18974
  whenIdle() {
18856
18975
  if (!this.processing && this.pending.length === 0) return Promise.resolve();
18857
- return new Promise((resolve2) => this.idleResolvers.push(resolve2));
18976
+ return new Promise((resolve4) => this.idleResolvers.push(resolve4));
18858
18977
  }
18859
18978
  removePending(dbPathHash) {
18860
18979
  this.pending = this.pending.filter((j) => j.dbPathHash !== dbPathHash);
@@ -18876,7 +18995,7 @@ var SemanticIndexJobQueue = class {
18876
18995
  this.processing = false;
18877
18996
  const resolvers = this.idleResolvers;
18878
18997
  this.idleResolvers = [];
18879
- for (const resolve2 of resolvers) resolve2();
18998
+ for (const resolve4 of resolvers) resolve4();
18880
18999
  }
18881
19000
  };
18882
19001
 
@@ -19526,16 +19645,16 @@ function resolveSearchToolEvidenceTokens(maxResultTokens) {
19526
19645
  return maxResultTokens && maxResultTokens > 0 ? Math.min(SEARCH_TOOL_EVIDENCE_TOKENS, maxResultTokens) : SEARCH_TOOL_EVIDENCE_TOKENS;
19527
19646
  }
19528
19647
  function sessionIdFromDbPath(dbPath) {
19529
- return path29.basename(dbPath, ".db");
19648
+ return path31.basename(dbPath, ".db");
19530
19649
  }
19531
19650
  var SEMANTIC_INDEX_DB_FILE = "embedding_index.db";
19532
19651
  var SEMANTIC_INDEX_CONFIG_FILE = "semantic-index-config.json";
19533
19652
  function createSemanticIndexService(params) {
19534
19653
  const { pathProvider } = params;
19535
19654
  return new SemanticIndexService({
19536
- vectorDbPath: path29.join(pathProvider.getVectorDir(), SEMANTIC_INDEX_DB_FILE),
19537
- configPath: path29.join(pathProvider.getAiDataDir(), SEMANTIC_INDEX_CONFIG_FILE),
19538
- modelsCacheDir: path29.join(pathProvider.getAiDataDir(), "models", "semantic-index"),
19655
+ vectorDbPath: path31.join(pathProvider.getVectorDir(), SEMANTIC_INDEX_DB_FILE),
19656
+ configPath: path31.join(pathProvider.getAiDataDir(), SEMANTIC_INDEX_CONFIG_FILE),
19657
+ modelsCacheDir: path31.join(pathProvider.getAiDataDir(), "models", "semantic-index"),
19539
19658
  modelDownloadProxyUrl: params.modelDownloadProxyUrl,
19540
19659
  sessionAdapter: params.sessionAdapter,
19541
19660
  nativeBinding: params.nativeBinding,
@@ -20085,8 +20204,8 @@ ${text}`;
20085
20204
  };
20086
20205
 
20087
20206
  // ../../packages/node-runtime/src/services/merge-cache.ts
20088
- import * as fs33 from "fs";
20089
- import * as path30 from "path";
20207
+ import * as fs35 from "fs";
20208
+ import * as path32 from "path";
20090
20209
  import * as crypto from "crypto";
20091
20210
  var MergeSessionCache = class {
20092
20211
  cache = /* @__PURE__ */ new Map();
@@ -20095,15 +20214,15 @@ var MergeSessionCache = class {
20095
20214
  constructor(pathProvider, options2) {
20096
20215
  this.tempDir = pathProvider.getTempDir();
20097
20216
  this.nativeBinding = options2?.nativeBinding;
20098
- if (!fs33.existsSync(this.tempDir)) {
20099
- fs33.mkdirSync(this.tempDir, { recursive: true });
20217
+ if (!fs35.existsSync(this.tempDir)) {
20218
+ fs35.mkdirSync(this.tempDir, { recursive: true });
20100
20219
  }
20101
20220
  }
20102
20221
  generateTempDbPath(filename) {
20103
20222
  const ts = Date.now();
20104
20223
  const rand = Math.random().toString(36).slice(2, 8);
20105
20224
  const safeName = filename.replace(/[/\\?%*:|"<>]/g, "_").slice(0, 40);
20106
- return path30.join(this.tempDir, `merge_${safeName}_${ts}_${rand}.db`);
20225
+ return path32.join(this.tempDir, `merge_${safeName}_${ts}_${rand}.db`);
20107
20226
  }
20108
20227
  /** Store a parsed file's temp DB and return a handle for subsequent requests. */
20109
20228
  store(filename, tempDbPath) {
@@ -20114,7 +20233,7 @@ var MergeSessionCache = class {
20114
20233
  /** Open a TempDbReader for a given handle. Caller must close the reader. */
20115
20234
  openReader(handle) {
20116
20235
  const entry = this.cache.get(handle);
20117
- if (!entry || !fs33.existsSync(entry.tempDbPath)) return null;
20236
+ if (!entry || !fs35.existsSync(entry.tempDbPath)) return null;
20118
20237
  const adapter = openBetterSqliteDatabase(entry.tempDbPath, {
20119
20238
  readonly: true,
20120
20239
  nativeBinding: this.nativeBinding
@@ -20159,7 +20278,7 @@ var MergeSessionCache = class {
20159
20278
  };
20160
20279
 
20161
20280
  // ../../packages/node-runtime/src/services/push-importer.ts
20162
- import * as fs34 from "fs";
20281
+ import * as fs36 from "fs";
20163
20282
  var SYSTEM_SENDER_ID = "SYSTEM";
20164
20283
  var SYSTEM_MEMBER_NAME = "\u7CFB\u7EDF\u6D88\u606F";
20165
20284
  function isRecord3(value) {
@@ -20526,7 +20645,7 @@ async function executePushImportUnlocked(deps, sessionId, payload) {
20526
20645
  return { ok: false, reason: "invalid_payload", message: "sessionId contains invalid characters" };
20527
20646
  }
20528
20647
  const dbPath = deps.getDbPath(sessionId);
20529
- const isNew = !fs34.existsSync(dbPath);
20648
+ const isNew = !fs36.existsSync(dbPath);
20530
20649
  const validationError = validatePayload(payload, isNew);
20531
20650
  if (validationError) {
20532
20651
  return { ok: false, reason: "invalid_payload", message: validationError };
@@ -20626,6 +20745,12 @@ var ImportIdempotencyCache = class {
20626
20745
  };
20627
20746
 
20628
20747
  export {
20748
+ CHATLAB_TEMP_ROOT_ENV,
20749
+ resolveChatLabTempRoot,
20750
+ ensureChatLabTempRoot,
20751
+ getChatLabTempScopeDir,
20752
+ createChatLabTempDir,
20753
+ removeChatLabTempDir,
20629
20754
  writeParseResultToDb,
20630
20755
  detectFormat,
20631
20756
  detectAllFormats,
@@ -20747,6 +20872,8 @@ export {
20747
20872
  checkSessionsCanGenerateSummary,
20748
20873
  MAX_CONFIG_COUNT,
20749
20874
  LLMConfigStore,
20875
+ createFileConfigStorage,
20876
+ createAuthProfileLlmConfigStore,
20750
20877
  CustomProviderStore,
20751
20878
  CustomModelStore,
20752
20879
  normalizeAnthropicBaseUrl,
@@ -20841,4 +20968,4 @@ export {
20841
20968
  hashImportBody,
20842
20969
  ImportIdempotencyCache
20843
20970
  };
20844
- //# sourceMappingURL=chunk-KCPGEILH.mjs.map
20971
+ //# sourceMappingURL=chunk-5G2INROS.mjs.map