jinzd-ai-cli 0.4.304 → 0.4.305

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 (64) hide show
  1. package/dist/{batch-RY2F7BX5.js → batch-OX27K4GG.js} +2 -2
  2. package/dist/{chunk-7L7T46PI.js → chunk-3ZABGT3S.js} +1 -1
  3. package/dist/{chunk-RWM2GFRC.js → chunk-45UVJXFQ.js} +6 -2
  4. package/dist/{chunk-6AGTDWO3.js → chunk-4DH5LZR5.js} +1 -1
  5. package/dist/{chunk-23SJVOQD.js → chunk-72AR23R2.js} +26 -5
  6. package/dist/{chunk-OECPGCHP.js → chunk-AXKERUXH.js} +3 -3
  7. package/dist/{chunk-VOIOUJXI.js → chunk-C2Z77RTU.js} +13 -5
  8. package/dist/{chunk-F3EJ4MIP.js → chunk-GOIDKTBE.js} +12 -11
  9. package/dist/{chunk-BSBGPDCX.js → chunk-I6RATYRF.js} +1 -1
  10. package/dist/{chunk-2PLYXL4P.js → chunk-IPUTC5EX.js} +12 -10
  11. package/dist/{chunk-7XU4BATV.js → chunk-KBDKKHXB.js} +15 -6
  12. package/dist/{chunk-4DEMGCK4.js → chunk-LF67HWWR.js} +37 -13
  13. package/dist/{chunk-RHCRE6XE.js → chunk-NBYSFFCO.js} +1 -1
  14. package/dist/{chunk-XIMM47EG.js → chunk-NFLE34QG.js} +1 -1
  15. package/dist/{chunk-BXP6YZ2P.js → chunk-NRSYBKWA.js} +5 -4
  16. package/dist/{chunk-IEQAE3QG.js → chunk-OAXLMF3U.js} +5 -4
  17. package/dist/{chunk-2GRGLTAK.js → chunk-PA4C452B.js} +1 -1
  18. package/dist/{chunk-I2WJ44D3.js → chunk-Q4DAKI7I.js} +1 -1
  19. package/dist/{chunk-TBTVV3KK.js → chunk-SZ4226XY.js} +1 -1
  20. package/dist/{chunk-3FI4TE5S.js → chunk-UFK5CTBU.js} +3 -3
  21. package/dist/{chunk-PPIISCFN.js → chunk-UFW4S3RU.js} +37 -13
  22. package/dist/{chunk-CKH4KQ4E.js → chunk-WQ3OMEC4.js} +6 -2
  23. package/dist/{chunk-UUSRWSSX.js → chunk-XJOK5353.js} +15 -6
  24. package/dist/{chunk-DNGUSTL6.js → chunk-YPOWDFOV.js} +1 -1
  25. package/dist/{ci-QYTLBM6Z.js → ci-IIMLOXFH.js} +4 -4
  26. package/dist/{ci-format-E5X27NC2.js → ci-format-FMBJC3EY.js} +2 -2
  27. package/dist/{constants-JDPKWZJP.js → constants-55QQ3RYE.js} +1 -1
  28. package/dist/{constants-F5WA5VPO.js → constants-7NVAPQVR.js} +1 -1
  29. package/dist/{doctor-cli-7NSEVW63.js → doctor-cli-ZHZ2XOF3.js} +4 -4
  30. package/dist/electron-server.js +232 -106
  31. package/dist/{hub-43PWTGGO.js → hub-MF53NIM2.js} +4 -4
  32. package/dist/{hub-server-RF6LURXY.js → hub-server-CBKCP5VD.js} +1 -1
  33. package/dist/index.js +24 -23
  34. package/dist/{indexer-RBEKMFT4.js → indexer-FPKY7LCT.js} +2 -2
  35. package/dist/{indexer-TNDWGFRI.js → indexer-P3FPRTPJ.js} +2 -2
  36. package/dist/{persistent-memory-A7RPDLR7.js → persistent-memory-LCOKUDTM.js} +2 -2
  37. package/dist/{persistent-memory-SHG3CJCP.js → persistent-memory-NACQW2VB.js} +2 -2
  38. package/dist/{pr-LW755EL7.js → pr-NHWE5FW7.js} +4 -4
  39. package/dist/{run-tests-MJ3SCW27.js → run-tests-EUPJLDXS.js} +2 -2
  40. package/dist/{run-tests-HV37CM5U.js → run-tests-ZG5X25BJ.js} +2 -2
  41. package/dist/{semantic-HLAE2O4F.js → semantic-7GM5M4MU.js} +3 -3
  42. package/dist/{semantic-VPNKXKKK.js → semantic-QOBAXEQ4.js} +3 -3
  43. package/dist/{server-EZ5ULLDP.js → server-PG7QCH53.js} +193 -82
  44. package/dist/{server-WI3Q4EDH.js → server-PNYRE3AL.js} +9 -9
  45. package/dist/{store-MWNHVGJT.js → store-CMSSWZF7.js} +3 -1
  46. package/dist/{store-VO37H6LS.js → store-SIKHCUYJ.js} +3 -1
  47. package/dist/{task-orchestrator-PWW5I2KE.js → task-orchestrator-WAJTCE6D.js} +9 -9
  48. package/dist/{usage-MAIV6XUZ.js → usage-DOES3DOS.js} +2 -2
  49. package/dist/{vector-store-JBAE6PS4.js → vector-store-JAXWDZYW.js} +1 -1
  50. package/dist/{vector-store-BBDXB5IQ.js → vector-store-PWIOQFTP.js} +1 -1
  51. package/dist/web/client/app.js +135 -60
  52. package/dist/web/client/app.js.br +0 -0
  53. package/dist/web/client/app.js.gz +0 -0
  54. package/dist/web/client/chat-input.js +38 -0
  55. package/dist/web/client/chat-input.js.br +0 -0
  56. package/dist/web/client/chat-input.js.gz +0 -0
  57. package/dist/web/client/index.html +1 -1
  58. package/dist/web/client/index.html.br +0 -0
  59. package/dist/web/client/index.html.gz +0 -0
  60. package/dist/web/client/stream-render.js +33 -0
  61. package/dist/web/client/style.css +2 -1
  62. package/dist/web/client/style.css.br +0 -0
  63. package/dist/web/client/style.css.gz +0 -0
  64. package/package.json +1 -1
@@ -11,8 +11,8 @@ import path from "path";
11
11
  import os from "os";
12
12
  import crypto from "crypto";
13
13
  var MAGIC = 1094927190;
14
- var VERSION = 1;
15
- var HEADER_BYTES = 16;
14
+ var VERSION = 2;
15
+ var HEADER_BYTES = 48;
16
16
  function indexDir() {
17
17
  return path.join(os.homedir(), ".aicli", "index");
18
18
  }
@@ -31,7 +31,7 @@ function emptyVectorStore(root) {
31
31
  symbolIdx: new Uint32Array(0)
32
32
  };
33
33
  }
34
- function saveVectorStore(root, indices, vectors) {
34
+ function saveVectorStore(root, indices, vectors, sourceFingerprint) {
35
35
  if (indices.length * EMBEDDING_DIM !== vectors.length) {
36
36
  throw new Error(
37
37
  `saveVectorStore: length mismatch \u2014 ${indices.length} indices vs ${vectors.length / EMBEDDING_DIM} vectors`
@@ -46,6 +46,7 @@ function saveVectorStore(root, indices, vectors) {
46
46
  buf.writeUInt32LE(VERSION, 4);
47
47
  buf.writeUInt32LE(count, 8);
48
48
  buf.writeUInt32LE(EMBEDDING_DIM, 12);
49
+ if (sourceFingerprint) Buffer.from(sourceFingerprint, "hex").copy(buf, 16, 0, 32);
49
50
  Buffer.from(indices.buffer, indices.byteOffset, indices.byteLength).copy(buf, HEADER_BYTES);
50
51
  Buffer.from(vectors.buffer, vectors.byteOffset, vectors.byteLength).copy(buf, HEADER_BYTES + count * 4);
51
52
  const target = vecPath(root);
@@ -77,7 +78,7 @@ function loadVectorStore(root) {
77
78
  buf.byteOffset + HEADER_BYTES + count * 4 + count * dim * 4
78
79
  )
79
80
  );
80
- return { root: path.resolve(root), count, dim, vectors, symbolIdx };
81
+ return { root: path.resolve(root), count, dim, vectors, symbolIdx, sourceFingerprint: buf.subarray(16, 48).toString("hex") };
81
82
  }
82
83
  function clearVectorStore(root) {
83
84
  const p = vecPath(root);
@@ -1,5 +1,5 @@
1
1
  // src/core/constants.ts
2
- var VERSION = "0.4.304";
2
+ var VERSION = "0.4.305";
3
3
  var APP_NAME = "ai-cli";
4
4
  var CONFIG_DIR_NAME = ".aicli";
5
5
  var CONFIG_FILE_NAME = "config.json";
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  CONFIG_DIR_NAME,
10
10
  PLUGINS_DIR_NAME
11
- } from "./chunk-RHCRE6XE.js";
11
+ } from "./chunk-NBYSFFCO.js";
12
12
 
13
13
  // src/diagnostics/tool-stats.ts
14
14
  import { mkdirSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TEST_TIMEOUT
3
- } from "./chunk-2GRGLTAK.js";
3
+ } from "./chunk-PA4C452B.js";
4
4
 
5
5
  // src/tools/builtin/run-tests.ts
6
6
  import { execSync, spawnSync } from "child_process";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  evaluateCiGate,
4
4
  normalizeCiThresholds
5
- } from "./chunk-6AGTDWO3.js";
5
+ } from "./chunk-4DH5LZR5.js";
6
6
  import {
7
7
  buildReviewPrompt,
8
8
  buildSecurityReviewPrompt,
@@ -16,10 +16,10 @@ import {
16
16
  } from "./chunk-VXEF2SWG.js";
17
17
  import {
18
18
  ConfigManager
19
- } from "./chunk-XIMM47EG.js";
19
+ } from "./chunk-NFLE34QG.js";
20
20
  import {
21
21
  VERSION
22
- } from "./chunk-RHCRE6XE.js";
22
+ } from "./chunk-NBYSFFCO.js";
23
23
 
24
24
  // src/cli/ci.ts
25
25
  import { execFileSync } from "child_process";
@@ -5,7 +5,7 @@ import {
5
5
  removeFile,
6
6
  saveIndex,
7
7
  upsertFileSymbols
8
- } from "./chunk-RWM2GFRC.js";
8
+ } from "./chunk-45UVJXFQ.js";
9
9
 
10
10
  // src/symbols/indexer.ts
11
11
  import fs2 from "fs";
@@ -581,15 +581,18 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
581
581
  "cmake-build-release"
582
582
  ]);
583
583
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
584
- function collectFiles(root, maxFiles) {
584
+ async function collectFiles(root, maxFiles, signal) {
585
585
  const out = [];
586
+ let incomplete = false;
586
587
  const stack = [root];
587
588
  while (stack.length > 0 && out.length < maxFiles) {
589
+ signal?.throwIfAborted();
588
590
  const dir = stack.pop();
589
591
  let entries;
590
592
  try {
591
- entries = fs2.readdirSync(dir, { withFileTypes: true });
593
+ entries = await fs2.promises.readdir(dir, { withFileTypes: true });
592
594
  } catch {
595
+ incomplete = true;
593
596
  continue;
594
597
  }
595
598
  for (const e of entries) {
@@ -604,33 +607,47 @@ function collectFiles(root, maxFiles) {
604
607
  const ext = path3.extname(e.name).slice(1);
605
608
  if (detectLanguage(ext)) {
606
609
  out.push(full);
607
- if (out.length >= maxFiles) break;
610
+ if (out.length >= maxFiles) {
611
+ incomplete = true;
612
+ break;
613
+ }
608
614
  }
609
615
  }
610
616
  }
611
617
  }
612
- return out;
618
+ return { files: out, incomplete };
613
619
  }
614
620
  async function indexProject(root, opts = {}) {
615
621
  const start = Date.now();
616
622
  const maxFiles = opts.maxFiles ?? 5e3;
623
+ if (!Number.isSafeInteger(maxFiles) || maxFiles < 1) throw new Error("maxFiles must be a positive integer");
617
624
  const force = opts.force === true;
618
625
  const absRoot = path3.resolve(root);
619
- let index = force ? emptyIndex(absRoot) : loadIndex(absRoot) ?? emptyIndex(absRoot);
620
- const files = collectFiles(absRoot, maxFiles);
626
+ const index = loadIndex(absRoot) ?? emptyIndex(absRoot);
627
+ const { files, incomplete } = await collectFiles(absRoot, maxFiles, opts.signal);
621
628
  const liveSet = new Set(files.map((f) => path3.resolve(f)));
629
+ const byFile = /* @__PURE__ */ new Map();
630
+ for (const symbol of index.symbols) {
631
+ const file = symbol.location.file;
632
+ const entries = byFile.get(file) ?? [];
633
+ entries.push(symbol);
634
+ byFile.set(file, entries);
635
+ }
622
636
  for (const known of Object.keys(index.files)) {
623
- if (!liveSet.has(known)) {
624
- index = removeFile(index, known);
637
+ if (!incomplete && !liveSet.has(known)) {
638
+ byFile.delete(known);
639
+ delete index.files[known];
625
640
  }
626
641
  }
627
642
  let parsed = 0;
628
643
  let skipped = 0;
629
644
  for (let i = 0; i < files.length; i++) {
645
+ opts.signal?.throwIfAborted();
646
+ if (i % 50 === 0) await new Promise((resolve) => setImmediate(resolve));
630
647
  const file = path3.resolve(files[i]);
631
648
  let stat;
632
649
  try {
633
- stat = fs2.statSync(file);
650
+ stat = await fs2.promises.stat(file);
634
651
  } catch {
635
652
  skipped++;
636
653
  continue;
@@ -645,18 +662,24 @@ async function indexProject(root, opts = {}) {
645
662
  }
646
663
  let src;
647
664
  try {
648
- src = fs2.readFileSync(file, "utf-8");
665
+ src = await fs2.promises.readFile(file, "utf-8");
649
666
  } catch {
650
667
  skipped++;
651
668
  continue;
652
669
  }
653
670
  const symbols = await parseSource(file, src);
654
- index = upsertFileSymbols(index, file, stat.mtimeMs, symbols);
671
+ byFile.set(file, symbols);
672
+ index.files[file] = stat.mtimeMs;
655
673
  parsed++;
656
674
  if (opts.onProgress && parsed % 50 === 0) {
657
675
  opts.onProgress(i + 1, files.length);
658
676
  }
659
677
  }
678
+ opts.signal?.throwIfAborted();
679
+ index.symbols = [...byFile.values()].flat();
680
+ index.fileCount = Object.keys(index.files).length;
681
+ index.symbolCount = index.symbols.length;
682
+ index.generated = (/* @__PURE__ */ new Date()).toISOString();
660
683
  saveIndex(index);
661
684
  return {
662
685
  index,
@@ -665,7 +688,8 @@ async function indexProject(root, opts = {}) {
665
688
  filesParsed: parsed,
666
689
  filesSkipped: skipped,
667
690
  symbols: index.symbolCount,
668
- durationMs: Date.now() - start
691
+ durationMs: Date.now() - start,
692
+ incomplete: incomplete || skipped > 0
669
693
  }
670
694
  };
671
695
  }
@@ -80,6 +80,9 @@ function saveIndex(index) {
80
80
  const target = indexPath(index.root);
81
81
  atomicWriteFileSync(target, JSON.stringify(index));
82
82
  }
83
+ function symbolFingerprint(index) {
84
+ return crypto.createHash("sha256").update(JSON.stringify(index.symbols)).digest("hex");
85
+ }
83
86
  function clearIndex(root) {
84
87
  const p = indexPath(root);
85
88
  try {
@@ -101,11 +104,11 @@ function emptyIndex(root) {
101
104
  function upsertFileSymbols(index, file, mtime, symbols) {
102
105
  const absFile = path.resolve(file);
103
106
  const had = absFile in index.files;
104
- index.symbols = index.symbols.filter((s) => s.location.file !== absFile);
107
+ if (had) index.symbols = index.symbols.filter((s) => s.location.file !== absFile);
105
108
  index.symbols.push(...symbols);
106
109
  index.files[absFile] = mtime;
107
110
  index.symbolCount = index.symbols.length;
108
- if (!had) index.fileCount = Object.keys(index.files).length;
111
+ if (!had) index.fileCount++;
109
112
  index.generated = (/* @__PURE__ */ new Date()).toISOString();
110
113
  return index;
111
114
  }
@@ -124,6 +127,7 @@ export {
124
127
  detectLanguage,
125
128
  loadIndex,
126
129
  saveIndex,
130
+ symbolFingerprint,
127
131
  clearIndex,
128
132
  emptyIndex,
129
133
  upsertFileSymbols,
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- loadIndex
4
- } from "./chunk-CKH4KQ4E.js";
3
+ loadIndex,
4
+ symbolFingerprint
5
+ } from "./chunk-WQ3OMEC4.js";
5
6
  import {
6
7
  loadVectorStore,
7
8
  saveVectorStore,
8
9
  searchVectorStore
9
- } from "./chunk-BXP6YZ2P.js";
10
+ } from "./chunk-NRSYBKWA.js";
10
11
  import {
11
12
  EMBEDDING_DIM,
12
13
  embed,
@@ -67,7 +68,7 @@ async function rebuildSemanticIndex(root, opts = {}) {
67
68
  const batchSize = opts.batchSize ?? 32;
68
69
  const total = Math.min(index.symbols.length, maxSymbols);
69
70
  if (total === 0) {
70
- saveVectorStore(root, new Uint32Array(0), new Float32Array(0));
71
+ saveVectorStore(root, new Uint32Array(0), new Float32Array(0), symbolFingerprint(index));
71
72
  return { symbolsEmbedded: 0, durationMs: Date.now() - start };
72
73
  }
73
74
  const symbolIdx = new Uint32Array(total);
@@ -88,7 +89,7 @@ async function rebuildSemanticIndex(root, opts = {}) {
88
89
  }
89
90
  if (opts.onProgress) opts.onProgress(end, total);
90
91
  }
91
- saveVectorStore(root, symbolIdx, vectors);
92
+ saveVectorStore(root, symbolIdx, vectors, symbolFingerprint(index));
92
93
  return {
93
94
  symbolsEmbedded: total,
94
95
  durationMs: Date.now() - start,
@@ -100,7 +101,14 @@ async function semanticSearch(root, query, k = 10) {
100
101
  if (!index) return [];
101
102
  const store = loadVectorStore(root);
102
103
  if (!store || store.count === 0) return [];
104
+ if (store.sourceFingerprint !== symbolFingerprint(index)) {
105
+ throw new Error("Semantic index is stale. Run /index semantic-rebuild before searching again.");
106
+ }
103
107
  const queryVec = await embedOne(query);
108
+ const current = loadIndex(root);
109
+ if (!current || symbolFingerprint(current) !== store.sourceFingerprint) {
110
+ throw new Error("Symbol index changed during search. Run /index semantic-rebuild and retry.");
111
+ }
104
112
  const hits = searchVectorStore(store, queryVec, k);
105
113
  return hits.map((h) => ({
106
114
  ...h,
@@ -109,7 +117,8 @@ async function semanticSearch(root, query, k = 10) {
109
117
  }
110
118
  function hasSemanticIndex(root) {
111
119
  const s = loadVectorStore(root);
112
- return s !== null && s.count > 0;
120
+ const index = loadIndex(root);
121
+ return s !== null && s.count > 0 && index !== null && s.sourceFingerprint === symbolFingerprint(index);
113
122
  }
114
123
 
115
124
  export {
@@ -12,7 +12,7 @@ import {
12
12
  MEMORY_FILE_NAME,
13
13
  MEMORY_MAX_CHARS,
14
14
  MEMORY_STORE_FILE_NAME
15
- } from "./chunk-2GRGLTAK.js";
15
+ } from "./chunk-PA4C452B.js";
16
16
 
17
17
  // src/memory/persistent-memory.ts
18
18
  import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
@@ -3,16 +3,16 @@ import {
3
3
  CI_COMMENT_MARKER,
4
4
  countSeverity,
5
5
  runCi
6
- } from "./chunk-3FI4TE5S.js";
7
- import "./chunk-6AGTDWO3.js";
6
+ } from "./chunk-UFK5CTBU.js";
7
+ import "./chunk-4DH5LZR5.js";
8
8
  import "./chunk-HLWUDRBO.js";
9
9
  import "./chunk-6YZEZFX5.js";
10
10
  import "./chunk-VXEF2SWG.js";
11
- import "./chunk-XIMM47EG.js";
11
+ import "./chunk-NFLE34QG.js";
12
12
  import "./chunk-MI4SFZGX.js";
13
13
  import "./chunk-TU3L3PW7.js";
14
14
  import "./chunk-IW3Q7AE5.js";
15
- import "./chunk-RHCRE6XE.js";
15
+ import "./chunk-NBYSFFCO.js";
16
16
  export {
17
17
  CI_COMMENT_MARKER,
18
18
  countSeverity,
@@ -6,8 +6,8 @@ import {
6
6
  formatCiResult,
7
7
  formatCiSarif,
8
8
  normalizeCiThresholds
9
- } from "./chunk-6AGTDWO3.js";
10
- import "./chunk-RHCRE6XE.js";
9
+ } from "./chunk-4DH5LZR5.js";
10
+ import "./chunk-NBYSFFCO.js";
11
11
  export {
12
12
  DEFAULT_CI_THRESHOLDS,
13
13
  detectCiGateSignals,
@@ -37,7 +37,7 @@ import {
37
37
  TEST_TIMEOUT,
38
38
  VERSION,
39
39
  buildUserIdentityPrompt
40
- } from "./chunk-2GRGLTAK.js";
40
+ } from "./chunk-PA4C452B.js";
41
41
  export {
42
42
  AGENTIC_BEHAVIOR_GUIDELINE,
43
43
  APP_NAME,
@@ -38,7 +38,7 @@ import {
38
38
  TEST_TIMEOUT,
39
39
  VERSION,
40
40
  buildUserIdentityPrompt
41
- } from "./chunk-RHCRE6XE.js";
41
+ } from "./chunk-NBYSFFCO.js";
42
42
  export {
43
43
  AGENTIC_BEHAVIOR_GUIDELINE,
44
44
  APP_NAME,
@@ -2,16 +2,16 @@
2
2
  import {
3
3
  formatDoctorReport,
4
4
  runDoctorCli
5
- } from "./chunk-OECPGCHP.js";
6
- import "./chunk-I2WJ44D3.js";
5
+ } from "./chunk-AXKERUXH.js";
6
+ import "./chunk-Q4DAKI7I.js";
7
7
  import "./chunk-RS7SKYTS.js";
8
8
  import "./chunk-VXEF2SWG.js";
9
- import "./chunk-XIMM47EG.js";
9
+ import "./chunk-NFLE34QG.js";
10
10
  import "./chunk-MI4SFZGX.js";
11
11
  import "./chunk-TU3L3PW7.js";
12
12
  import "./chunk-HOSJZMQS.js";
13
13
  import "./chunk-IW3Q7AE5.js";
14
- import "./chunk-RHCRE6XE.js";
14
+ import "./chunk-NBYSFFCO.js";
15
15
  export {
16
16
  formatDoctorReport,
17
17
  runDoctorCli