chatlab-cli 0.31.2 → 0.31.3

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 (111) hide show
  1. package/dist/{chat-command-QPL4GNHP.mjs → chat-command-ZIXKNLSE.mjs} +15 -9
  2. package/dist/chat-command-ZIXKNLSE.mjs.map +1 -0
  3. package/dist/{chunk-OAXVKNPN.mjs → chunk-23AIEWCD.mjs} +2 -2
  4. package/dist/{chunk-F2NZ7HAY.mjs → chunk-3J7WTUEE.mjs} +2 -2
  5. package/dist/{chunk-GYPBWKAU.mjs → chunk-75FZ26HM.mjs} +896 -439
  6. package/dist/chunk-75FZ26HM.mjs.map +1 -0
  7. package/dist/{chunk-OQ6N4PDD.mjs → chunk-BLOBEOCG.mjs} +2 -2
  8. package/dist/{chunk-6JKKHPXY.mjs → chunk-DV4U34MR.mjs} +2 -2
  9. package/dist/{chunk-ZCXCHKQV.mjs → chunk-EINCXXWY.mjs} +3 -3
  10. package/dist/{chunk-3SZWD7UM.mjs → chunk-FDLLEDNW.mjs} +79 -20
  11. package/dist/chunk-FDLLEDNW.mjs.map +1 -0
  12. package/dist/{chunk-BSSR4ZYW.mjs → chunk-GZO3NAHC.mjs} +2130 -2018
  13. package/dist/chunk-GZO3NAHC.mjs.map +1 -0
  14. package/dist/{chunk-S5PQM5J4.mjs → chunk-MFOCDGCC.mjs} +17 -4
  15. package/dist/chunk-MFOCDGCC.mjs.map +1 -0
  16. package/dist/{chunk-64FKPYPJ.mjs → chunk-UIUEG7JB.mjs} +11 -11
  17. package/dist/{chunk-IK7GJTGY.mjs → chunk-YVNZ73O5.mjs} +147 -266
  18. package/dist/chunk-YVNZ73O5.mjs.map +1 -0
  19. package/dist/cli.mjs +8 -8
  20. package/dist/contacts-worker.mjs +2 -2
  21. package/dist/global-insight-worker.mjs +1 -1
  22. package/dist/{http-NOEWVWCP.mjs → http-WDG2OHOV.mjs} +11 -11
  23. package/dist/{import-RS3HW7ZM.mjs → import-4BDC37F7.mjs} +7 -7
  24. package/dist/index.mjs +11 -11
  25. package/dist/{mcp-7F3G47Z4.mjs → mcp-4KUVRGFF.mjs} +8 -8
  26. package/dist/people-relationships-worker.mjs +2 -2
  27. package/dist/semantic-index-worker.mjs +1 -1
  28. package/dist/{src-MNH5S423.mjs → src-ZOCLFBCJ.mjs} +28 -6
  29. package/dist/{stream-import-BPCHGRAN.mjs → stream-import-ERTT7U6V.mjs} +7 -7
  30. package/dist/{worker-runtime-TTAXGQ5R.mjs → worker-runtime-2TUZHV7W.mjs} +5 -5
  31. package/dist-web/assets/ActionToolsPanel-Dp-ojXjO.css +1 -0
  32. package/dist-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-GgQ5ueMX.js +110 -0
  33. package/dist-web/assets/{BufferResource-Dh2kaMuP.js → BufferResource-DgKoy0Ii.js} +1 -1
  34. package/dist-web/assets/{CanvasRenderer-B8hHywwz.js → CanvasRenderer-CKpp71xg.js} +1 -1
  35. package/dist-web/assets/{EChartWordcloud-BXC_4nUP.js → EChartWordcloud-CSOuFvyM.js} +1 -1
  36. package/dist-web/assets/{Filter-Bap1KMW6.js → Filter-D32zqY5x.js} +1 -1
  37. package/dist-web/assets/{LoadingState.vue_vue_type_script_setup_true_lang-B2KAoiMG.js → LoadingState.vue_vue_type_script_setup_true_lang-DUAtrSZD.js} +1 -1
  38. package/dist-web/assets/{MessageExportModal-H3-LAaXY.js → MessageExportModal-BYLw4vZ8.js} +1 -1
  39. package/dist-web/assets/{PageHeader-CzTV_lyM.js → PageHeader-Dmu6cdAk.js} +1 -1
  40. package/dist-web/assets/{RelationshipGalaxyCanvas-C6ZoUZNc.js → RelationshipGalaxyCanvas-DsMOubHV.js} +3 -3
  41. package/dist-web/assets/{RelationshipGalaxyThreeCanvas-DV6B-7XB.js → RelationshipGalaxyThreeCanvas-Dh5HjVHr.js} +1 -1
  42. package/dist-web/assets/{RenderTargetSystem-Dpgyoac_.js → RenderTargetSystem-CovK4x_D.js} +1 -1
  43. package/dist-web/assets/{ThemeCard.vue_vue_type_script_setup_true_lang-BWJ6kuSC.js → ThemeCard.vue_vue_type_script_setup_true_lang-DhUfYrEx.js} +1 -1
  44. package/dist-web/assets/{TimeSelect.vue_vue_type_script_setup_true_lang--Tbo7p-l.js → TimeSelect.vue_vue_type_script_setup_true_lang-CaumhCAS.js} +1 -1
  45. package/dist-web/assets/{WebGLRenderer-DICnsAm5.js → WebGLRenderer-CawhbcYU.js} +1 -1
  46. package/dist-web/assets/{WebGPURenderer-Bf0gkRK9.js → WebGPURenderer-B7P1D2sA.js} +1 -1
  47. package/dist-web/assets/{annual-summary-time-range-CK0IIPsY.js → annual-summary-time-range-Bya4h2j6.js} +1 -1
  48. package/dist-web/assets/{base-D5T8QZ8b.js → base-ClGWE9aq.js} +1 -1
  49. package/dist-web/assets/{browserAll-DcoCy7xY.js → browserAll-CtQkc1DF.js} +1 -1
  50. package/dist-web/assets/{dateFormat-BDOkdsCR.js → dateFormat-Cfb89ZjM.js} +1 -1
  51. package/dist-web/assets/{electron-CmhzSjaH.js → electron-Brd7jS6W.js} +1 -1
  52. package/dist-web/assets/{fetch-CNz28Lv5.js → fetch-BJ3lnhzK.js} +1 -1
  53. package/dist-web/assets/{fetch-DfTM4Dah.js → fetch-BoB63ns8.js} +1 -1
  54. package/dist-web/assets/fetch-BtK7YvLp.js +1 -0
  55. package/dist-web/assets/{fetch-D71bG6Fc.js → fetch-CeREJiFL.js} +1 -1
  56. package/dist-web/assets/{fetch-C1mlq5VY.js → fetch-D2hvh7lO.js} +1 -1
  57. package/dist-web/assets/{fetch-DtcNaN3d.js → fetch-DVGCzZ0E.js} +1 -1
  58. package/dist-web/assets/{fetch-BddgpyKJ.js → fetch-DWoMmOlr.js} +1 -1
  59. package/dist-web/assets/{fetch-dI5w8lYN.js → fetch-DkfUUq-R.js} +1 -1
  60. package/dist-web/assets/{fetch-D8xv4lgE.js → fetch-Dr_Fjtvp.js} +1 -1
  61. package/dist-web/assets/{fetch-TATpgXht.js → fetch-u7ivV7Uy.js} +1 -1
  62. package/dist-web/assets/{index-CY5yJhCJ.js → index-BHnQaeQY.js} +1 -1
  63. package/dist-web/assets/{index-qZ7jnIna.js → index-BXaKyn8J.js} +2 -2
  64. package/dist-web/assets/{index-Dtbu8m1o.js → index-BzH9cnfy.js} +1 -1
  65. package/dist-web/assets/{index-Bs4ZX2-v.js → index-CuPE4SSh.js} +1 -1
  66. package/dist-web/assets/index-D-qNxFxp.js +173 -0
  67. package/dist-web/assets/index-D494nYee.js +64 -0
  68. package/dist-web/assets/index-D8Uq3_Dc.css +1 -0
  69. package/dist-web/assets/index-DBb03wVF.css +1 -0
  70. package/dist-web/assets/{index-DClxj4T2.js → index-DJ8kB4US.js} +2 -2
  71. package/dist-web/assets/{index-De3ImZb9.js → index-DNMWR2Vj.js} +1 -1
  72. package/dist-web/assets/{index-DphjBwbA.js → index-DSPls1YV.js} +1 -1
  73. package/dist-web/assets/{index-soX5gDgh.js → index-DcAqhCpS.js} +1 -1
  74. package/dist-web/assets/{index-a1ZrlsKo.js → index-DnkaYOFI.js} +1 -1
  75. package/dist-web/assets/index-_UKteDZB.js +25 -0
  76. package/dist-web/assets/index-gi0wgh0M.css +1 -0
  77. package/dist-web/assets/{index-Dp3gCHpK.js → index-w_1EjXiF.js} +1 -1
  78. package/dist-web/assets/{people-page-header-D93GTPBO.js → people-page-header-YGQM9G53.js} +1 -1
  79. package/dist-web/assets/{vendor-nuxt-ui-DUpPmItD.js → vendor-nuxt-ui-DmkGVKod.js} +2 -2
  80. package/dist-web/assets/{vendor-reka-ui-BLnO2MqY.js → vendor-reka-ui-BkhadcDj.js} +1 -1
  81. package/dist-web/assets/{web-H9T1dZys.js → web-zXxtk2KZ.js} +1 -1
  82. package/dist-web/assets/{webworkerAll-D1Kui8G8.js → webworkerAll-BzRoT-6m.js} +1 -1
  83. package/dist-web/index.html +4 -4
  84. package/package.json +1 -1
  85. package/dist/chat-command-QPL4GNHP.mjs.map +0 -1
  86. package/dist/chunk-3SZWD7UM.mjs.map +0 -1
  87. package/dist/chunk-BSSR4ZYW.mjs.map +0 -1
  88. package/dist/chunk-GYPBWKAU.mjs.map +0 -1
  89. package/dist/chunk-IK7GJTGY.mjs.map +0 -1
  90. package/dist/chunk-S5PQM5J4.mjs.map +0 -1
  91. package/dist-web/assets/ActionToolsPanel-CbWhu_Uv.css +0 -1
  92. package/dist-web/assets/ActionToolsPanel.vue_vue_type_script_setup_true_lang-CvvNqXuh.js +0 -110
  93. package/dist-web/assets/fetch-BJka-sCN.js +0 -1
  94. package/dist-web/assets/index-CAjUCtGD.css +0 -1
  95. package/dist-web/assets/index-CF59LLOG.js +0 -25
  96. package/dist-web/assets/index-CJ3WtSLo.js +0 -173
  97. package/dist-web/assets/index-CJS6FVuj.js +0 -64
  98. package/dist-web/assets/index-CsqMIyA9.css +0 -1
  99. package/dist-web/assets/index-CtmXho1w.css +0 -1
  100. /package/dist/{chunk-OAXVKNPN.mjs.map → chunk-23AIEWCD.mjs.map} +0 -0
  101. /package/dist/{chunk-F2NZ7HAY.mjs.map → chunk-3J7WTUEE.mjs.map} +0 -0
  102. /package/dist/{chunk-OQ6N4PDD.mjs.map → chunk-BLOBEOCG.mjs.map} +0 -0
  103. /package/dist/{chunk-6JKKHPXY.mjs.map → chunk-DV4U34MR.mjs.map} +0 -0
  104. /package/dist/{chunk-ZCXCHKQV.mjs.map → chunk-EINCXXWY.mjs.map} +0 -0
  105. /package/dist/{chunk-64FKPYPJ.mjs.map → chunk-UIUEG7JB.mjs.map} +0 -0
  106. /package/dist/{http-NOEWVWCP.mjs.map → http-WDG2OHOV.mjs.map} +0 -0
  107. /package/dist/{import-RS3HW7ZM.mjs.map → import-4BDC37F7.mjs.map} +0 -0
  108. /package/dist/{mcp-7F3G47Z4.mjs.map → mcp-4KUVRGFF.mjs.map} +0 -0
  109. /package/dist/{src-MNH5S423.mjs.map → src-ZOCLFBCJ.mjs.map} +0 -0
  110. /package/dist/{stream-import-BPCHGRAN.mjs.map → stream-import-ERTT7U6V.mjs.map} +0 -0
  111. /package/dist/{worker-runtime-TTAXGQ5R.mjs.map → worker-runtime-2TUZHV7W.mjs.map} +0 -0
@@ -235,72 +235,9 @@ function parseValueByType(section, key, expectedType, rawValue) {
235
235
  return rawValue;
236
236
  }
237
237
 
238
- // ../../packages/config/src/auth-profiles.ts
238
+ // ../../packages/config/src/migrations/runner.ts
239
239
  import * as fs3 from "fs";
240
240
  import * as path3 from "path";
241
- var AUTH_PROFILES_FILE = "auth-profiles.json";
242
- function getAuthProfilesPath() {
243
- return path3.join(getConfigDir(), AUTH_PROFILES_FILE);
244
- }
245
- function loadAuthProfiles() {
246
- const filePath = getAuthProfilesPath();
247
- if (!fs3.existsSync(filePath)) {
248
- return { version: 1, profiles: {} };
249
- }
250
- try {
251
- const content = fs3.readFileSync(filePath, "utf-8");
252
- const data = JSON.parse(content);
253
- if (!data.profiles || typeof data.profiles !== "object") {
254
- return { version: 1, profiles: {} };
255
- }
256
- return data;
257
- } catch {
258
- return { version: 1, profiles: {} };
259
- }
260
- }
261
- function getApiKeyByProfile(profileName) {
262
- const data = loadAuthProfiles();
263
- const profile = data.profiles[profileName];
264
- return profile?.key || "";
265
- }
266
- function getApiKeyByProvider(provider) {
267
- const data = loadAuthProfiles();
268
- for (const profile of Object.values(data.profiles)) {
269
- if (profile.provider === provider) {
270
- return profile.key || "";
271
- }
272
- }
273
- return "";
274
- }
275
- function resolveApiKey(provider, authProfile) {
276
- if (authProfile) {
277
- const key = getApiKeyByProfile(authProfile);
278
- if (key) return key;
279
- }
280
- return getApiKeyByProvider(provider);
281
- }
282
- function writeAuthProfile(name, profile) {
283
- const configDir = getConfigDir();
284
- if (!fs3.existsSync(configDir)) {
285
- fs3.mkdirSync(configDir, { recursive: true });
286
- }
287
- const data = loadAuthProfiles();
288
- data.profiles[name] = profile;
289
- const filePath = getAuthProfilesPath();
290
- fs3.writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
291
- }
292
- function deleteAuthProfile(name) {
293
- const data = loadAuthProfiles();
294
- if (!(name in data.profiles)) return false;
295
- delete data.profiles[name];
296
- const filePath = getAuthProfilesPath();
297
- fs3.writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
298
- return true;
299
- }
300
-
301
- // ../../packages/config/src/migrations/runner.ts
302
- import * as fs4 from "fs";
303
- import * as path4 from "path";
304
241
  var VERSION_FILE = ".migration-version";
305
242
  var MigrationRunner = class {
306
243
  migrations;
@@ -310,10 +247,10 @@ var MigrationRunner = class {
310
247
  this.context = context;
311
248
  }
312
249
  getCurrentVersion() {
313
- const versionPath = path4.join(this.context.dataDir, VERSION_FILE);
250
+ const versionPath = path3.join(this.context.dataDir, VERSION_FILE);
314
251
  try {
315
- if (fs4.existsSync(versionPath)) {
316
- const raw = fs4.readFileSync(versionPath, "utf-8").trim();
252
+ if (fs3.existsSync(versionPath)) {
253
+ const raw = fs3.readFileSync(versionPath, "utf-8").trim();
317
254
  const ver = parseInt(raw, 10);
318
255
  return Number.isFinite(ver) ? ver : 0;
319
256
  }
@@ -322,12 +259,12 @@ var MigrationRunner = class {
322
259
  return 0;
323
260
  }
324
261
  writeVersion(version) {
325
- const versionPath = path4.join(this.context.dataDir, VERSION_FILE);
262
+ const versionPath = path3.join(this.context.dataDir, VERSION_FILE);
326
263
  try {
327
- if (!fs4.existsSync(this.context.dataDir)) {
328
- fs4.mkdirSync(this.context.dataDir, { recursive: true });
264
+ if (!fs3.existsSync(this.context.dataDir)) {
265
+ fs3.mkdirSync(this.context.dataDir, { recursive: true });
329
266
  }
330
- fs4.writeFileSync(versionPath, String(version), "utf-8");
267
+ fs3.writeFileSync(versionPath, String(version), "utf-8");
331
268
  } catch (err) {
332
269
  this.context.logger.error("Migration", `Failed to write version file: ${err}`);
333
270
  }
@@ -359,8 +296,8 @@ var MigrationRunner = class {
359
296
  };
360
297
 
361
298
  // ../../packages/config/src/migrations/m001-legacy-to-multi-config.ts
362
- import * as fs5 from "fs";
363
- import * as path5 from "path";
299
+ import * as fs4 from "fs";
300
+ import * as path4 from "path";
364
301
  import { randomUUID } from "crypto";
365
302
  function isLegacyFlatConfig(data) {
366
303
  if (!data || typeof data !== "object") return false;
@@ -372,9 +309,9 @@ var m001LegacyToMultiConfig = {
372
309
  name: "legacy-to-multi-config",
373
310
  description: "Convert legacy flat LLM config to multi-config format",
374
311
  async up(ctx) {
375
- const configPath = path5.join(ctx.aiDataDir, "llm-config.json");
376
- if (!fs5.existsSync(configPath)) return;
377
- const raw = fs5.readFileSync(configPath, "utf-8");
312
+ const configPath = path4.join(ctx.aiDataDir, "llm-config.json");
313
+ if (!fs4.existsSync(configPath)) return;
314
+ const raw = fs4.readFileSync(configPath, "utf-8");
378
315
  let data;
379
316
  try {
380
317
  data = JSON.parse(raw);
@@ -400,24 +337,24 @@ var m001LegacyToMultiConfig = {
400
337
  defaultAssistant: { configId: newConfig.id, modelId: newConfig.model },
401
338
  fastModel: null
402
339
  };
403
- fs5.writeFileSync(configPath, JSON.stringify(migrated, null, 2), "utf-8");
340
+ fs4.writeFileSync(configPath, JSON.stringify(migrated, null, 2), "utf-8");
404
341
  ctx.logger.info("Migration", "Legacy config migrated to multi-config format");
405
342
  }
406
343
  };
407
344
 
408
345
  // ../../packages/config/src/migrations/m002-schema-v2.ts
409
- import * as fs6 from "fs";
410
- import * as path6 from "path";
346
+ import * as fs5 from "fs";
347
+ import * as path5 from "path";
411
348
  var m002SchemaV2 = {
412
349
  version: 2,
413
350
  name: "schema-v2",
414
351
  description: "Upgrade LLM config to schema v2 (remove deprecated fields)",
415
352
  async up(ctx) {
416
- const configPath = path6.join(ctx.aiDataDir, "llm-config.json");
417
- if (!fs6.existsSync(configPath)) return;
353
+ const configPath = path5.join(ctx.aiDataDir, "llm-config.json");
354
+ if (!fs5.existsSync(configPath)) return;
418
355
  let data;
419
356
  try {
420
- data = JSON.parse(fs6.readFileSync(configPath, "utf-8"));
357
+ data = JSON.parse(fs5.readFileSync(configPath, "utf-8"));
421
358
  } catch {
422
359
  return;
423
360
  }
@@ -431,23 +368,23 @@ var m002SchemaV2 = {
431
368
  });
432
369
  data.configs = cleanedConfigs;
433
370
  data.schemaVersion = 2;
434
- fs6.writeFileSync(configPath, JSON.stringify(data, null, 2), "utf-8");
371
+ fs5.writeFileSync(configPath, JSON.stringify(data, null, 2), "utf-8");
435
372
  }
436
373
  };
437
374
 
438
375
  // ../../packages/config/src/migrations/m003-schema-v3.ts
439
- import * as fs7 from "fs";
440
- import * as path7 from "path";
376
+ import * as fs6 from "fs";
377
+ import * as path6 from "path";
441
378
  var m003SchemaV3 = {
442
379
  version: 3,
443
380
  name: "schema-v3-dual-slot",
444
381
  description: "Upgrade LLM config to schema v3 (dual-slot model selection)",
445
382
  async up(ctx) {
446
- const configPath = path7.join(ctx.aiDataDir, "llm-config.json");
447
- if (!fs7.existsSync(configPath)) return;
383
+ const configPath = path6.join(ctx.aiDataDir, "llm-config.json");
384
+ if (!fs6.existsSync(configPath)) return;
448
385
  let data;
449
386
  try {
450
- data = JSON.parse(fs7.readFileSync(configPath, "utf-8"));
387
+ data = JSON.parse(fs6.readFileSync(configPath, "utf-8"));
451
388
  } catch {
452
389
  return;
453
390
  }
@@ -461,7 +398,7 @@ var m003SchemaV3 = {
461
398
  data.fastModel = data.fastModel ?? null;
462
399
  data.schemaVersion = 3;
463
400
  delete data.activeConfigId;
464
- fs7.writeFileSync(configPath, JSON.stringify(data, null, 2), "utf-8");
401
+ fs6.writeFileSync(configPath, JSON.stringify(data, null, 2), "utf-8");
465
402
  }
466
403
  };
467
404
 
@@ -470,9 +407,9 @@ import * as fs9 from "fs";
470
407
  import * as path9 from "path";
471
408
 
472
409
  // ../../packages/config/src/migrations/crypto-legacy.ts
473
- import * as fs8 from "fs";
410
+ import * as fs7 from "fs";
474
411
  import * as os2 from "os";
475
- import * as path8 from "path";
412
+ import * as path7 from "path";
476
413
  import { createDecipheriv, createHash } from "crypto";
477
414
  import { execSync } from "child_process";
478
415
  var ENCRYPTED_PREFIX = "enc:";
@@ -484,8 +421,8 @@ function isEncrypted(value) {
484
421
  }
485
422
  function readKeyFromFile(keyPath) {
486
423
  try {
487
- if (fs8.existsSync(keyPath)) {
488
- const key = fs8.readFileSync(keyPath, "utf-8").trim();
424
+ if (fs7.existsSync(keyPath)) {
425
+ const key = fs7.readFileSync(keyPath, "utf-8").trim();
489
426
  if (key.length >= 32) return key;
490
427
  }
491
428
  } catch {
@@ -494,14 +431,14 @@ function readKeyFromFile(keyPath) {
494
431
  }
495
432
  function getAllDeviceKeyPaths() {
496
433
  const home = os2.homedir();
497
- const paths = [path8.join(home, ".chatlab", DEVICE_KEY_FILE)];
434
+ const paths = [path7.join(home, ".chatlab", DEVICE_KEY_FILE)];
498
435
  if (process.platform === "darwin") {
499
- paths.push(path8.join(home, "Library", "Application Support", "ChatLab", "data", DEVICE_KEY_FILE));
436
+ paths.push(path7.join(home, "Library", "Application Support", "ChatLab", "data", DEVICE_KEY_FILE));
500
437
  } else if (process.platform === "win32") {
501
- const appData = process.env.APPDATA || path8.join(home, "AppData", "Roaming");
502
- paths.push(path8.join(appData, "ChatLab", "data", DEVICE_KEY_FILE));
438
+ const appData = process.env.APPDATA || path7.join(home, "AppData", "Roaming");
439
+ paths.push(path7.join(appData, "ChatLab", "data", DEVICE_KEY_FILE));
503
440
  } else {
504
- paths.push(path8.join(home, ".config", "ChatLab", "data", DEVICE_KEY_FILE));
441
+ paths.push(path7.join(home, ".config", "ChatLab", "data", DEVICE_KEY_FILE));
505
442
  }
506
443
  return paths;
507
444
  }
@@ -582,6 +519,69 @@ function decryptApiKey(encrypted) {
582
519
  return "";
583
520
  }
584
521
 
522
+ // ../../packages/config/src/auth-profiles.ts
523
+ import * as fs8 from "fs";
524
+ import * as path8 from "path";
525
+ var AUTH_PROFILES_FILE = "auth-profiles.json";
526
+ function getAuthProfilesPath() {
527
+ return path8.join(getConfigDir(), AUTH_PROFILES_FILE);
528
+ }
529
+ function loadAuthProfiles() {
530
+ const filePath = getAuthProfilesPath();
531
+ if (!fs8.existsSync(filePath)) {
532
+ return { version: 1, profiles: {} };
533
+ }
534
+ try {
535
+ const content = fs8.readFileSync(filePath, "utf-8");
536
+ const data = JSON.parse(content);
537
+ if (!data.profiles || typeof data.profiles !== "object") {
538
+ return { version: 1, profiles: {} };
539
+ }
540
+ return data;
541
+ } catch {
542
+ return { version: 1, profiles: {} };
543
+ }
544
+ }
545
+ function getApiKeyByProfile(profileName) {
546
+ const data = loadAuthProfiles();
547
+ const profile = data.profiles[profileName];
548
+ return profile?.key || "";
549
+ }
550
+ function getApiKeyByProvider(provider) {
551
+ const data = loadAuthProfiles();
552
+ for (const profile of Object.values(data.profiles)) {
553
+ if (profile.provider === provider) {
554
+ return profile.key || "";
555
+ }
556
+ }
557
+ return "";
558
+ }
559
+ function resolveApiKey(provider, authProfile) {
560
+ if (authProfile) {
561
+ const key = getApiKeyByProfile(authProfile);
562
+ if (key) return key;
563
+ }
564
+ return getApiKeyByProvider(provider);
565
+ }
566
+ function writeAuthProfile(name, profile) {
567
+ const configDir = getConfigDir();
568
+ if (!fs8.existsSync(configDir)) {
569
+ fs8.mkdirSync(configDir, { recursive: true });
570
+ }
571
+ const data = loadAuthProfiles();
572
+ data.profiles[name] = profile;
573
+ const filePath = getAuthProfilesPath();
574
+ fs8.writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
575
+ }
576
+ function deleteAuthProfile(name) {
577
+ const data = loadAuthProfiles();
578
+ if (!(name in data.profiles)) return false;
579
+ delete data.profiles[name];
580
+ const filePath = getAuthProfilesPath();
581
+ fs8.writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
582
+ return true;
583
+ }
584
+
585
585
  // ../../packages/config/src/migrations/m004-encrypted-keys-to-auth-profiles.ts
586
586
  function deriveProfileName(provider, config) {
587
587
  if (provider !== "openai-compatible") {
@@ -715,6 +715,28 @@ function openBetterSqliteDatabase(filePath, options) {
715
715
  return new BetterSqliteAdapter(db);
716
716
  }
717
717
 
718
+ // ../../packages/shared-types/index.ts
719
+ var KNOWN_PLATFORMS = {
720
+ QQ: "qq",
721
+ WECHAT: "weixin",
722
+ DISCORD: "discord",
723
+ WHATSAPP: "whatsapp",
724
+ TELEGRAM: "telegram",
725
+ INSTAGRAM: "instagram",
726
+ GOOGLE_CHAT: "google-chat",
727
+ LINE: "line",
728
+ UNKNOWN: "unknown"
729
+ };
730
+ var GENERAL_ASSISTANT_IDS = ["general_cn", "general_tw", "general_en", "general_ja"];
731
+ var DEFAULT_GENERAL_ASSISTANT_ID = "general_cn";
732
+ function getDefaultGeneralAssistantId(locale) {
733
+ if (locale?.startsWith("zh-TW")) return "general_tw";
734
+ if (locale?.startsWith("en")) return "general_en";
735
+ if (locale?.startsWith("ja")) return "general_ja";
736
+ return DEFAULT_GENERAL_ASSISTANT_ID;
737
+ }
738
+ var CONTACTS_TIME_RANGE_PRESETS = ["1y", "2y", "3y", "5y", "all"];
739
+
718
740
  // ../../packages/node-runtime/src/ai/ai-logger.ts
719
741
  import * as fs10 from "fs";
720
742
  import * as path10 from "path";
@@ -2999,10 +3021,7 @@ function getMentionAnalysis(db, filter) {
2999
3021
  const emptyResult = {
3000
3022
  topMentioners: [],
3001
3023
  topMentioned: [],
3002
- oneWay: [],
3003
- twoWay: [],
3004
- totalMentions: 0,
3005
- memberDetails: []
3024
+ totalMentions: 0
3006
3025
  };
3007
3026
  const members = db.prepare(
3008
3027
  `SELECT id, platform_id as platformId, COALESCE(group_nickname, account_name, platform_id) as name
@@ -3032,7 +3051,6 @@ function getMentionAnalysis(db, filter) {
3032
3051
  `SELECT msg.sender_id as senderId, msg.content
3033
3052
  FROM message msg JOIN member m ON msg.sender_id = m.id ${whereClause}`
3034
3053
  ).all(...params);
3035
- const mentionMatrix = /* @__PURE__ */ new Map();
3036
3054
  const mentionedCount = /* @__PURE__ */ new Map();
3037
3055
  const mentionerCount = /* @__PURE__ */ new Map();
3038
3056
  let totalMentions = 0;
@@ -3045,9 +3063,6 @@ function getMentionAnalysis(db, filter) {
3045
3063
  if (mentionedId && mentionedId !== msg.senderId && !mentionedInThisMsg.has(mentionedId)) {
3046
3064
  mentionedInThisMsg.add(mentionedId);
3047
3065
  totalMentions++;
3048
- if (!mentionMatrix.has(msg.senderId)) mentionMatrix.set(msg.senderId, /* @__PURE__ */ new Map());
3049
- const fromMap = mentionMatrix.get(msg.senderId);
3050
- fromMap.set(mentionedId, (fromMap.get(mentionedId) || 0) + 1);
3051
3066
  mentionerCount.set(msg.senderId, (mentionerCount.get(msg.senderId) || 0) + 1);
3052
3067
  mentionedCount.set(mentionedId, (mentionedCount.get(mentionedId) || 0) + 1);
3053
3068
  }
@@ -3078,116 +3093,7 @@ function getMentionAnalysis(db, filter) {
3078
3093
  });
3079
3094
  }
3080
3095
  topMentioned.sort((a, b) => b.count - a.count);
3081
- const oneWay = [];
3082
- const processedPairs = /* @__PURE__ */ new Set();
3083
- for (const [fromId, toMap] of mentionMatrix.entries()) {
3084
- for (const [toId, fromToCount] of toMap.entries()) {
3085
- const pairKey = `${Math.min(fromId, toId)}-${Math.max(fromId, toId)}`;
3086
- if (processedPairs.has(pairKey)) continue;
3087
- processedPairs.add(pairKey);
3088
- const toFromCount = mentionMatrix.get(toId)?.get(fromId) || 0;
3089
- const total = fromToCount + toFromCount;
3090
- if (total < 3) continue;
3091
- const ratio = fromToCount / total;
3092
- if (ratio >= 0.8) {
3093
- const fromInfo = memberIdToInfo.get(fromId);
3094
- const toInfo = memberIdToInfo.get(toId);
3095
- oneWay.push({
3096
- fromMemberId: fromId,
3097
- fromName: fromInfo.name,
3098
- toMemberId: toId,
3099
- toName: toInfo.name,
3100
- fromToCount,
3101
- toFromCount,
3102
- ratio: Math.round(ratio * 100) / 100
3103
- });
3104
- } else if (ratio <= 0.2) {
3105
- const fromInfo = memberIdToInfo.get(fromId);
3106
- const toInfo = memberIdToInfo.get(toId);
3107
- oneWay.push({
3108
- fromMemberId: toId,
3109
- fromName: toInfo.name,
3110
- toMemberId: fromId,
3111
- toName: fromInfo.name,
3112
- fromToCount: toFromCount,
3113
- toFromCount: fromToCount,
3114
- ratio: Math.round((1 - ratio) * 100) / 100
3115
- });
3116
- }
3117
- }
3118
- }
3119
- oneWay.sort((a, b) => b.fromToCount - a.fromToCount);
3120
- const twoWay = [];
3121
- processedPairs.clear();
3122
- for (const [fromId, toMap] of mentionMatrix.entries()) {
3123
- for (const [toId, fromToCount] of toMap.entries()) {
3124
- const pairKey = `${Math.min(fromId, toId)}-${Math.max(fromId, toId)}`;
3125
- if (processedPairs.has(pairKey)) continue;
3126
- processedPairs.add(pairKey);
3127
- const toFromCount = mentionMatrix.get(toId)?.get(fromId) || 0;
3128
- const total = fromToCount + toFromCount;
3129
- if (total < 5 || toFromCount === 0 || fromToCount === 0) continue;
3130
- const ratio = Math.min(fromToCount, toFromCount) / Math.max(fromToCount, toFromCount);
3131
- if (ratio >= 0.3) {
3132
- const m1Info = memberIdToInfo.get(fromId);
3133
- const m2Info = memberIdToInfo.get(toId);
3134
- twoWay.push({
3135
- member1Id: fromId,
3136
- member1Name: m1Info.name,
3137
- member2Id: toId,
3138
- member2Name: m2Info.name,
3139
- member1To2: fromToCount,
3140
- member2To1: toFromCount,
3141
- total,
3142
- balance: Math.round(ratio * 100) / 100
3143
- });
3144
- }
3145
- }
3146
- }
3147
- twoWay.sort((a, b) => b.total - a.total);
3148
- const memberDetails = [];
3149
- for (const member of members) {
3150
- const info = memberIdToInfo.get(member.id);
3151
- const topMentionedByThis = [];
3152
- const toMap = mentionMatrix.get(member.id);
3153
- if (toMap) {
3154
- for (const [toId, count] of toMap.entries()) {
3155
- const toInfo = memberIdToInfo.get(toId);
3156
- topMentionedByThis.push({
3157
- fromMemberId: member.id,
3158
- fromName: info.name,
3159
- toMemberId: toId,
3160
- toName: toInfo.name,
3161
- count
3162
- });
3163
- }
3164
- topMentionedByThis.sort((a, b) => b.count - a.count);
3165
- }
3166
- const topMentionersOfThis = [];
3167
- for (const [fromId, fToMap] of mentionMatrix.entries()) {
3168
- const count = fToMap.get(member.id);
3169
- if (count) {
3170
- const fromInfo = memberIdToInfo.get(fromId);
3171
- topMentionersOfThis.push({
3172
- fromMemberId: fromId,
3173
- fromName: fromInfo.name,
3174
- toMemberId: member.id,
3175
- toName: info.name,
3176
- count
3177
- });
3178
- }
3179
- }
3180
- topMentionersOfThis.sort((a, b) => b.count - a.count);
3181
- if (topMentionedByThis.length > 0 || topMentionersOfThis.length > 0) {
3182
- memberDetails.push({
3183
- memberId: member.id,
3184
- name: info.name,
3185
- topMentioned: topMentionedByThis.slice(0, 5),
3186
- topMentioners: topMentionersOfThis.slice(0, 5)
3187
- });
3188
- }
3189
- }
3190
- return { topMentioners, topMentioned, oneWay, twoWay, totalMentions, memberDetails };
3096
+ return { topMentioners, topMentioned, totalMentions };
3191
3097
  }
3192
3098
  function getMentionGraph(db, filter) {
3193
3099
  const emptyResult = { nodes: [], links: [], maxLinkValue: 0 };
@@ -3975,20 +3881,6 @@ function buildContactKey(platform, platformId, sessionId) {
3975
3881
  return sessionId?.trim() ? `${normalizedPlatform}:${sessionId.trim()}:${normalizedPlatformId}` : `${normalizedPlatform}:${normalizedPlatformId}`;
3976
3882
  }
3977
3883
 
3978
- // ../../packages/shared-types/index.ts
3979
- var KNOWN_PLATFORMS = {
3980
- QQ: "qq",
3981
- WECHAT: "weixin",
3982
- DISCORD: "discord",
3983
- WHATSAPP: "whatsapp",
3984
- TELEGRAM: "telegram",
3985
- INSTAGRAM: "instagram",
3986
- GOOGLE_CHAT: "google-chat",
3987
- LINE: "line",
3988
- UNKNOWN: "unknown"
3989
- };
3990
- var CONTACTS_TIME_RANGE_PRESETS = ["1y", "2y", "3y", "5y", "all"];
3991
-
3992
3884
  // ../../packages/core/src/query/global-insight.ts
3993
3885
  var SYSTEM_MESSAGE_TYPES2 = [80 /* SYSTEM */, 81 /* RECALL */];
3994
3886
  function getAnnualSummarySessionFacts(db, sessionId, range) {
@@ -4634,26 +4526,6 @@ function getMembers(db) {
4634
4526
  ORDER BY messageCount DESC`
4635
4527
  ).all();
4636
4528
  }
4637
- function getMembersDetailed(db) {
4638
- const rows = db.prepare(
4639
- `SELECT
4640
- m.id as id,
4641
- m.platform_id as platformId,
4642
- COALESCE(m.account_name, m.platform_id) as accountName,
4643
- m.group_nickname as groupNickname,
4644
- (SELECT COUNT(*) FROM message WHERE sender_id = m.id) as messageCount
4645
- FROM member m
4646
- WHERE COALESCE(m.account_name, '') != '\u7CFB\u7EDF\u6D88\u606F'
4647
- ORDER BY messageCount DESC`
4648
- ).all();
4649
- return rows.map((row) => ({
4650
- id: Number(row.id),
4651
- platformId: String(row.platformId),
4652
- accountName: String(row.accountName || row.platformId),
4653
- groupNickname: row.groupNickname ? String(row.groupNickname) : null,
4654
- messageCount: Number(row.messageCount)
4655
- }));
4656
- }
4657
4529
  function executeReadonlySql(db, sql, maxRows = 1e3) {
4658
4530
  const result = executeSql(db, sql, { maxRows });
4659
4531
  return {
@@ -5034,14 +4906,20 @@ function mergeMembers(db, memberId1, memberId2) {
5034
4906
  return false;
5035
4907
  }
5036
4908
  }
4909
+ function deleteMembers(db, memberIds) {
4910
+ const uniqueMemberIds = Array.from(new Set(memberIds));
4911
+ if (uniqueMemberIds.length === 0) return false;
4912
+ const placeholders = uniqueMemberIds.map(() => "?").join(", ");
4913
+ db.transaction(() => {
4914
+ db.prepare(`DELETE FROM message WHERE sender_id IN (${placeholders})`).run(...uniqueMemberIds);
4915
+ db.prepare(`DELETE FROM member_name_history WHERE member_id IN (${placeholders})`).run(...uniqueMemberIds);
4916
+ db.prepare(`DELETE FROM member WHERE id IN (${placeholders})`).run(...uniqueMemberIds);
4917
+ });
4918
+ return true;
4919
+ }
5037
4920
  function deleteMember(db, memberId) {
5038
4921
  try {
5039
- db.transaction(() => {
5040
- db.prepare("DELETE FROM message WHERE sender_id = ?").run(memberId);
5041
- db.prepare("DELETE FROM member_name_history WHERE member_id = ?").run(memberId);
5042
- db.prepare("DELETE FROM member WHERE id = ?").run(memberId);
5043
- });
5044
- return true;
4922
+ return deleteMembers(db, [memberId]);
5045
4923
  } catch {
5046
4924
  return false;
5047
4925
  }
@@ -5097,6 +4975,7 @@ function getCatchphraseAnalysis(db, filter) {
5097
4975
  JOIN member m ON msg.sender_id = m.id
5098
4976
  ${whereClause}
5099
4977
  GROUP BY m.id, TRIM(msg.content)
4978
+ HAVING COUNT(*) >= 2
5100
4979
  ORDER BY m.id, count DESC
5101
4980
  `
5102
4981
  ).all(...params);
@@ -5118,9 +4997,8 @@ function getCatchphraseAnalysis(db, filter) {
5118
4997
  }
5119
4998
  const members = Array.from(memberMap.values());
5120
4999
  members.sort((a, b) => {
5121
- const aTotal = a.catchphrases.reduce((sum, c) => sum + c.count, 0);
5122
- const bTotal = b.catchphrases.reduce((sum, c) => sum + c.count, 0);
5123
- return bTotal - aTotal;
5000
+ const countDifference = (b.catchphrases[0]?.count ?? 0) - (a.catchphrases[0]?.count ?? 0);
5001
+ return countDifference || a.memberId - b.memberId;
5124
5002
  });
5125
5003
  return { members };
5126
5004
  }
@@ -7956,15 +7834,15 @@ function tokenizeQueryForFts(keywords) {
7956
7834
  import * as fs13 from "fs";
7957
7835
  import * as os3 from "os";
7958
7836
  import * as path13 from "path";
7959
- var SYSTEM_SUBDIRS = ["ai", "settings", "cache", "logs", "temp", "nlp"];
7837
+ var SYSTEM_SUBDIRS = ["ai", "settings", "cache", "logs", "nlp"];
7960
7838
  var STORAGE_CONFIG_FILE = "storage.json";
7961
- function getElectronUserDataDir() {
7962
- const home = os3.homedir();
7963
- switch (process.platform) {
7839
+ function getElectronUserDataDir(options = {}) {
7840
+ const home = options.homeDir ?? os3.homedir();
7841
+ switch (options.platform ?? process.platform) {
7964
7842
  case "darwin":
7965
7843
  return path13.join(home, "Library", "Application Support", "ChatLab");
7966
7844
  case "win32": {
7967
- const appData = process.env.APPDATA || path13.join(home, "AppData", "Roaming");
7845
+ const appData = options.appDataDir ?? process.env.APPDATA ?? path13.join(home, "AppData", "Roaming");
7968
7846
  return path13.join(appData, "ChatLab");
7969
7847
  }
7970
7848
  default:
@@ -9218,6 +9096,9 @@ export {
9218
9096
  BetterSqliteAdapter,
9219
9097
  openBetterSqliteDatabase,
9220
9098
  KNOWN_PLATFORMS,
9099
+ GENERAL_ASSISTANT_IDS,
9100
+ DEFAULT_GENERAL_ASSISTANT_ID,
9101
+ getDefaultGeneralAssistantId,
9221
9102
  CONTACTS_TIME_RANGE_PRESETS,
9222
9103
  AiLogger,
9223
9104
  extractErrorInfo,
@@ -9283,7 +9164,6 @@ export {
9283
9164
  searchMessagesLike,
9284
9165
  searchMessagesByKeywords,
9285
9166
  getMembers,
9286
- getMembersDetailed,
9287
9167
  executeReadonlySql,
9288
9168
  executeSql,
9289
9169
  getSchemaDetailed,
@@ -9297,6 +9177,7 @@ export {
9297
9177
  computeResponseTimeStats,
9298
9178
  updateMemberAliases,
9299
9179
  mergeMembers,
9180
+ deleteMembers,
9300
9181
  deleteMember,
9301
9182
  getCatchphraseAnalysis,
9302
9183
  getRelationshipStats,
@@ -9385,4 +9266,4 @@ export {
9385
9266
  StaticPathProvider,
9386
9267
  createDatabaseManagerAdapter
9387
9268
  };
9388
- //# sourceMappingURL=chunk-IK7GJTGY.mjs.map
9269
+ //# sourceMappingURL=chunk-YVNZ73O5.mjs.map