jinzd-ai-cli 0.4.76 → 0.4.78
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.
- package/README.md +3 -1
- package/dist/batch-CDCTUTIQ.js +218 -0
- package/dist/{chunk-KR4FTJWB.js → chunk-EUE6VMGO.js} +73 -7
- package/dist/{chunk-H4DQNZZ6.js → chunk-FCVQ6OP5.js} +1 -1
- package/dist/{chunk-XTH7S3AM.js → chunk-GKDETNDH.js} +2 -2
- package/dist/{chunk-2Q77FT3F.js → chunk-HELGL4RH.js} +6 -3
- package/dist/chunk-HPDDAXFY.js +84 -0
- package/dist/{chunk-K3JJX2Z5.js → chunk-KHYHG2SO.js} +1 -1
- package/dist/chunk-PFYAAX2S.js +169 -0
- package/dist/{chunk-34NJTPWZ.js → chunk-TNAPORYF.js} +6 -3
- package/dist/chunk-UTCC3UMT.js +83 -0
- package/dist/chunk-XMA222FQ.js +167 -0
- package/dist/electron-server.js +12465 -0
- package/dist/file-checkpoint-CGH6OJVI.js +6 -0
- package/dist/file-checkpoint-NKBHGC7L.js +7 -0
- package/dist/{hub-YPNEYO3Z.js → hub-BIFM6NOM.js} +1 -1
- package/dist/index.js +64 -19
- package/dist/indexer-C7QYYHSZ.js +10 -0
- package/dist/indexer-O5FCGFBJ.js +9 -0
- package/dist/{run-tests-MKKCDUUV.js → run-tests-JBM4K5FO.js} +2 -2
- package/dist/{run-tests-2I5S24IH.js → run-tests-MONKXJBT.js} +1 -1
- package/dist/semantic-MD7HYPWZ.js +14 -0
- package/dist/semantic-RBWU76MD.js +15 -0
- package/dist/{server-6MPBAH4K.js → server-GCE5V4SL.js} +51 -16
- package/dist/store-247B3TAU.js +16 -0
- package/dist/store-S24SPPDZ.js +17 -0
- package/dist/{task-orchestrator-I5HPXTJY.js → task-orchestrator-YAWEIZE7.js} +6 -4
- package/dist/vector-store-UR7IARXB.js +14 -0
- package/dist/vector-store-YTVHACBV.js +15 -0
- package/package.json +3 -10
|
@@ -6,7 +6,7 @@ import { platform } from "os";
|
|
|
6
6
|
import chalk from "chalk";
|
|
7
7
|
|
|
8
8
|
// src/core/constants.ts
|
|
9
|
-
var VERSION = "0.4.
|
|
9
|
+
var VERSION = "0.4.78";
|
|
10
10
|
var APP_NAME = "ai-cli";
|
|
11
11
|
var CONFIG_DIR_NAME = ".aicli";
|
|
12
12
|
var CONFIG_FILE_NAME = "config.json";
|
|
@@ -41,8 +41,10 @@ var PLAN_MODE_READONLY_TOOLS = /* @__PURE__ */ new Set([
|
|
|
41
41
|
// C1 symbol index (read-only)
|
|
42
42
|
"get_outline",
|
|
43
43
|
// C1 symbol index (read-only)
|
|
44
|
-
"find_references"
|
|
44
|
+
"find_references",
|
|
45
45
|
// C1 symbol index (read-only)
|
|
46
|
+
"search_code"
|
|
47
|
+
// C2 semantic search (read-only)
|
|
46
48
|
]);
|
|
47
49
|
var PLAN_MODE_SYSTEM_ADDON = `# \u{1F50D} Plan Mode \u2014 Read-Only Planning Mode
|
|
48
50
|
|
|
@@ -85,7 +87,8 @@ var SUBAGENT_ALLOWED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
85
87
|
"run_tests",
|
|
86
88
|
"find_symbol",
|
|
87
89
|
"get_outline",
|
|
88
|
-
"find_references"
|
|
90
|
+
"find_references",
|
|
91
|
+
"search_code"
|
|
89
92
|
]);
|
|
90
93
|
var TEST_TIMEOUT = 3e5;
|
|
91
94
|
var AGENTIC_BEHAVIOR_GUIDELINE = `# Important Behavioral Guidelines
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadIndex
|
|
3
|
+
} from "./chunk-BJAT4GNC.js";
|
|
4
|
+
import {
|
|
5
|
+
EMBEDDING_DIM,
|
|
6
|
+
embed,
|
|
7
|
+
embedOne,
|
|
8
|
+
loadVectorStore,
|
|
9
|
+
saveVectorStore,
|
|
10
|
+
searchVectorStore
|
|
11
|
+
} from "./chunk-XMA222FQ.js";
|
|
12
|
+
|
|
13
|
+
// src/symbols/semantic.ts
|
|
14
|
+
function buildEmbeddingText(s) {
|
|
15
|
+
const parts = [s.kind, s.name];
|
|
16
|
+
if (s.container) parts.push(`in ${s.container}`);
|
|
17
|
+
if (s.signature) parts.push(s.signature);
|
|
18
|
+
if (s.doc) parts.push(s.doc);
|
|
19
|
+
return parts.join(" ").slice(0, 512);
|
|
20
|
+
}
|
|
21
|
+
async function rebuildSemanticIndex(root, opts = {}) {
|
|
22
|
+
const start = Date.now();
|
|
23
|
+
const index = loadIndex(root);
|
|
24
|
+
if (!index) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`No symbol index for ${root}. Run /index rebuild first so find_symbol has data to embed.`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
const maxSymbols = opts.maxSymbols ?? 2e4;
|
|
30
|
+
const batchSize = opts.batchSize ?? 32;
|
|
31
|
+
const total = Math.min(index.symbols.length, maxSymbols);
|
|
32
|
+
if (total === 0) {
|
|
33
|
+
saveVectorStore(root, new Uint32Array(0), new Float32Array(0));
|
|
34
|
+
return { symbolsEmbedded: 0, durationMs: Date.now() - start };
|
|
35
|
+
}
|
|
36
|
+
const symbolIdx = new Uint32Array(total);
|
|
37
|
+
const vectors = new Float32Array(total * EMBEDDING_DIM);
|
|
38
|
+
let modelFirstLoadMs;
|
|
39
|
+
for (let i = 0; i < total; i += batchSize) {
|
|
40
|
+
const end = Math.min(i + batchSize, total);
|
|
41
|
+
const batch = [];
|
|
42
|
+
for (let j = i; j < end; j++) {
|
|
43
|
+
symbolIdx[j] = j;
|
|
44
|
+
batch.push(buildEmbeddingText(index.symbols[j]));
|
|
45
|
+
}
|
|
46
|
+
const batchStart = Date.now();
|
|
47
|
+
const rows = await embed(batch);
|
|
48
|
+
if (i === 0) modelFirstLoadMs = Date.now() - batchStart;
|
|
49
|
+
for (let r = 0; r < rows.length; r++) {
|
|
50
|
+
vectors.set(rows[r], (i + r) * EMBEDDING_DIM);
|
|
51
|
+
}
|
|
52
|
+
if (opts.onProgress) opts.onProgress(end, total);
|
|
53
|
+
}
|
|
54
|
+
saveVectorStore(root, symbolIdx, vectors);
|
|
55
|
+
return {
|
|
56
|
+
symbolsEmbedded: total,
|
|
57
|
+
durationMs: Date.now() - start,
|
|
58
|
+
modelFirstLoadMs
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async function semanticSearch(root, query, k = 10) {
|
|
62
|
+
const index = loadIndex(root);
|
|
63
|
+
if (!index) return [];
|
|
64
|
+
const store = loadVectorStore(root);
|
|
65
|
+
if (!store || store.count === 0) return [];
|
|
66
|
+
const queryVec = await embedOne(query);
|
|
67
|
+
const hits = searchVectorStore(store, queryVec, k);
|
|
68
|
+
return hits.map((h) => ({
|
|
69
|
+
...h,
|
|
70
|
+
symbol: index.symbols[h.symbolIdx]
|
|
71
|
+
})).filter((h) => h.symbol !== void 0);
|
|
72
|
+
}
|
|
73
|
+
function hasSemanticIndex(root) {
|
|
74
|
+
const s = loadVectorStore(root);
|
|
75
|
+
return s !== null && s.count > 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
buildEmbeddingText,
|
|
80
|
+
rebuildSemanticIndex,
|
|
81
|
+
semanticSearch,
|
|
82
|
+
hasSemanticIndex
|
|
83
|
+
};
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// src/symbols/vector-store.ts
|
|
2
|
+
import fs2 from "fs";
|
|
3
|
+
import path2 from "path";
|
|
4
|
+
import os2 from "os";
|
|
5
|
+
import crypto from "crypto";
|
|
6
|
+
|
|
7
|
+
// src/symbols/embedder.ts
|
|
8
|
+
import path from "path";
|
|
9
|
+
import os from "os";
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
var EMBEDDING_MODEL_ID = "Xenova/paraphrase-multilingual-MiniLM-L12-v2";
|
|
12
|
+
var EMBEDDING_DIM = 384;
|
|
13
|
+
var pipelinePromise = null;
|
|
14
|
+
function cacheDir() {
|
|
15
|
+
return path.join(os.homedir(), ".aicli", "models");
|
|
16
|
+
}
|
|
17
|
+
async function getEmbedder() {
|
|
18
|
+
if (pipelinePromise) return pipelinePromise;
|
|
19
|
+
pipelinePromise = (async () => {
|
|
20
|
+
const mod = await import("@huggingface/transformers");
|
|
21
|
+
const dir = cacheDir();
|
|
22
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
23
|
+
mod.env.cacheDir = dir;
|
|
24
|
+
mod.env.allowRemoteModels = true;
|
|
25
|
+
mod.env.allowLocalModels = true;
|
|
26
|
+
const pipe = await mod.pipeline("feature-extraction", EMBEDDING_MODEL_ID, {
|
|
27
|
+
// Keep the ONNX session in float32; int8 quantization exists but the
|
|
28
|
+
// quality drop on short code identifiers is noticeable.
|
|
29
|
+
dtype: "fp32"
|
|
30
|
+
});
|
|
31
|
+
return pipe;
|
|
32
|
+
})();
|
|
33
|
+
return pipelinePromise;
|
|
34
|
+
}
|
|
35
|
+
async function embed(texts) {
|
|
36
|
+
if (texts.length === 0) return [];
|
|
37
|
+
const pipe = await getEmbedder();
|
|
38
|
+
const out = await pipe(texts, { pooling: "mean", normalize: true });
|
|
39
|
+
const batch = texts.length;
|
|
40
|
+
const dim = EMBEDDING_DIM;
|
|
41
|
+
const rows = new Array(batch);
|
|
42
|
+
for (let i = 0; i < batch; i++) {
|
|
43
|
+
rows[i] = new Float32Array(out.data.buffer, out.data.byteOffset + i * dim * 4, dim).slice();
|
|
44
|
+
}
|
|
45
|
+
return rows;
|
|
46
|
+
}
|
|
47
|
+
async function embedOne(text) {
|
|
48
|
+
const [vec] = await embed([text]);
|
|
49
|
+
return vec;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/symbols/vector-store.ts
|
|
53
|
+
var MAGIC = 1094927190;
|
|
54
|
+
var VERSION = 1;
|
|
55
|
+
var HEADER_BYTES = 16;
|
|
56
|
+
function indexDir() {
|
|
57
|
+
return path2.join(os2.homedir(), ".aicli", "index");
|
|
58
|
+
}
|
|
59
|
+
function projectHash(root) {
|
|
60
|
+
return crypto.createHash("sha1").update(path2.resolve(root).toLowerCase()).digest("hex").slice(0, 16);
|
|
61
|
+
}
|
|
62
|
+
function vecPath(root) {
|
|
63
|
+
return path2.join(indexDir(), `${projectHash(root)}.vec`);
|
|
64
|
+
}
|
|
65
|
+
function emptyVectorStore(root) {
|
|
66
|
+
return {
|
|
67
|
+
root: path2.resolve(root),
|
|
68
|
+
count: 0,
|
|
69
|
+
dim: EMBEDDING_DIM,
|
|
70
|
+
vectors: new Float32Array(0),
|
|
71
|
+
symbolIdx: new Uint32Array(0)
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function saveVectorStore(root, indices, vectors) {
|
|
75
|
+
if (indices.length * EMBEDDING_DIM !== vectors.length) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
`saveVectorStore: length mismatch \u2014 ${indices.length} indices vs ${vectors.length / EMBEDDING_DIM} vectors`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
const count = indices.length;
|
|
81
|
+
const dir = indexDir();
|
|
82
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
83
|
+
const totalBytes = HEADER_BYTES + count * 4 + count * EMBEDDING_DIM * 4;
|
|
84
|
+
const buf = Buffer.alloc(totalBytes);
|
|
85
|
+
buf.writeUInt32LE(MAGIC, 0);
|
|
86
|
+
buf.writeUInt32LE(VERSION, 4);
|
|
87
|
+
buf.writeUInt32LE(count, 8);
|
|
88
|
+
buf.writeUInt32LE(EMBEDDING_DIM, 12);
|
|
89
|
+
Buffer.from(indices.buffer, indices.byteOffset, indices.byteLength).copy(buf, HEADER_BYTES);
|
|
90
|
+
Buffer.from(vectors.buffer, vectors.byteOffset, vectors.byteLength).copy(buf, HEADER_BYTES + count * 4);
|
|
91
|
+
const target = vecPath(root);
|
|
92
|
+
const tmp = `${target}.tmp`;
|
|
93
|
+
fs2.writeFileSync(tmp, buf);
|
|
94
|
+
fs2.renameSync(tmp, target);
|
|
95
|
+
}
|
|
96
|
+
function loadVectorStore(root) {
|
|
97
|
+
const p = vecPath(root);
|
|
98
|
+
if (!fs2.existsSync(p)) return null;
|
|
99
|
+
let buf;
|
|
100
|
+
try {
|
|
101
|
+
buf = fs2.readFileSync(p);
|
|
102
|
+
} catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
if (buf.length < HEADER_BYTES) return null;
|
|
106
|
+
const magic = buf.readUInt32LE(0);
|
|
107
|
+
const version = buf.readUInt32LE(4);
|
|
108
|
+
const count = buf.readUInt32LE(8);
|
|
109
|
+
const dim = buf.readUInt32LE(12);
|
|
110
|
+
if (magic !== MAGIC || version !== VERSION || dim !== EMBEDDING_DIM) return null;
|
|
111
|
+
const expected = HEADER_BYTES + count * 4 + count * dim * 4;
|
|
112
|
+
if (buf.length !== expected) return null;
|
|
113
|
+
const symbolIdx = new Uint32Array(
|
|
114
|
+
buf.buffer.slice(buf.byteOffset + HEADER_BYTES, buf.byteOffset + HEADER_BYTES + count * 4)
|
|
115
|
+
);
|
|
116
|
+
const vectors = new Float32Array(
|
|
117
|
+
buf.buffer.slice(
|
|
118
|
+
buf.byteOffset + HEADER_BYTES + count * 4,
|
|
119
|
+
buf.byteOffset + HEADER_BYTES + count * 4 + count * dim * 4
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
return { root: path2.resolve(root), count, dim, vectors, symbolIdx };
|
|
123
|
+
}
|
|
124
|
+
function clearVectorStore(root) {
|
|
125
|
+
const p = vecPath(root);
|
|
126
|
+
try {
|
|
127
|
+
if (fs2.existsSync(p)) fs2.unlinkSync(p);
|
|
128
|
+
} catch {
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function searchVectorStore(store, queryVec, k) {
|
|
132
|
+
if (store.count === 0) return [];
|
|
133
|
+
if (queryVec.length !== store.dim) {
|
|
134
|
+
throw new Error(`searchVectorStore: dim mismatch (query=${queryVec.length}, store=${store.dim})`);
|
|
135
|
+
}
|
|
136
|
+
const { count, dim, vectors, symbolIdx } = store;
|
|
137
|
+
const heap = [];
|
|
138
|
+
const push = (hit) => {
|
|
139
|
+
if (heap.length < k) {
|
|
140
|
+
heap.push(hit);
|
|
141
|
+
heap.sort((a, b) => a.score - b.score);
|
|
142
|
+
} else if (hit.score > heap[0].score) {
|
|
143
|
+
heap[0] = hit;
|
|
144
|
+
heap.sort((a, b) => a.score - b.score);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
for (let row = 0; row < count; row++) {
|
|
148
|
+
const base = row * dim;
|
|
149
|
+
let score = 0;
|
|
150
|
+
for (let d = 0; d < dim; d++) {
|
|
151
|
+
score += vectors[base + d] * queryVec[d];
|
|
152
|
+
}
|
|
153
|
+
push({ row, symbolIdx: symbolIdx[row], score });
|
|
154
|
+
}
|
|
155
|
+
return heap.sort((a, b) => b.score - a.score);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export {
|
|
159
|
+
EMBEDDING_DIM,
|
|
160
|
+
embed,
|
|
161
|
+
embedOne,
|
|
162
|
+
emptyVectorStore,
|
|
163
|
+
saveVectorStore,
|
|
164
|
+
loadVectorStore,
|
|
165
|
+
clearVectorStore,
|
|
166
|
+
searchVectorStore
|
|
167
|
+
};
|