@lih-x-x/kmr 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +96 -63
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -398,6 +398,36 @@ var RANK_RESULTS_PROMPT = `\u4F60\u662F\u4E00\u4E2A\u641C\u7D22\u6392\u5E8F\u52A
398
398
 
399
399
  \u7528\u6237\u67E5\u8BE2\uFF1A`;
400
400
 
401
+ // src/utils/claudeEnv.ts
402
+ import fs from "fs";
403
+ import path from "path";
404
+ import os from "os";
405
+ var cachedEnv = null;
406
+ function getClaudeEnv() {
407
+ if (cachedEnv) return cachedEnv;
408
+ const settingsPath = path.join(os.homedir(), ".claude", "settings.json");
409
+ let settingsEnv = {};
410
+ try {
411
+ const content = fs.readFileSync(settingsPath, "utf-8");
412
+ const settings = JSON.parse(content);
413
+ if (settings.env && typeof settings.env === "object") {
414
+ settingsEnv = settings.env;
415
+ }
416
+ } catch {
417
+ }
418
+ cachedEnv = { ...settingsEnv };
419
+ for (const key of Object.keys(settingsEnv)) {
420
+ if (process.env[key]) {
421
+ cachedEnv[key] = process.env[key];
422
+ }
423
+ }
424
+ return cachedEnv;
425
+ }
426
+ function getExecEnv() {
427
+ const claudeEnv = getClaudeEnv();
428
+ return { ...process.env, ...claudeEnv };
429
+ }
430
+
401
431
  // src/agent/claudeCode.ts
402
432
  var execFileAsync = promisify(execFile);
403
433
  var ClaudeCodeProvider = class {
@@ -448,7 +478,8 @@ ${prompt}
448
478
  try {
449
479
  const { stdout } = await execFileAsync("acpx", ["--allowed-tools", "", "claude", "exec", prompt], {
450
480
  timeout: this.timeout,
451
- maxBuffer: 1024 * 1024
481
+ maxBuffer: 1024 * 1024,
482
+ env: getExecEnv()
452
483
  });
453
484
  return this.extractJson(stdout);
454
485
  } catch (err) {
@@ -489,31 +520,31 @@ ${prompt}
489
520
  };
490
521
 
491
522
  // src/storage/jsonStore.ts
492
- import fs from "fs";
493
- import path from "path";
523
+ import fs2 from "fs";
524
+ import path2 from "path";
494
525
  var JsonStore = class {
495
526
  constructor(dataDir) {
496
527
  this.dataDir = dataDir;
497
- fs.mkdirSync(dataDir, { recursive: true });
528
+ fs2.mkdirSync(dataDir, { recursive: true });
498
529
  }
499
530
  dataDir;
500
531
  async save(record) {
501
532
  const date = record.summary.date || (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
502
533
  const fileName = `${date}_${record.id}.json`;
503
- const filePath = path.join(this.dataDir, fileName);
504
- fs.writeFileSync(filePath, JSON.stringify(record, null, 2), "utf-8");
534
+ const filePath = path2.join(this.dataDir, fileName);
535
+ fs2.writeFileSync(filePath, JSON.stringify(record, null, 2), "utf-8");
505
536
  return filePath;
506
537
  }
507
538
  async load(id) {
508
539
  const files = this.getFiles();
509
540
  const target = files.find((f) => f.includes(id));
510
541
  if (!target) return null;
511
- const raw = fs.readFileSync(target, "utf-8");
542
+ const raw = fs2.readFileSync(target, "utf-8");
512
543
  return JSON.parse(raw);
513
544
  }
514
545
  async list() {
515
546
  const files = this.getFiles();
516
- return files.map((f) => JSON.parse(fs.readFileSync(f, "utf-8")));
547
+ return files.map((f) => JSON.parse(fs2.readFileSync(f, "utf-8")));
517
548
  }
518
549
  async search(keywords) {
519
550
  const all = await this.list();
@@ -526,25 +557,25 @@ var JsonStore = class {
526
557
  const files = this.getFiles();
527
558
  const target = files.find((f) => f.includes(id));
528
559
  if (!target) return false;
529
- fs.unlinkSync(target);
560
+ fs2.unlinkSync(target);
530
561
  return true;
531
562
  }
532
563
  getFiles() {
533
- if (!fs.existsSync(this.dataDir)) return [];
534
- return fs.readdirSync(this.dataDir).filter((f) => f.endsWith(".json")).map((f) => path.join(this.dataDir, f));
564
+ if (!fs2.existsSync(this.dataDir)) return [];
565
+ return fs2.readdirSync(this.dataDir).filter((f) => f.endsWith(".json")).map((f) => path2.join(this.dataDir, f));
535
566
  }
536
567
  };
537
568
 
538
569
  // src/query/finder.ts
539
- import fs2 from "fs";
540
- import path2 from "path";
570
+ import fs3 from "fs";
571
+ import path3 from "path";
541
572
  async function grepMeetings(dataDir, keywords) {
542
- if (!fs2.existsSync(dataDir)) return [];
543
- const files = fs2.readdirSync(dataDir).filter((f) => f.endsWith(".json"));
573
+ if (!fs3.existsSync(dataDir)) return [];
574
+ const files = fs3.readdirSync(dataDir).filter((f) => f.endsWith(".json"));
544
575
  const matches = [];
545
576
  for (const file of files) {
546
- const filePath = path2.join(dataDir, file);
547
- const raw = fs2.readFileSync(filePath, "utf-8");
577
+ const filePath = path3.join(dataDir, file);
578
+ const raw = fs3.readFileSync(filePath, "utf-8");
548
579
  const hasMatch = keywords.some((kw) => raw.includes(kw));
549
580
  if (hasMatch) {
550
581
  matches.push(JSON.parse(raw));
@@ -572,11 +603,11 @@ var QueryHandler = class {
572
603
 
573
604
  // src/web/server.ts
574
605
  import http from "http";
575
- import fs3 from "fs";
576
- import path3 from "path";
606
+ import fs4 from "fs";
607
+ import path4 from "path";
577
608
  import { fileURLToPath } from "url";
578
- var __dirname = path3.dirname(fileURLToPath(import.meta.url));
579
- var PUBLIC_DIR = path3.join(__dirname, "public");
609
+ var __dirname = path4.dirname(fileURLToPath(import.meta.url));
610
+ var PUBLIC_DIR = path4.join(__dirname, "public");
580
611
  var MIME_TYPES = {
581
612
  ".html": "text/html; charset=utf-8",
582
613
  ".css": "text/css; charset=utf-8",
@@ -586,30 +617,30 @@ var MIME_TYPES = {
586
617
  ".svg": "image/svg+xml"
587
618
  };
588
619
  function serveStatic(res, urlPath) {
589
- const safePath = path3.normalize(urlPath).replace(/^(\.\.[/\\])+/, "");
590
- let filePath = path3.join(PUBLIC_DIR, safePath === "/" ? "index.html" : safePath);
591
- if (!fs3.existsSync(filePath) || fs3.statSync(filePath).isDirectory()) {
592
- filePath = path3.join(PUBLIC_DIR, "index.html");
620
+ const safePath = path4.normalize(urlPath).replace(/^(\.\.[/\\])+/, "");
621
+ let filePath = path4.join(PUBLIC_DIR, safePath === "/" ? "index.html" : safePath);
622
+ if (!fs4.existsSync(filePath) || fs4.statSync(filePath).isDirectory()) {
623
+ filePath = path4.join(PUBLIC_DIR, "index.html");
593
624
  }
594
- const ext = path3.extname(filePath);
625
+ const ext = path4.extname(filePath);
595
626
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
596
- const content = fs3.readFileSync(filePath);
627
+ const content = fs4.readFileSync(filePath);
597
628
  res.writeHead(200, { "Content-Type": contentType });
598
629
  res.end(content);
599
630
  }
600
631
  function listSessions(kmrDir) {
601
- const sessionsDir = path3.join(kmrDir, "sessions");
602
- if (!fs3.existsSync(sessionsDir)) return [];
603
- return fs3.readdirSync(sessionsDir).filter((d) => {
604
- const full = path3.join(sessionsDir, d);
605
- return fs3.statSync(full).isDirectory();
632
+ const sessionsDir = path4.join(kmrDir, "sessions");
633
+ if (!fs4.existsSync(sessionsDir)) return [];
634
+ return fs4.readdirSync(sessionsDir).filter((d) => {
635
+ const full = path4.join(sessionsDir, d);
636
+ return fs4.statSync(full).isDirectory();
606
637
  }).map((userId) => {
607
- const summaryPath = path3.join(sessionsDir, userId, "summary.md");
638
+ const summaryPath = path4.join(sessionsDir, userId, "summary.md");
608
639
  let summaryPreview = "";
609
640
  let messageCount = 0;
610
641
  let lastActivity = "";
611
- if (fs3.existsSync(summaryPath)) {
612
- const content = fs3.readFileSync(summaryPath, "utf-8");
642
+ if (fs4.existsSync(summaryPath)) {
643
+ const content = fs4.readFileSync(summaryPath, "utf-8");
613
644
  const lines = content.split("\n").filter((l) => l.trim().length > 0);
614
645
  messageCount = lines.length;
615
646
  for (let i = lines.length - 1; i >= 0; i--) {
@@ -621,26 +652,26 @@ function listSessions(kmrDir) {
621
652
  const lastLine = lines[lines.length - 1] || "";
622
653
  const timeMatch = lastLine.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]/);
623
654
  if (timeMatch) lastActivity = timeMatch[1];
624
- const stat = fs3.statSync(summaryPath);
655
+ const stat = fs4.statSync(summaryPath);
625
656
  if (!lastActivity) lastActivity = stat.mtime.toISOString().replace("T", " ").slice(0, 19);
626
657
  } else {
627
- const userDir = path3.join(sessionsDir, userId);
628
- const stat = fs3.statSync(userDir);
658
+ const userDir = path4.join(sessionsDir, userId);
659
+ const stat = fs4.statSync(userDir);
629
660
  lastActivity = stat.mtime.toISOString().replace("T", " ").slice(0, 19);
630
661
  }
631
662
  return { userId, summaryPreview, messageCount, lastActivity };
632
663
  }).sort((a, b) => b.lastActivity.localeCompare(a.lastActivity));
633
664
  }
634
665
  function deleteSession(kmrDir, userId) {
635
- const sessionDir = path3.join(kmrDir, "sessions", userId);
636
- if (!fs3.existsSync(sessionDir)) return false;
637
- fs3.rmSync(sessionDir, { recursive: true, force: true });
666
+ const sessionDir = path4.join(kmrDir, "sessions", userId);
667
+ if (!fs4.existsSync(sessionDir)) return false;
668
+ fs4.rmSync(sessionDir, { recursive: true, force: true });
638
669
  return true;
639
670
  }
640
671
  function getSessionDetail(kmrDir, userId) {
641
- const summaryPath = path3.join(kmrDir, "sessions", userId, "summary.md");
642
- if (!fs3.existsSync(summaryPath)) return null;
643
- return fs3.readFileSync(summaryPath, "utf-8");
672
+ const summaryPath = path4.join(kmrDir, "sessions", userId, "summary.md");
673
+ if (!fs4.existsSync(summaryPath)) return null;
674
+ return fs4.readFileSync(summaryPath, "utf-8");
644
675
  }
645
676
  function startWebServer(store, kmrDir, port = 3e3) {
646
677
  return new Promise((resolve, reject) => {
@@ -710,8 +741,8 @@ async function handleApi(req, res, url, store, kmrDir) {
710
741
  return;
711
742
  }
712
743
  if (pathname === "/api/config" && method === "GET") {
713
- const configPath = path3.join(kmrDir, "config.json");
714
- const config = JSON.parse(fs3.readFileSync(configPath, "utf-8"));
744
+ const configPath = path4.join(kmrDir, "config.json");
745
+ const config = JSON.parse(fs4.readFileSync(configPath, "utf-8"));
715
746
  jsonResponse(res, 200, { ok: true, data: config });
716
747
  return;
717
748
  }
@@ -724,8 +755,8 @@ async function handleApi(req, res, url, store, kmrDir) {
724
755
  jsonResponse(res, 400, { ok: false, error: "\u65E0\u6548\u7684 JSON \u683C\u5F0F" });
725
756
  return;
726
757
  }
727
- const configPath = path3.join(kmrDir, "config.json");
728
- fs3.writeFileSync(configPath, JSON.stringify(parsed, null, 2), "utf-8");
758
+ const configPath = path4.join(kmrDir, "config.json");
759
+ fs4.writeFileSync(configPath, JSON.stringify(parsed, null, 2), "utf-8");
729
760
  jsonResponse(res, 200, { ok: true, data: parsed });
730
761
  return;
731
762
  }
@@ -779,8 +810,8 @@ function openBrowser(url) {
779
810
  // src/session/manager.ts
780
811
  import { execFile as execFile3 } from "child_process";
781
812
  import { promisify as promisify2 } from "util";
782
- import fs4 from "fs";
783
- import path4 from "path";
813
+ import fs5 from "fs";
814
+ import path5 from "path";
784
815
 
785
816
  // src/session/skill.ts
786
817
  var SESSION_SKILL = `\u4F60\u662F KMR\uFF08Key Meetings Record\uFF09\u7684\u667A\u80FD\u52A9\u624B\u3002
@@ -808,8 +839,8 @@ var execFileAsync2 = promisify2(execFile3);
808
839
  var SessionManager = class {
809
840
  constructor(kmrDir, timeout = 6e4) {
810
841
  this.timeout = timeout;
811
- this.sessionDir = path4.join(kmrDir, "sessions");
812
- fs4.mkdirSync(this.sessionDir, { recursive: true });
842
+ this.sessionDir = path5.join(kmrDir, "sessions");
843
+ fs5.mkdirSync(this.sessionDir, { recursive: true });
813
844
  }
814
845
  timeout;
815
846
  activeSessions = /* @__PURE__ */ new Map();
@@ -828,15 +859,16 @@ var SessionManager = class {
828
859
  return existing.name;
829
860
  }
830
861
  const sessionName = `kmr-${userId}`;
831
- const userDir = path4.join(this.sessionDir, userId);
832
- fs4.mkdirSync(userDir, { recursive: true });
833
- const skillPath = path4.join(userDir, "skill.md");
834
- fs4.writeFileSync(skillPath, SESSION_SKILL, "utf-8");
862
+ const userDir = path5.join(this.sessionDir, userId);
863
+ fs5.mkdirSync(userDir, { recursive: true });
864
+ const skillPath = path5.join(userDir, "skill.md");
865
+ fs5.writeFileSync(skillPath, SESSION_SKILL, "utf-8");
835
866
  console.log(`[session] \u521B\u5EFA\u65B0 session: ${sessionName}`);
836
867
  try {
837
868
  await execFileAsync2("acpx", ["claude", "sessions", "ensure", "--name", sessionName], {
838
869
  timeout: this.timeout,
839
- maxBuffer: 1024 * 1024
870
+ maxBuffer: 1024 * 1024,
871
+ env: getExecEnv()
840
872
  });
841
873
  } catch (err) {
842
874
  console.error(`[session] \u521B\u5EFA session \u5931\u8D25:`, err.message);
@@ -847,7 +879,7 @@ var SessionManager = class {
847
879
  await execFileAsync2(
848
880
  "acpx",
849
881
  ["--approve-all", "claude", "-s", sessionName, SESSION_SKILL],
850
- { timeout: this.timeout, maxBuffer: 1024 * 1024 }
882
+ { timeout: this.timeout, maxBuffer: 1024 * 1024, env: getExecEnv() }
851
883
  );
852
884
  } catch (err) {
853
885
  console.error(`[session] \u89D2\u8272\u8BBE\u5B9A\u5931\u8D25:`, err.message);
@@ -863,7 +895,7 @@ var SessionManager = class {
863
895
  const { stdout } = await execFileAsync2(
864
896
  "acpx",
865
897
  ["--approve-all", "claude", "-s", sessionName, text],
866
- { timeout: this.timeout, maxBuffer: 1024 * 1024 }
898
+ { timeout: this.timeout, maxBuffer: 1024 * 1024, env: getExecEnv() }
867
899
  );
868
900
  return this.extractReply(stdout);
869
901
  } catch (err) {
@@ -882,21 +914,22 @@ var SessionManager = class {
882
914
  return filtered || output.trim();
883
915
  }
884
916
  async appendSummary(userId, userText, aiReply) {
885
- const userDir = path4.join(this.sessionDir, userId);
886
- const summaryPath = path4.join(userDir, "summary.md");
917
+ const userDir = path5.join(this.sessionDir, userId);
918
+ const summaryPath = path5.join(userDir, "summary.md");
887
919
  const now = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
888
920
  const entry = `
889
921
  [${now}] \u7528\u6237: ${userText}
890
922
  [${now}] AI: ${aiReply}
891
923
  `;
892
- fs4.appendFileSync(summaryPath, entry, "utf-8");
924
+ fs5.appendFileSync(summaryPath, entry, "utf-8");
893
925
  }
894
926
  async closeSession(userId) {
895
927
  const info = this.activeSessions.get(userId);
896
928
  if (!info) return;
897
929
  try {
898
930
  await execFileAsync2("acpx", ["claude", "sessions", "close", info.name], {
899
- timeout: 1e4
931
+ timeout: 1e4,
932
+ env: getExecEnv()
900
933
  });
901
934
  console.log(`[session] \u5DF2\u5173\u95ED session: ${info.name}`);
902
935
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lih-x-x/kmr",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {