jinzd-ai-cli 0.4.304 → 0.4.306
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/dist/{batch-RY2F7BX5.js → batch-JLGWQ7HU.js} +2 -2
- package/dist/{chunk-3FI4TE5S.js → chunk-3RDJEYF7.js} +3 -3
- package/dist/{chunk-RWM2GFRC.js → chunk-45UVJXFQ.js} +6 -2
- package/dist/{chunk-23SJVOQD.js → chunk-72AR23R2.js} +26 -5
- package/dist/{chunk-I2WJ44D3.js → chunk-7SSCSSC6.js} +1 -1
- package/dist/{chunk-F3EJ4MIP.js → chunk-AYLK4EGA.js} +12 -11
- package/dist/{chunk-VOIOUJXI.js → chunk-C2Z77RTU.js} +13 -5
- package/dist/{chunk-2GRGLTAK.js → chunk-JDT6UG6R.js} +3 -1
- package/dist/{chunk-OECPGCHP.js → chunk-JFNBJHR6.js} +3 -3
- package/dist/{chunk-6AGTDWO3.js → chunk-K5SDDTN7.js} +1 -1
- package/dist/{chunk-7XU4BATV.js → chunk-KBDKKHXB.js} +15 -6
- package/dist/{chunk-7L7T46PI.js → chunk-LAP7TPPK.js} +1 -1
- package/dist/{chunk-4DEMGCK4.js → chunk-LF67HWWR.js} +37 -13
- package/dist/{chunk-TBTVV3KK.js → chunk-NLB7JZSO.js} +1 -1
- package/dist/{chunk-BXP6YZ2P.js → chunk-NRSYBKWA.js} +5 -4
- package/dist/{chunk-IEQAE3QG.js → chunk-OAXLMF3U.js} +5 -4
- package/dist/{chunk-XIMM47EG.js → chunk-OC2XHG5L.js} +1 -1
- package/dist/{chunk-RHCRE6XE.js → chunk-T6WQEQI4.js} +3 -1
- package/dist/{chunk-PPIISCFN.js → chunk-UFW4S3RU.js} +37 -13
- package/dist/{chunk-2PLYXL4P.js → chunk-VLDB2SVN.js} +33 -21
- package/dist/{chunk-BSBGPDCX.js → chunk-W6PLV3EY.js} +1 -1
- package/dist/{chunk-CKH4KQ4E.js → chunk-WQ3OMEC4.js} +6 -2
- package/dist/{chunk-DNGUSTL6.js → chunk-WZWRA7R2.js} +1 -1
- package/dist/{chunk-UUSRWSSX.js → chunk-XJOK5353.js} +15 -6
- package/dist/{ci-QYTLBM6Z.js → ci-6PHEL3C7.js} +4 -4
- package/dist/{ci-format-E5X27NC2.js → ci-format-AZYUP6BL.js} +2 -2
- package/dist/{constants-JDPKWZJP.js → constants-AXBD2EEB.js} +3 -1
- package/dist/{constants-F5WA5VPO.js → constants-CPNWIUGZ.js} +3 -1
- package/dist/{doctor-cli-7NSEVW63.js → doctor-cli-DDHHDMMJ.js} +4 -4
- package/dist/electron-server.js +253 -117
- package/dist/{hub-43PWTGGO.js → hub-DDYAWLF2.js} +4 -4
- package/dist/{hub-server-RF6LURXY.js → hub-server-CBKCP5VD.js} +1 -1
- package/dist/index.js +25 -24
- package/dist/{indexer-RBEKMFT4.js → indexer-FPKY7LCT.js} +2 -2
- package/dist/{indexer-TNDWGFRI.js → indexer-P3FPRTPJ.js} +2 -2
- package/dist/{persistent-memory-SHG3CJCP.js → persistent-memory-6XYYOMSC.js} +2 -2
- package/dist/{persistent-memory-A7RPDLR7.js → persistent-memory-XZISXRWT.js} +2 -2
- package/dist/{pr-LW755EL7.js → pr-UY4ZCZNI.js} +4 -4
- package/dist/{run-tests-HV37CM5U.js → run-tests-BAMLVLO6.js} +2 -2
- package/dist/{run-tests-MJ3SCW27.js → run-tests-UEE3OMLS.js} +2 -2
- package/dist/{semantic-HLAE2O4F.js → semantic-7GM5M4MU.js} +3 -3
- package/dist/{semantic-VPNKXKKK.js → semantic-QOBAXEQ4.js} +3 -3
- package/dist/{server-WI3Q4EDH.js → server-6IC33CJK.js} +9 -9
- package/dist/{server-EZ5ULLDP.js → server-DBHLVQVP.js} +193 -82
- package/dist/{store-MWNHVGJT.js → store-CMSSWZF7.js} +3 -1
- package/dist/{store-VO37H6LS.js → store-SIKHCUYJ.js} +3 -1
- package/dist/{task-orchestrator-PWW5I2KE.js → task-orchestrator-RDDETDW2.js} +9 -9
- package/dist/{usage-MAIV6XUZ.js → usage-D473ZVIP.js} +2 -2
- package/dist/{vector-store-JBAE6PS4.js → vector-store-JAXWDZYW.js} +1 -1
- package/dist/{vector-store-BBDXB5IQ.js → vector-store-PWIOQFTP.js} +1 -1
- package/dist/web/client/app.js +135 -60
- package/dist/web/client/app.js.br +0 -0
- package/dist/web/client/app.js.gz +0 -0
- package/dist/web/client/chat-input.js +38 -0
- package/dist/web/client/chat-input.js.br +0 -0
- package/dist/web/client/chat-input.js.gz +0 -0
- package/dist/web/client/index.html +1 -1
- package/dist/web/client/index.html.br +0 -0
- package/dist/web/client/index.html.gz +0 -0
- package/dist/web/client/stream-render.js +33 -0
- package/dist/web/client/style.css +2 -1
- package/dist/web/client/style.css.br +0 -0
- package/dist/web/client/style.css.gz +0 -0
- package/package.json +1 -1
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
} from "./chunk-RS7SKYTS.js";
|
|
5
5
|
import {
|
|
6
6
|
ConfigManager
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-OC2XHG5L.js";
|
|
8
8
|
import "./chunk-TU3L3PW7.js";
|
|
9
9
|
import {
|
|
10
10
|
atomicWriteFileSync
|
|
11
11
|
} from "./chunk-IW3Q7AE5.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-T6WQEQI4.js";
|
|
13
13
|
|
|
14
14
|
// src/cli/batch.ts
|
|
15
15
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
evaluateCiGate,
|
|
4
4
|
normalizeCiThresholds
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-K5SDDTN7.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-
|
|
19
|
+
} from "./chunk-OC2XHG5L.js";
|
|
20
20
|
import {
|
|
21
21
|
VERSION
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-T6WQEQI4.js";
|
|
23
23
|
|
|
24
24
|
// src/cli/ci.ts
|
|
25
25
|
import { execFileSync } from "child_process";
|
|
@@ -79,6 +79,9 @@ function saveIndex(index) {
|
|
|
79
79
|
const target = indexPath(index.root);
|
|
80
80
|
atomicWriteFileSync(target, JSON.stringify(index));
|
|
81
81
|
}
|
|
82
|
+
function symbolFingerprint(index) {
|
|
83
|
+
return crypto.createHash("sha256").update(JSON.stringify(index.symbols)).digest("hex");
|
|
84
|
+
}
|
|
82
85
|
function clearIndex(root) {
|
|
83
86
|
const p = indexPath(root);
|
|
84
87
|
try {
|
|
@@ -100,11 +103,11 @@ function emptyIndex(root) {
|
|
|
100
103
|
function upsertFileSymbols(index, file, mtime, symbols) {
|
|
101
104
|
const absFile = path.resolve(file);
|
|
102
105
|
const had = absFile in index.files;
|
|
103
|
-
index.symbols = index.symbols.filter((s) => s.location.file !== absFile);
|
|
106
|
+
if (had) index.symbols = index.symbols.filter((s) => s.location.file !== absFile);
|
|
104
107
|
index.symbols.push(...symbols);
|
|
105
108
|
index.files[absFile] = mtime;
|
|
106
109
|
index.symbolCount = index.symbols.length;
|
|
107
|
-
if (!had) index.fileCount
|
|
110
|
+
if (!had) index.fileCount++;
|
|
108
111
|
index.generated = (/* @__PURE__ */ new Date()).toISOString();
|
|
109
112
|
return index;
|
|
110
113
|
}
|
|
@@ -123,6 +126,7 @@ export {
|
|
|
123
126
|
detectLanguage,
|
|
124
127
|
loadIndex,
|
|
125
128
|
saveIndex,
|
|
129
|
+
symbolFingerprint,
|
|
126
130
|
clearIndex,
|
|
127
131
|
emptyIndex,
|
|
128
132
|
upsertFileSymbols,
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
HubAgent,
|
|
4
4
|
isConverged
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-C2Z77RTU.js";
|
|
6
6
|
|
|
7
7
|
// src/hub/discuss.ts
|
|
8
8
|
var DiscussionOrchestrator = class {
|
|
9
9
|
agents = [];
|
|
10
10
|
state;
|
|
11
11
|
aborted = false;
|
|
12
|
+
controller = new AbortController();
|
|
13
|
+
cancelReview;
|
|
12
14
|
humanSteer;
|
|
13
15
|
voteConverge;
|
|
14
16
|
/** Callback for rendering events */
|
|
@@ -48,6 +50,8 @@ var DiscussionOrchestrator = class {
|
|
|
48
50
|
/** Signal the orchestrator to stop after current turn */
|
|
49
51
|
abort() {
|
|
50
52
|
this.aborted = true;
|
|
53
|
+
this.controller.abort();
|
|
54
|
+
this.cancelReview?.();
|
|
51
55
|
}
|
|
52
56
|
/**
|
|
53
57
|
* Run the full discussion on a given topic.
|
|
@@ -58,6 +62,7 @@ var DiscussionOrchestrator = class {
|
|
|
58
62
|
this.state.round = 0;
|
|
59
63
|
this.state.finished = false;
|
|
60
64
|
this.aborted = false;
|
|
65
|
+
this.controller = new AbortController();
|
|
61
66
|
try {
|
|
62
67
|
for (let round = 1; round <= this.state.maxRounds; round++) {
|
|
63
68
|
if (this.aborted) {
|
|
@@ -78,7 +83,7 @@ var DiscussionOrchestrator = class {
|
|
|
78
83
|
round,
|
|
79
84
|
this.state.maxRounds,
|
|
80
85
|
(token) => this.emit({ type: "agent_token", roleId: agent.role.id, token }),
|
|
81
|
-
{ voteConverge: this.voteConverge }
|
|
86
|
+
{ voteConverge: this.voteConverge, signal: this.controller.signal }
|
|
82
87
|
);
|
|
83
88
|
this.state.messages.push(message);
|
|
84
89
|
if (message.converged) convergedCount++;
|
|
@@ -90,6 +95,7 @@ var DiscussionOrchestrator = class {
|
|
|
90
95
|
this.emit({ type: "agent_spoke", roleId: agent.role.id, message });
|
|
91
96
|
}
|
|
92
97
|
} catch (err) {
|
|
98
|
+
if (this.aborted) break;
|
|
93
99
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
94
100
|
this.emit({ type: "error", roleId: agent.role.id, message: errMsg });
|
|
95
101
|
this.state.messages.push({
|
|
@@ -101,6 +107,10 @@ var DiscussionOrchestrator = class {
|
|
|
101
107
|
}
|
|
102
108
|
}
|
|
103
109
|
this.emit({ type: "round_end", round });
|
|
110
|
+
if (this.aborted) {
|
|
111
|
+
this.emit({ type: "discussion_end", reason: "user_interrupt" });
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
104
114
|
if (allPassed && round > 1) {
|
|
105
115
|
this.emit({ type: "discussion_end", reason: "consensus" });
|
|
106
116
|
break;
|
|
@@ -117,7 +127,18 @@ var DiscussionOrchestrator = class {
|
|
|
117
127
|
break;
|
|
118
128
|
}
|
|
119
129
|
if (this.humanSteer && this.onRoundReview && !this.aborted) {
|
|
120
|
-
const
|
|
130
|
+
const stopped = new Promise((resolve) => {
|
|
131
|
+
this.cancelReview = () => resolve({ action: "stop" });
|
|
132
|
+
});
|
|
133
|
+
let steer;
|
|
134
|
+
try {
|
|
135
|
+
steer = await Promise.race([
|
|
136
|
+
this.onRoundReview({ round, maxRounds: this.state.maxRounds, state: this.state }),
|
|
137
|
+
stopped
|
|
138
|
+
]);
|
|
139
|
+
} finally {
|
|
140
|
+
this.cancelReview = void 0;
|
|
141
|
+
}
|
|
121
142
|
if (steer.action === "stop") {
|
|
122
143
|
this.emit({ type: "discussion_end", reason: "human_stop" });
|
|
123
144
|
break;
|
|
@@ -138,7 +159,7 @@ var DiscussionOrchestrator = class {
|
|
|
138
159
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
139
160
|
this.emit({ type: "error", message: errMsg });
|
|
140
161
|
}
|
|
141
|
-
await this.generateSummary();
|
|
162
|
+
if (!this.aborted) await this.generateSummary();
|
|
142
163
|
this.state.finished = true;
|
|
143
164
|
return this.state;
|
|
144
165
|
}
|
|
@@ -156,7 +177,7 @@ var DiscussionOrchestrator = class {
|
|
|
156
177
|
return;
|
|
157
178
|
}
|
|
158
179
|
try {
|
|
159
|
-
this.state.summary = await summarizer.summarize(this.state.topic, this.state.messages);
|
|
180
|
+
this.state.summary = await summarizer.summarize(this.state.topic, this.state.messages, this.controller.signal);
|
|
160
181
|
this.emit({ type: "summary", content: this.state.summary });
|
|
161
182
|
} catch (err) {
|
|
162
183
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
setPreferredAgentName,
|
|
17
17
|
truncateForPersist,
|
|
18
18
|
undoStack
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-VLDB2SVN.js";
|
|
20
20
|
import {
|
|
21
21
|
buildReviewPrompt,
|
|
22
22
|
buildSecurityReviewPrompt
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
touchMemoryReferences,
|
|
52
52
|
updateMemoryApproval,
|
|
53
53
|
updateMemoryEntry
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-LAP7TPPK.js";
|
|
55
55
|
import {
|
|
56
56
|
theme
|
|
57
57
|
} from "./chunk-5C76XDDF.js";
|
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
import {
|
|
66
66
|
buildDoctorReport,
|
|
67
67
|
formatDoctorReport
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-JFNBJHR6.js";
|
|
69
69
|
import {
|
|
70
70
|
describePlugin,
|
|
71
71
|
getActivePluginAssets,
|
|
@@ -80,7 +80,7 @@ import {
|
|
|
80
80
|
trustHook,
|
|
81
81
|
trustPlugin,
|
|
82
82
|
untrustHook
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-7SSCSSC6.js";
|
|
84
84
|
import {
|
|
85
85
|
isCleanDocumentBody,
|
|
86
86
|
stripOuterCodeFence
|
|
@@ -109,7 +109,7 @@ import {
|
|
|
109
109
|
MCP_TOOL_PREFIX,
|
|
110
110
|
REPO_URL,
|
|
111
111
|
VERSION
|
|
112
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-T6WQEQI4.js";
|
|
113
113
|
|
|
114
114
|
// src/skills/manager.ts
|
|
115
115
|
import { existsSync, readdirSync, mkdirSync, statSync } from "fs";
|
|
@@ -2426,7 +2426,7 @@ No tools match "${filter}".
|
|
|
2426
2426
|
const { join: join6 } = await import("path");
|
|
2427
2427
|
const { existsSync: existsSync6 } = await import("fs");
|
|
2428
2428
|
const { getGitRoot } = await import("./git-context-EXOEHQSF.js");
|
|
2429
|
-
const { MCP_PROJECT_CONFIG_NAME } = await import("./constants-
|
|
2429
|
+
const { MCP_PROJECT_CONFIG_NAME } = await import("./constants-CPNWIUGZ.js");
|
|
2430
2430
|
const { approveProject, hashMcpFile } = await import("./project-trust-NKYHL3VZ.js");
|
|
2431
2431
|
const cwd = process.cwd();
|
|
2432
2432
|
const projectRoot = getGitRoot(cwd) ?? cwd;
|
|
@@ -3534,7 +3534,7 @@ function createReviewCommands() {
|
|
|
3534
3534
|
usage: "/test [command|filter]",
|
|
3535
3535
|
async execute(args, ctx) {
|
|
3536
3536
|
try {
|
|
3537
|
-
const { executeTests } = await import("./run-tests-
|
|
3537
|
+
const { executeTests } = await import("./run-tests-BAMLVLO6.js");
|
|
3538
3538
|
const argStr = args.join(" ").trim();
|
|
3539
3539
|
let testArgs = {};
|
|
3540
3540
|
if (argStr) {
|
|
@@ -3900,9 +3900,9 @@ function createMemoryCommands() {
|
|
|
3900
3900
|
async execute(args, ctx) {
|
|
3901
3901
|
const sub = (args[0] ?? "status").toLowerCase();
|
|
3902
3902
|
const root = process.cwd();
|
|
3903
|
-
const { loadIndex, clearIndex } = await import("./store-
|
|
3904
|
-
const { indexProject } = await import("./indexer-
|
|
3905
|
-
const { loadVectorStore, clearVectorStore } = await import("./vector-store-
|
|
3903
|
+
const { loadIndex, clearIndex } = await import("./store-CMSSWZF7.js");
|
|
3904
|
+
const { indexProject } = await import("./indexer-P3FPRTPJ.js");
|
|
3905
|
+
const { loadVectorStore, clearVectorStore } = await import("./vector-store-PWIOQFTP.js");
|
|
3906
3906
|
if (sub === "status") {
|
|
3907
3907
|
const idx = loadIndex(root);
|
|
3908
3908
|
const vec = loadVectorStore(root);
|
|
@@ -3933,6 +3933,7 @@ function createMemoryCommands() {
|
|
|
3933
3933
|
}
|
|
3934
3934
|
});
|
|
3935
3935
|
process.stdout.write("\r\x1B[K");
|
|
3936
|
+
if (stats.incomplete) console.log(theme.dim(" Partial index: scan limit or unreadable files reached; unscanned entries retained."));
|
|
3936
3937
|
console.log(theme.success(
|
|
3937
3938
|
` \u2713 Indexed ${stats.filesParsed} files (${stats.symbols} symbols) in ${stats.durationMs}ms`
|
|
3938
3939
|
));
|
|
@@ -3961,7 +3962,7 @@ function createMemoryCommands() {
|
|
|
3961
3962
|
}
|
|
3962
3963
|
console.log(theme.dim(` Building semantic index for ${idx.symbolCount} symbols\u2026`));
|
|
3963
3964
|
console.log(theme.dim(" (First run downloads ~117 MB embedding model to ~/.aicli/models/)"));
|
|
3964
|
-
const { rebuildSemanticIndex } = await import("./semantic-
|
|
3965
|
+
const { rebuildSemanticIndex } = await import("./semantic-7GM5M4MU.js");
|
|
3965
3966
|
try {
|
|
3966
3967
|
const stats = await rebuildSemanticIndex(root, {
|
|
3967
3968
|
onProgress: (done, total) => {
|
|
@@ -70,6 +70,7 @@ var HubAgent = class {
|
|
|
70
70
|
model: this.modelId,
|
|
71
71
|
systemPrompt,
|
|
72
72
|
stream: false,
|
|
73
|
+
signal: opts?.signal,
|
|
73
74
|
temperature: 0.7,
|
|
74
75
|
maxTokens: 4096,
|
|
75
76
|
...this.thinking ?? {}
|
|
@@ -104,15 +105,21 @@ var HubAgent = class {
|
|
|
104
105
|
model: this.modelId,
|
|
105
106
|
systemPrompt,
|
|
106
107
|
stream: true,
|
|
108
|
+
signal: opts?.signal,
|
|
107
109
|
temperature: 0.7,
|
|
108
110
|
maxTokens: 4096,
|
|
109
111
|
...this.thinking ?? {}
|
|
110
112
|
});
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
try {
|
|
114
|
+
for await (const chunk of stream) {
|
|
115
|
+
if (chunk.delta) {
|
|
116
|
+
raw += chunk.delta;
|
|
117
|
+
onToken?.(chunk.delta);
|
|
118
|
+
}
|
|
119
|
+
if (opts?.signal?.aborted) break;
|
|
115
120
|
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (!opts?.signal?.aborted) throw error;
|
|
116
123
|
}
|
|
117
124
|
const { content, passed, converged } = parseTurn(raw);
|
|
118
125
|
return {
|
|
@@ -127,7 +134,7 @@ var HubAgent = class {
|
|
|
127
134
|
/**
|
|
128
135
|
* Generate a summary of the entire discussion from this agent's perspective.
|
|
129
136
|
*/
|
|
130
|
-
async summarize(topic, history) {
|
|
137
|
+
async summarize(topic, history, signal) {
|
|
131
138
|
const provider = this.providers.get(this.providerId);
|
|
132
139
|
if (!provider) {
|
|
133
140
|
throw new Error(`Provider "${this.providerId}" not available`);
|
|
@@ -144,6 +151,7 @@ var HubAgent = class {
|
|
|
144
151
|
model: this.modelId,
|
|
145
152
|
stream: false,
|
|
146
153
|
temperature: 0.3,
|
|
154
|
+
signal,
|
|
147
155
|
maxTokens: 4096,
|
|
148
156
|
...this.thinking ?? {}
|
|
149
157
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/core/constants.ts
|
|
2
|
-
var VERSION = "0.4.
|
|
2
|
+
var VERSION = "0.4.306";
|
|
3
3
|
var APP_NAME = "ai-cli";
|
|
4
4
|
var CONFIG_DIR_NAME = ".aicli";
|
|
5
5
|
var CONFIG_FILE_NAME = "config.json";
|
|
@@ -18,6 +18,7 @@ var DEFAULT_TEMPERATURE = 0.7;
|
|
|
18
18
|
var MAX_HISTORY_DAYS = 30;
|
|
19
19
|
var DEFAULT_MAX_TOOL_ROUNDS = 200;
|
|
20
20
|
var DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP = 5e5;
|
|
21
|
+
var MAX_GLOB_MATCHES = 30;
|
|
21
22
|
var MCP_TOOL_PREFIX = "mcp__";
|
|
22
23
|
var MCP_PROJECT_CONFIG_NAME = ".mcp.json";
|
|
23
24
|
var MCP_CONNECT_TIMEOUT = 3e4;
|
|
@@ -152,6 +153,7 @@ export {
|
|
|
152
153
|
MAX_HISTORY_DAYS,
|
|
153
154
|
DEFAULT_MAX_TOOL_ROUNDS,
|
|
154
155
|
DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
|
|
156
|
+
MAX_GLOB_MATCHES,
|
|
155
157
|
MCP_TOOL_PREFIX,
|
|
156
158
|
MCP_PROJECT_CONFIG_NAME,
|
|
157
159
|
MCP_CONNECT_TIMEOUT,
|
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
listHooks,
|
|
9
9
|
listInstalledPlugins,
|
|
10
10
|
resetStats
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-7SSCSSC6.js";
|
|
12
12
|
import {
|
|
13
13
|
ProviderRegistry
|
|
14
14
|
} from "./chunk-VXEF2SWG.js";
|
|
15
15
|
import {
|
|
16
16
|
ConfigManager
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-OC2XHG5L.js";
|
|
18
18
|
import {
|
|
19
19
|
getGitRoot
|
|
20
20
|
} from "./chunk-HOSJZMQS.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
MCP_PROJECT_CONFIG_NAME,
|
|
27
27
|
MEMORY_FILE_NAME,
|
|
28
28
|
VERSION
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-T6WQEQI4.js";
|
|
30
30
|
|
|
31
31
|
// src/diagnostics/doctor-report.ts
|
|
32
32
|
import { existsSync as existsSync3, statSync as statSync2 } from "fs";
|
|
@@ -2,15 +2,16 @@ import {
|
|
|
2
2
|
loadVectorStore,
|
|
3
3
|
saveVectorStore,
|
|
4
4
|
searchVectorStore
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OAXLMF3U.js";
|
|
6
6
|
import {
|
|
7
7
|
EMBEDDING_DIM,
|
|
8
8
|
embed,
|
|
9
9
|
embedOne
|
|
10
10
|
} from "./chunk-JV5N65KN.js";
|
|
11
11
|
import {
|
|
12
|
-
loadIndex
|
|
13
|
-
|
|
12
|
+
loadIndex,
|
|
13
|
+
symbolFingerprint
|
|
14
|
+
} from "./chunk-45UVJXFQ.js";
|
|
14
15
|
|
|
15
16
|
// src/symbols/semantic.ts
|
|
16
17
|
function pathTokens(absFile, root) {
|
|
@@ -66,7 +67,7 @@ async function rebuildSemanticIndex(root, opts = {}) {
|
|
|
66
67
|
const batchSize = opts.batchSize ?? 32;
|
|
67
68
|
const total = Math.min(index.symbols.length, maxSymbols);
|
|
68
69
|
if (total === 0) {
|
|
69
|
-
saveVectorStore(root, new Uint32Array(0), new Float32Array(0));
|
|
70
|
+
saveVectorStore(root, new Uint32Array(0), new Float32Array(0), symbolFingerprint(index));
|
|
70
71
|
return { symbolsEmbedded: 0, durationMs: Date.now() - start };
|
|
71
72
|
}
|
|
72
73
|
const symbolIdx = new Uint32Array(total);
|
|
@@ -87,7 +88,7 @@ async function rebuildSemanticIndex(root, opts = {}) {
|
|
|
87
88
|
}
|
|
88
89
|
if (opts.onProgress) opts.onProgress(end, total);
|
|
89
90
|
}
|
|
90
|
-
saveVectorStore(root, symbolIdx, vectors);
|
|
91
|
+
saveVectorStore(root, symbolIdx, vectors, symbolFingerprint(index));
|
|
91
92
|
return {
|
|
92
93
|
symbolsEmbedded: total,
|
|
93
94
|
durationMs: Date.now() - start,
|
|
@@ -99,7 +100,14 @@ async function semanticSearch(root, query, k = 10) {
|
|
|
99
100
|
if (!index) return [];
|
|
100
101
|
const store = loadVectorStore(root);
|
|
101
102
|
if (!store || store.count === 0) return [];
|
|
103
|
+
if (store.sourceFingerprint !== symbolFingerprint(index)) {
|
|
104
|
+
throw new Error("Semantic index is stale. Run /index semantic-rebuild before searching again.");
|
|
105
|
+
}
|
|
102
106
|
const queryVec = await embedOne(query);
|
|
107
|
+
const current = loadIndex(root);
|
|
108
|
+
if (!current || symbolFingerprint(current) !== store.sourceFingerprint) {
|
|
109
|
+
throw new Error("Symbol index changed during search. Run /index semantic-rebuild and retry.");
|
|
110
|
+
}
|
|
103
111
|
const hits = searchVectorStore(store, queryVec, k);
|
|
104
112
|
return hits.map((h) => ({
|
|
105
113
|
...h,
|
|
@@ -108,7 +116,8 @@ async function semanticSearch(root, query, k = 10) {
|
|
|
108
116
|
}
|
|
109
117
|
function hasSemanticIndex(root) {
|
|
110
118
|
const s = loadVectorStore(root);
|
|
111
|
-
|
|
119
|
+
const index = loadIndex(root);
|
|
120
|
+
return s !== null && s.count > 0 && index !== null && s.sourceFingerprint === symbolFingerprint(index);
|
|
112
121
|
}
|
|
113
122
|
|
|
114
123
|
export {
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
MEMORY_FILE_NAME,
|
|
14
14
|
MEMORY_MAX_CHARS,
|
|
15
15
|
MEMORY_STORE_FILE_NAME
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-T6WQEQI4.js";
|
|
17
17
|
|
|
18
18
|
// src/memory/persistent-memory.ts
|
|
19
19
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
removeFile,
|
|
7
7
|
saveIndex,
|
|
8
8
|
upsertFileSymbols
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-WQ3OMEC4.js";
|
|
10
10
|
|
|
11
11
|
// src/symbols/indexer.ts
|
|
12
12
|
import fs2 from "fs";
|
|
@@ -582,15 +582,18 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
582
582
|
"cmake-build-release"
|
|
583
583
|
]);
|
|
584
584
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
585
|
-
function collectFiles(root, maxFiles) {
|
|
585
|
+
async function collectFiles(root, maxFiles, signal) {
|
|
586
586
|
const out = [];
|
|
587
|
+
let incomplete = false;
|
|
587
588
|
const stack = [root];
|
|
588
589
|
while (stack.length > 0 && out.length < maxFiles) {
|
|
590
|
+
signal?.throwIfAborted();
|
|
589
591
|
const dir = stack.pop();
|
|
590
592
|
let entries;
|
|
591
593
|
try {
|
|
592
|
-
entries = fs2.
|
|
594
|
+
entries = await fs2.promises.readdir(dir, { withFileTypes: true });
|
|
593
595
|
} catch {
|
|
596
|
+
incomplete = true;
|
|
594
597
|
continue;
|
|
595
598
|
}
|
|
596
599
|
for (const e of entries) {
|
|
@@ -605,33 +608,47 @@ function collectFiles(root, maxFiles) {
|
|
|
605
608
|
const ext = path3.extname(e.name).slice(1);
|
|
606
609
|
if (detectLanguage(ext)) {
|
|
607
610
|
out.push(full);
|
|
608
|
-
if (out.length >= maxFiles)
|
|
611
|
+
if (out.length >= maxFiles) {
|
|
612
|
+
incomplete = true;
|
|
613
|
+
break;
|
|
614
|
+
}
|
|
609
615
|
}
|
|
610
616
|
}
|
|
611
617
|
}
|
|
612
618
|
}
|
|
613
|
-
return out;
|
|
619
|
+
return { files: out, incomplete };
|
|
614
620
|
}
|
|
615
621
|
async function indexProject(root, opts = {}) {
|
|
616
622
|
const start = Date.now();
|
|
617
623
|
const maxFiles = opts.maxFiles ?? 5e3;
|
|
624
|
+
if (!Number.isSafeInteger(maxFiles) || maxFiles < 1) throw new Error("maxFiles must be a positive integer");
|
|
618
625
|
const force = opts.force === true;
|
|
619
626
|
const absRoot = path3.resolve(root);
|
|
620
|
-
|
|
621
|
-
const files = collectFiles(absRoot, maxFiles);
|
|
627
|
+
const index = loadIndex(absRoot) ?? emptyIndex(absRoot);
|
|
628
|
+
const { files, incomplete } = await collectFiles(absRoot, maxFiles, opts.signal);
|
|
622
629
|
const liveSet = new Set(files.map((f) => path3.resolve(f)));
|
|
630
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
631
|
+
for (const symbol of index.symbols) {
|
|
632
|
+
const file = symbol.location.file;
|
|
633
|
+
const entries = byFile.get(file) ?? [];
|
|
634
|
+
entries.push(symbol);
|
|
635
|
+
byFile.set(file, entries);
|
|
636
|
+
}
|
|
623
637
|
for (const known of Object.keys(index.files)) {
|
|
624
|
-
if (!liveSet.has(known)) {
|
|
625
|
-
|
|
638
|
+
if (!incomplete && !liveSet.has(known)) {
|
|
639
|
+
byFile.delete(known);
|
|
640
|
+
delete index.files[known];
|
|
626
641
|
}
|
|
627
642
|
}
|
|
628
643
|
let parsed = 0;
|
|
629
644
|
let skipped = 0;
|
|
630
645
|
for (let i = 0; i < files.length; i++) {
|
|
646
|
+
opts.signal?.throwIfAborted();
|
|
647
|
+
if (i % 50 === 0) await new Promise((resolve) => setImmediate(resolve));
|
|
631
648
|
const file = path3.resolve(files[i]);
|
|
632
649
|
let stat;
|
|
633
650
|
try {
|
|
634
|
-
stat = fs2.
|
|
651
|
+
stat = await fs2.promises.stat(file);
|
|
635
652
|
} catch {
|
|
636
653
|
skipped++;
|
|
637
654
|
continue;
|
|
@@ -646,18 +663,24 @@ async function indexProject(root, opts = {}) {
|
|
|
646
663
|
}
|
|
647
664
|
let src;
|
|
648
665
|
try {
|
|
649
|
-
src = fs2.
|
|
666
|
+
src = await fs2.promises.readFile(file, "utf-8");
|
|
650
667
|
} catch {
|
|
651
668
|
skipped++;
|
|
652
669
|
continue;
|
|
653
670
|
}
|
|
654
671
|
const symbols = await parseSource(file, src);
|
|
655
|
-
|
|
672
|
+
byFile.set(file, symbols);
|
|
673
|
+
index.files[file] = stat.mtimeMs;
|
|
656
674
|
parsed++;
|
|
657
675
|
if (opts.onProgress && parsed % 50 === 0) {
|
|
658
676
|
opts.onProgress(i + 1, files.length);
|
|
659
677
|
}
|
|
660
678
|
}
|
|
679
|
+
opts.signal?.throwIfAborted();
|
|
680
|
+
index.symbols = [...byFile.values()].flat();
|
|
681
|
+
index.fileCount = Object.keys(index.files).length;
|
|
682
|
+
index.symbolCount = index.symbols.length;
|
|
683
|
+
index.generated = (/* @__PURE__ */ new Date()).toISOString();
|
|
661
684
|
saveIndex(index);
|
|
662
685
|
return {
|
|
663
686
|
index,
|
|
@@ -666,7 +689,8 @@ async function indexProject(root, opts = {}) {
|
|
|
666
689
|
filesParsed: parsed,
|
|
667
690
|
filesSkipped: skipped,
|
|
668
691
|
symbols: index.symbolCount,
|
|
669
|
-
durationMs: Date.now() - start
|
|
692
|
+
durationMs: Date.now() - start,
|
|
693
|
+
incomplete: incomplete || skipped > 0
|
|
670
694
|
}
|
|
671
695
|
};
|
|
672
696
|
}
|
|
@@ -12,8 +12,8 @@ import path from "path";
|
|
|
12
12
|
import os from "os";
|
|
13
13
|
import crypto from "crypto";
|
|
14
14
|
var MAGIC = 1094927190;
|
|
15
|
-
var VERSION =
|
|
16
|
-
var HEADER_BYTES =
|
|
15
|
+
var VERSION = 2;
|
|
16
|
+
var HEADER_BYTES = 48;
|
|
17
17
|
function indexDir() {
|
|
18
18
|
return path.join(os.homedir(), ".aicli", "index");
|
|
19
19
|
}
|
|
@@ -32,7 +32,7 @@ function emptyVectorStore(root) {
|
|
|
32
32
|
symbolIdx: new Uint32Array(0)
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
function saveVectorStore(root, indices, vectors) {
|
|
35
|
+
function saveVectorStore(root, indices, vectors, sourceFingerprint) {
|
|
36
36
|
if (indices.length * EMBEDDING_DIM !== vectors.length) {
|
|
37
37
|
throw new Error(
|
|
38
38
|
`saveVectorStore: length mismatch \u2014 ${indices.length} indices vs ${vectors.length / EMBEDDING_DIM} vectors`
|
|
@@ -47,6 +47,7 @@ function saveVectorStore(root, indices, vectors) {
|
|
|
47
47
|
buf.writeUInt32LE(VERSION, 4);
|
|
48
48
|
buf.writeUInt32LE(count, 8);
|
|
49
49
|
buf.writeUInt32LE(EMBEDDING_DIM, 12);
|
|
50
|
+
if (sourceFingerprint) Buffer.from(sourceFingerprint, "hex").copy(buf, 16, 0, 32);
|
|
50
51
|
Buffer.from(indices.buffer, indices.byteOffset, indices.byteLength).copy(buf, HEADER_BYTES);
|
|
51
52
|
Buffer.from(vectors.buffer, vectors.byteOffset, vectors.byteLength).copy(buf, HEADER_BYTES + count * 4);
|
|
52
53
|
const target = vecPath(root);
|
|
@@ -78,7 +79,7 @@ function loadVectorStore(root) {
|
|
|
78
79
|
buf.byteOffset + HEADER_BYTES + count * 4 + count * dim * 4
|
|
79
80
|
)
|
|
80
81
|
);
|
|
81
|
-
return { root: path.resolve(root), count, dim, vectors, symbolIdx };
|
|
82
|
+
return { root: path.resolve(root), count, dim, vectors, symbolIdx, sourceFingerprint: buf.subarray(16, 48).toString("hex") };
|
|
82
83
|
}
|
|
83
84
|
function clearVectorStore(root) {
|
|
84
85
|
const p = vecPath(root);
|
|
@@ -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 =
|
|
15
|
-
var HEADER_BYTES =
|
|
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);
|