jinzd-ai-cli 0.4.303 → 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.
- package/dist/{batch-PEH5MTMC.js → batch-OX27K4GG.js} +2 -2
- package/dist/{chunk-DHQCJC2B.js → chunk-3ZABGT3S.js} +1 -1
- package/dist/{chunk-RWM2GFRC.js → chunk-45UVJXFQ.js} +6 -2
- package/dist/{chunk-55AANMEM.js → chunk-4DH5LZR5.js} +1 -1
- package/dist/{chunk-23SJVOQD.js → chunk-72AR23R2.js} +26 -5
- package/dist/{chunk-6ZRLM3NG.js → chunk-AXKERUXH.js} +3 -3
- package/dist/{chunk-VOIOUJXI.js → chunk-C2Z77RTU.js} +13 -5
- package/dist/{chunk-ZMCZMR4R.js → chunk-GOIDKTBE.js} +12 -11
- package/dist/{chunk-ORDEOJXX.js → chunk-I6RATYRF.js} +1 -1
- package/dist/{chunk-WCJR5HCF.js → chunk-IPUTC5EX.js} +30 -12
- package/dist/{chunk-7XU4BATV.js → chunk-KBDKKHXB.js} +15 -6
- package/dist/{chunk-4DEMGCK4.js → chunk-LF67HWWR.js} +37 -13
- package/dist/{chunk-7WD2TBWY.js → chunk-NBYSFFCO.js} +1 -1
- package/dist/{chunk-XEKMGE2G.js → chunk-NFLE34QG.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-3GOHR45I.js → chunk-PA4C452B.js} +1 -1
- package/dist/{chunk-Q24BN6WF.js → chunk-Q4DAKI7I.js} +1 -1
- package/dist/{chunk-EMLRCVY2.js → chunk-SZ4226XY.js} +1 -1
- package/dist/{chunk-YK42KYKN.js → chunk-UFK5CTBU.js} +3 -3
- package/dist/{chunk-PPIISCFN.js → chunk-UFW4S3RU.js} +37 -13
- package/dist/{chunk-CKH4KQ4E.js → chunk-WQ3OMEC4.js} +6 -2
- package/dist/{chunk-UUSRWSSX.js → chunk-XJOK5353.js} +15 -6
- package/dist/{chunk-PEDN3AWT.js → chunk-YPOWDFOV.js} +1 -1
- package/dist/{ci-UXULLQMN.js → ci-IIMLOXFH.js} +4 -4
- package/dist/{ci-format-23FWBZN6.js → ci-format-FMBJC3EY.js} +2 -2
- package/dist/{constants-A6VKRPMA.js → constants-55QQ3RYE.js} +1 -1
- package/dist/{constants-HL7DYRDJ.js → constants-7NVAPQVR.js} +1 -1
- package/dist/{doctor-cli-FXBLI3EA.js → doctor-cli-ZHZ2XOF3.js} +4 -4
- package/dist/electron-server.js +250 -108
- package/dist/{hub-NLULKDKU.js → hub-MF53NIM2.js} +4 -4
- package/dist/{hub-server-RF6LURXY.js → hub-server-CBKCP5VD.js} +1 -1
- package/dist/index.js +24 -23
- package/dist/{indexer-RBEKMFT4.js → indexer-FPKY7LCT.js} +2 -2
- package/dist/{indexer-TNDWGFRI.js → indexer-P3FPRTPJ.js} +2 -2
- package/dist/{persistent-memory-NLXNNWOW.js → persistent-memory-LCOKUDTM.js} +2 -2
- package/dist/{persistent-memory-R4KLRI5Q.js → persistent-memory-NACQW2VB.js} +2 -2
- package/dist/{pr-K6Z73QYN.js → pr-NHWE5FW7.js} +4 -4
- package/dist/{run-tests-RYUB6PVF.js → run-tests-EUPJLDXS.js} +2 -2
- package/dist/{run-tests-PQ3SUDDN.js → run-tests-ZG5X25BJ.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-QCCH3277.js → server-PG7QCH53.js} +193 -82
- package/dist/{server-UJDYIBVR.js → server-PNYRE3AL.js} +9 -9
- package/dist/{store-MWNHVGJT.js → store-CMSSWZF7.js} +3 -1
- package/dist/{store-VO37H6LS.js → store-SIKHCUYJ.js} +3 -1
- package/dist/{task-orchestrator-QAQFB7DG.js → task-orchestrator-WAJTCE6D.js} +9 -9
- package/dist/{usage-PMHXXU2P.js → usage-DOES3DOS.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-NFLE34QG.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-NBYSFFCO.js";
|
|
13
13
|
|
|
14
14
|
// src/cli/batch.ts
|
|
15
15
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -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-NBYSFFCO.js";
|
|
17
17
|
|
|
18
18
|
// src/memory/persistent-memory.ts
|
|
19
19
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
|
|
@@ -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);
|
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
listHooks,
|
|
9
9
|
listInstalledPlugins,
|
|
10
10
|
resetStats
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-Q4DAKI7I.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-NFLE34QG.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-NBYSFFCO.js";
|
|
30
30
|
|
|
31
31
|
// src/diagnostics/doctor-report.ts
|
|
32
32
|
import { existsSync as existsSync3, statSync as statSync2 } from "fs";
|
|
@@ -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
|
});
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
setPreferredAgentName,
|
|
17
17
|
truncateForPersist,
|
|
18
18
|
undoStack
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-IPUTC5EX.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-3ZABGT3S.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-AXKERUXH.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-Q4DAKI7I.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-NBYSFFCO.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-7NVAPQVR.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-ZG5X25BJ.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) => {
|
|
@@ -11,17 +11,17 @@ import {
|
|
|
11
11
|
searchPersistentMemories,
|
|
12
12
|
touchMemoryReferences,
|
|
13
13
|
updateMemoryEntry
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-3ZABGT3S.js";
|
|
15
15
|
import {
|
|
16
16
|
indexProject
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-LF67HWWR.js";
|
|
18
18
|
import {
|
|
19
19
|
hasSemanticIndex,
|
|
20
20
|
semanticSearch
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-XJOK5353.js";
|
|
22
22
|
import {
|
|
23
23
|
loadIndex
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-WQ3OMEC4.js";
|
|
25
25
|
import {
|
|
26
26
|
theme
|
|
27
27
|
} from "./chunk-5C76XDDF.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
runHook,
|
|
31
31
|
runLifecycleHooks,
|
|
32
32
|
runTool
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-Q4DAKI7I.js";
|
|
34
34
|
import {
|
|
35
35
|
buildTruncatedArgumentsError,
|
|
36
36
|
getDangerLevel,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
} from "./chunk-4BKXL7SM.js";
|
|
51
51
|
import {
|
|
52
52
|
runTestsTool
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-I6RATYRF.js";
|
|
54
54
|
import {
|
|
55
55
|
CONFIG_DIR_NAME,
|
|
56
56
|
DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
SUBAGENT_ALLOWED_TOOLS,
|
|
59
59
|
SUBAGENT_DEFAULT_MAX_ROUNDS,
|
|
60
60
|
SUBAGENT_MAX_ROUNDS_LIMIT
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-NBYSFFCO.js";
|
|
62
62
|
|
|
63
63
|
// src/tools/shell-pool.ts
|
|
64
64
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -931,6 +931,11 @@ function buildErrorHint(command, stderr) {
|
|
|
931
931
|
`Hint: On Windows, "-ErrorAction SilentlyContinue" silences the error MESSAGE but does NOT change the exit code \u2014 the process still exits 1 when the path doesn't exist (because powershell.exe -NonInteractive flips the exit code on any non-terminating error, silenced or not). If you're just probing for existence, use Test-Path instead \u2014 it returns $true/$false without raising: \`if (Test-Path ./mydir) { Get-ChildItem ./mydir }\` or unconditionally use \`New-Item -ItemType Directory -Force -Path ./mydir\` which is idempotent. Don't retry the same -ErrorAction SilentlyContinue probe expecting a different result.`
|
|
932
932
|
);
|
|
933
933
|
}
|
|
934
|
+
if (IS_WINDOWS3 && /Select-Object\s+(?:[^|]*\s)?-(?:First|Last)\s+\d+/i.test(command) && /\|/.test(command)) {
|
|
935
|
+
hints.push(
|
|
936
|
+
`Hint: "Select-Object -First N" stops the upstream pipeline as soon as it has N items (PipelineStoppedException), and PowerShell reports that as a FAILURE even when the upstream command did its job \u2014 check the output above: if it shows the work completed (e.g. "EXPORTED 25 slide(s)"), this is a false failure and you should NOT retry. To avoid it, capture first and slice after: \`$out = <command>; $out | Select-Object -First N\`, or drop the -First and let the full output through.`
|
|
937
|
+
);
|
|
938
|
+
}
|
|
934
939
|
if (IS_WINDOWS3 && /\bWrite-(?:Content|File)\b/i.test(command) && /(not recognized|无法将.*识别|不是.*cmdlet|CommandNotFoundException)/i.test(stderr)) {
|
|
935
940
|
hints.push(
|
|
936
941
|
`Hint: 'Write-Content' / 'Write-File' are NOT PowerShell cmdlets (common LLM hallucination). To write a file, prefer the built-in 'write_file' tool \u2014 it handles encoding/escaping cleanly and supports diff preview. If you must stay in bash: use 'Set-Content -Path <file> -Value <string> -Encoding utf8' (overwrites) or 'Add-Content' (appends) or 'Out-File -FilePath <file> -Encoding utf8'.`
|
|
@@ -2126,9 +2131,9 @@ function setMaxOutputCap(cap) {
|
|
|
2126
2131
|
activeMaxChars = getMaxOutputChars(lastContextWindow);
|
|
2127
2132
|
}
|
|
2128
2133
|
}
|
|
2129
|
-
function getMaxOutputChars(contextWindow) {
|
|
2134
|
+
function getMaxOutputChars(contextWindow, cap = activeCap) {
|
|
2130
2135
|
if (!contextWindow || contextWindow <= 0) return DEFAULT_MAX_TOOL_OUTPUT_CHARS;
|
|
2131
|
-
return Math.max(DEFAULT_MAX_TOOL_OUTPUT_CHARS, Math.min(Math.floor(contextWindow / 4),
|
|
2136
|
+
return Math.max(DEFAULT_MAX_TOOL_OUTPUT_CHARS, Math.min(Math.floor(contextWindow / 4), cap > 0 ? cap : DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP));
|
|
2132
2137
|
}
|
|
2133
2138
|
var activeMaxChars = DEFAULT_MAX_TOOL_OUTPUT_CHARS;
|
|
2134
2139
|
var lastContextWindow = 0;
|
|
@@ -2401,7 +2406,12 @@ function buildErrorPreview(content) {
|
|
|
2401
2406
|
undecorated.push(raw[i]);
|
|
2402
2407
|
}
|
|
2403
2408
|
const meaningful = undecorated.filter(
|
|
2404
|
-
(l) => !/^(?:\[[^\]]+\]\s*)?Exit code \d+:$/.test(l.trim()) &&
|
|
2409
|
+
(l) => !/^(?:\[[^\]]+\]\s*)?Exit code \d+:$/.test(l.trim()) && // `formatFailureHeader()` 在拿不到退出码时打的那句 —— 与 "Exit code N:" 同类噪声。
|
|
2410
|
+
// 不过滤的话它会占掉第一个展示位:2026-09-05 实战里 `export_slides.ps1 | Select-Object
|
|
2411
|
+
// -First 3` 提前掐断管道被 PowerShell 报成失败,预览成了
|
|
2412
|
+
// 「Command failed before exit code could be determined: · …\slide-02.png」——
|
|
2413
|
+
// 两段都没用,而真正有信息的 `EXPORTED 25 slide(s)` 就在第二行、从没上屏。
|
|
2414
|
+
!/^(?:\[[^\]]+\]\s*)?Command failed before exit code could be determined:$/.test(l.trim()) && !/^Traceback \(most recent call last\):$/.test(l.trim()) && !l.startsWith("[Command failed") && !l.startsWith("\u{1F4A1} ") && l.trim() !== ""
|
|
2405
2415
|
);
|
|
2406
2416
|
let primary = -1;
|
|
2407
2417
|
for (let i = meaningful.length - 1; i >= 0; i--) {
|
|
@@ -2902,7 +2912,7 @@ var ToolExecutor = class {
|
|
|
2902
2912
|
... (${lines.length - maxLines} more lines)`) : "";
|
|
2903
2913
|
const truncatedNote = wasTruncated ? theme.warning(`
|
|
2904
2914
|
\u26A1 Output truncated to ${getActiveMaxChars()} chars before sending to AI`) : "";
|
|
2905
|
-
console.log(theme.toolResult(
|
|
2915
|
+
console.log(theme.toolResult(`\u2713 ${name} result: `) + theme.dim(preview) + moreLines + truncatedNote);
|
|
2906
2916
|
}
|
|
2907
2917
|
console.log();
|
|
2908
2918
|
}
|
|
@@ -3128,7 +3138,7 @@ Do NOT split a long document into many write_file(append=true) calls. That patte
|
|
|
3128
3138
|
const mode = appendMode ? "appended" : "written";
|
|
3129
3139
|
void (async () => {
|
|
3130
3140
|
try {
|
|
3131
|
-
const { updateFile } = await import("./indexer-
|
|
3141
|
+
const { updateFile } = await import("./indexer-P3FPRTPJ.js");
|
|
3132
3142
|
await updateFile(process.cwd(), filePath);
|
|
3133
3143
|
} catch {
|
|
3134
3144
|
}
|
|
@@ -3555,6 +3565,9 @@ Note: Path can be absolute or relative to cwd.`,
|
|
|
3555
3565
|
fileCheckpoints.snapshot(filePath, ToolExecutor.currentMessageIndex);
|
|
3556
3566
|
atomicWriteFileSync(filePath, res.content);
|
|
3557
3567
|
}
|
|
3568
|
+
if (!res.ok) {
|
|
3569
|
+
throw new ToolError("edit_file", lines.join("\n"));
|
|
3570
|
+
}
|
|
3558
3571
|
return lines.join("\n");
|
|
3559
3572
|
}
|
|
3560
3573
|
if (args["edits"] !== void 0) {
|
|
@@ -3607,6 +3620,9 @@ Note: Path can be absolute or relative to cwd.`,
|
|
|
3607
3620
|
lines.push(` \u2717 #${r.index + 1}: ${r.error}`);
|
|
3608
3621
|
}
|
|
3609
3622
|
}
|
|
3623
|
+
if (anyFailed && stopOnError) {
|
|
3624
|
+
throw new ToolError("edit_file", lines.join("\n"));
|
|
3625
|
+
}
|
|
3610
3626
|
return lines.join("\n");
|
|
3611
3627
|
}
|
|
3612
3628
|
const replaceArgs = normalizeReplaceArgs(args);
|
|
@@ -7179,7 +7195,9 @@ export {
|
|
|
7179
7195
|
checkPermissionWithProfile,
|
|
7180
7196
|
formatPermissionProfileWarning,
|
|
7181
7197
|
checkNetworkPolicy,
|
|
7198
|
+
DEFAULT_MAX_TOOL_OUTPUT_CHARS,
|
|
7182
7199
|
setMaxOutputCap,
|
|
7200
|
+
getMaxOutputChars,
|
|
7183
7201
|
setContextWindow,
|
|
7184
7202
|
truncateForPersist,
|
|
7185
7203
|
truncateOutput,
|
|
@@ -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 {
|
|
@@ -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
|
}
|