jinzd-ai-cli 0.4.16 → 0.4.18
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/{chunk-DMM3XL26.js → chunk-NLT5FT2W.js} +77 -25
- package/dist/{chunk-2OKRGXVU.js → chunk-OBFFL5DJ.js} +62 -14
- package/dist/{hub-2MUUWFAZ.js → hub-WF6CNNUT.js} +1 -1
- package/dist/index.js +24 -18
- package/dist/{server-4JOL6AJL.js → server-KSH5U7QY.js} +2 -2
- package/dist/{task-orchestrator-USDQ6J6V.js → task-orchestrator-FVBUXFLC.js} +1 -1
- package/package.json +1 -1
|
@@ -594,14 +594,8 @@ Suggestion: read existing text versions (.md / .txt) in the project, or install
|
|
|
594
594
|
return `[Binary file: ${filePath} (${ext})]
|
|
595
595
|
This is a binary file and cannot be read as text. If there is a text version (.md / .txt) in the project, please read that instead.`;
|
|
596
596
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
if (fstat.size > MAX_FILE_BYTES) {
|
|
600
|
-
return `[File too large: ${filePath} | ${(fstat.size / 1024 / 1024).toFixed(1)} MB exceeds ${MAX_FILE_BYTES / 1024 / 1024} MB limit]`;
|
|
601
|
-
}
|
|
602
|
-
} catch {
|
|
603
|
-
}
|
|
604
|
-
const buf = readFileSync2(normalizedPath);
|
|
597
|
+
const { readFile: readFile2 } = await import("fs/promises");
|
|
598
|
+
const buf = size > 1048576 ? await readFile2(normalizedPath) : readFileSync2(normalizedPath);
|
|
605
599
|
if (encoding === "base64") {
|
|
606
600
|
return `[File: ${filePath} | base64]
|
|
607
601
|
|
|
@@ -1021,6 +1015,7 @@ function formatSize(bytes) {
|
|
|
1021
1015
|
|
|
1022
1016
|
// src/tools/builtin/grep-files.ts
|
|
1023
1017
|
import { readdirSync as readdirSync4, readFileSync as readFileSync4, statSync as statSync4, existsSync as existsSync6 } from "fs";
|
|
1018
|
+
import { readFile } from "fs/promises";
|
|
1024
1019
|
import { join as join2, relative } from "path";
|
|
1025
1020
|
var grepFilesTool = {
|
|
1026
1021
|
definition: {
|
|
@@ -1089,7 +1084,22 @@ Supports regex. Automatically skips node_modules, dist, .git directories.`,
|
|
|
1089
1084
|
if (stat.isFile()) {
|
|
1090
1085
|
searchInFile(rootPath, rootPath, regex, contextLines, maxResults, results);
|
|
1091
1086
|
} else {
|
|
1092
|
-
|
|
1087
|
+
const filePaths = collectFilePaths(rootPath, filePattern, maxResults);
|
|
1088
|
+
const BATCH_SIZE = 16;
|
|
1089
|
+
for (let i = 0; i < filePaths.length && results.length < maxResults; i += BATCH_SIZE) {
|
|
1090
|
+
const batch = filePaths.slice(i, i + BATCH_SIZE);
|
|
1091
|
+
const batchResults = await Promise.all(
|
|
1092
|
+
batch.map(
|
|
1093
|
+
({ fullPath, relPath }) => searchInFileAsync(fullPath, relPath, regex, contextLines, maxResults - results.length)
|
|
1094
|
+
)
|
|
1095
|
+
);
|
|
1096
|
+
for (const br of batchResults) {
|
|
1097
|
+
for (const r of br) {
|
|
1098
|
+
if (results.length >= maxResults) break;
|
|
1099
|
+
results.push(r);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1093
1103
|
}
|
|
1094
1104
|
if (results.length === 0) {
|
|
1095
1105
|
return `No matches found for pattern: ${pattern}
|
|
@@ -1137,27 +1147,69 @@ function isBinary(filename) {
|
|
|
1137
1147
|
const ext = filename.slice(filename.lastIndexOf(".")).toLowerCase();
|
|
1138
1148
|
return BINARY_EXTS.has(ext);
|
|
1139
1149
|
}
|
|
1140
|
-
function
|
|
1141
|
-
|
|
1142
|
-
|
|
1150
|
+
function collectFilePaths(rootPath, filePattern, maxFiles) {
|
|
1151
|
+
const paths = [];
|
|
1152
|
+
function walk(dirPath) {
|
|
1153
|
+
if (paths.length >= maxFiles) return;
|
|
1154
|
+
let entries;
|
|
1155
|
+
try {
|
|
1156
|
+
entries = readdirSync4(dirPath, { withFileTypes: true });
|
|
1157
|
+
} catch {
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
for (const entry of entries) {
|
|
1161
|
+
if (paths.length >= maxFiles) return;
|
|
1162
|
+
if (entry.isDirectory()) {
|
|
1163
|
+
if (SKIP_DIRS.has(entry.name) || entry.name.startsWith(".")) continue;
|
|
1164
|
+
walk(join2(dirPath, entry.name));
|
|
1165
|
+
} else if (entry.isFile()) {
|
|
1166
|
+
if (isBinary(entry.name)) continue;
|
|
1167
|
+
if (filePattern && !matchesFilePattern(entry.name, filePattern)) continue;
|
|
1168
|
+
const fullPath = join2(dirPath, entry.name);
|
|
1169
|
+
try {
|
|
1170
|
+
if (statSync4(fullPath).size > 1e6) continue;
|
|
1171
|
+
} catch {
|
|
1172
|
+
continue;
|
|
1173
|
+
}
|
|
1174
|
+
paths.push({ fullPath, relPath: relative(rootPath, fullPath) });
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
walk(rootPath);
|
|
1179
|
+
return paths;
|
|
1180
|
+
}
|
|
1181
|
+
async function searchInFileAsync(fullPath, displayPath, regex, contextLines, maxResults) {
|
|
1182
|
+
let content;
|
|
1143
1183
|
try {
|
|
1144
|
-
|
|
1184
|
+
content = await readFile(fullPath, "utf-8");
|
|
1145
1185
|
} catch {
|
|
1146
|
-
return;
|
|
1186
|
+
return [];
|
|
1147
1187
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1188
|
+
const results = [];
|
|
1189
|
+
const lines = content.split("\n");
|
|
1190
|
+
regex.lastIndex = 0;
|
|
1191
|
+
for (let i = 0; i < lines.length && results.length < maxResults; i++) {
|
|
1192
|
+
regex.lastIndex = 0;
|
|
1193
|
+
if (regex.test(lines[i])) {
|
|
1194
|
+
const match = {
|
|
1195
|
+
file: displayPath.replace(/\\/g, "/"),
|
|
1196
|
+
lineNumber: i + 1,
|
|
1197
|
+
lineText: lines[i]
|
|
1198
|
+
};
|
|
1199
|
+
if (contextLines > 0) {
|
|
1200
|
+
match.contextBefore = [];
|
|
1201
|
+
for (let j = Math.max(0, i - contextLines); j < i; j++) {
|
|
1202
|
+
match.contextBefore.push([j + 1, lines[j]]);
|
|
1203
|
+
}
|
|
1204
|
+
match.contextAfter = [];
|
|
1205
|
+
for (let j = i + 1; j <= Math.min(lines.length - 1, i + contextLines); j++) {
|
|
1206
|
+
match.contextAfter.push([j + 1, lines[j]]);
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
results.push(match);
|
|
1159
1210
|
}
|
|
1160
1211
|
}
|
|
1212
|
+
return results;
|
|
1161
1213
|
}
|
|
1162
1214
|
function searchInFile(fullPath, displayPath, regex, contextLines, maxResults, results) {
|
|
1163
1215
|
try {
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
ProviderNotFoundError,
|
|
8
8
|
RateLimitError,
|
|
9
9
|
schemaToJsonSchema
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-NLT5FT2W.js";
|
|
11
11
|
import {
|
|
12
12
|
APP_NAME,
|
|
13
13
|
CONFIG_DIR_NAME,
|
|
@@ -2050,7 +2050,7 @@ var ProviderRegistry = class {
|
|
|
2050
2050
|
};
|
|
2051
2051
|
|
|
2052
2052
|
// src/session/session-manager.ts
|
|
2053
|
-
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync, unlinkSync, renameSync } from "fs";
|
|
2053
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync, unlinkSync, renameSync, openSync, readSync, closeSync } from "fs";
|
|
2054
2054
|
import { join as join2 } from "path";
|
|
2055
2055
|
import { v4 as uuidv4 } from "uuid";
|
|
2056
2056
|
|
|
@@ -2256,6 +2256,11 @@ function safeDate(value) {
|
|
|
2256
2256
|
const d = new Date(value);
|
|
2257
2257
|
return isNaN(d.getTime()) ? /* @__PURE__ */ new Date(0) : d;
|
|
2258
2258
|
}
|
|
2259
|
+
function extractJsonField(header, field) {
|
|
2260
|
+
const re = new RegExp(`"${field}"\\s*:\\s*"([^"]*)"`, "i");
|
|
2261
|
+
const m = header.match(re);
|
|
2262
|
+
return m ? m[1] : void 0;
|
|
2263
|
+
}
|
|
2259
2264
|
var SessionManager = class {
|
|
2260
2265
|
constructor(config) {
|
|
2261
2266
|
this.config = config;
|
|
@@ -2300,18 +2305,8 @@ var SessionManager = class {
|
|
|
2300
2305
|
const metas = [];
|
|
2301
2306
|
for (const file of files) {
|
|
2302
2307
|
try {
|
|
2303
|
-
const
|
|
2304
|
-
|
|
2305
|
-
);
|
|
2306
|
-
metas.push({
|
|
2307
|
-
id: data.id,
|
|
2308
|
-
provider: data.provider,
|
|
2309
|
-
model: data.model,
|
|
2310
|
-
messageCount: data.messages?.length ?? 0,
|
|
2311
|
-
created: safeDate(data.created),
|
|
2312
|
-
updated: safeDate(data.updated),
|
|
2313
|
-
title: data.title
|
|
2314
|
-
});
|
|
2308
|
+
const meta = this.readSessionMeta(join2(this.historyDir, file));
|
|
2309
|
+
if (meta) metas.push(meta);
|
|
2315
2310
|
} catch (err) {
|
|
2316
2311
|
process.stderr.write(
|
|
2317
2312
|
`[Warning] Skipping corrupted session file "${file}": ${err instanceof Error ? err.message : String(err)}
|
|
@@ -2321,6 +2316,59 @@ var SessionManager = class {
|
|
|
2321
2316
|
}
|
|
2322
2317
|
return metas.sort((a, b) => b.updated.getTime() - a.updated.getTime());
|
|
2323
2318
|
}
|
|
2319
|
+
/**
|
|
2320
|
+
* P1-B: Read only the first ~1KB of a session file to extract metadata fields.
|
|
2321
|
+
* Session JSON format puts id/provider/model/created/updated/title before the
|
|
2322
|
+
* large "messages" array, so a small header read suffices for metadata extraction.
|
|
2323
|
+
* Falls back to full file read if header parsing fails.
|
|
2324
|
+
*/
|
|
2325
|
+
readSessionMeta(filePath) {
|
|
2326
|
+
const HEADER_SIZE = 1024;
|
|
2327
|
+
let header;
|
|
2328
|
+
try {
|
|
2329
|
+
const fd = openSync(filePath, "r");
|
|
2330
|
+
const buf = Buffer.alloc(HEADER_SIZE);
|
|
2331
|
+
const bytesRead = readSync(fd, buf, 0, HEADER_SIZE, 0);
|
|
2332
|
+
closeSync(fd);
|
|
2333
|
+
header = buf.toString("utf-8", 0, bytesRead);
|
|
2334
|
+
} catch {
|
|
2335
|
+
return null;
|
|
2336
|
+
}
|
|
2337
|
+
const id = extractJsonField(header, "id");
|
|
2338
|
+
const provider = extractJsonField(header, "provider");
|
|
2339
|
+
const model = extractJsonField(header, "model");
|
|
2340
|
+
const created = extractJsonField(header, "created");
|
|
2341
|
+
const updated = extractJsonField(header, "updated");
|
|
2342
|
+
const title = extractJsonField(header, "title");
|
|
2343
|
+
if (id && provider && model) {
|
|
2344
|
+
let messageCount = 0;
|
|
2345
|
+
try {
|
|
2346
|
+
const full = readFileSync2(filePath, "utf-8");
|
|
2347
|
+
const matches = full.match(/"role"\s*:/g);
|
|
2348
|
+
messageCount = matches ? matches.length : 0;
|
|
2349
|
+
} catch {
|
|
2350
|
+
}
|
|
2351
|
+
return {
|
|
2352
|
+
id,
|
|
2353
|
+
provider,
|
|
2354
|
+
model,
|
|
2355
|
+
messageCount,
|
|
2356
|
+
created: safeDate(created),
|
|
2357
|
+
updated: safeDate(updated),
|
|
2358
|
+
title: title || void 0
|
|
2359
|
+
};
|
|
2360
|
+
}
|
|
2361
|
+
const data = JSON.parse(readFileSync2(filePath, "utf-8"));
|
|
2362
|
+
return {
|
|
2363
|
+
id: data.id,
|
|
2364
|
+
provider: data.provider,
|
|
2365
|
+
model: data.model,
|
|
2366
|
+
messageCount: data.messages?.length ?? 0,
|
|
2367
|
+
created: safeDate(data.created),
|
|
2368
|
+
updated: safeDate(data.updated),
|
|
2369
|
+
title: data.title
|
|
2370
|
+
};
|
|
2371
|
+
}
|
|
2324
2372
|
deleteSession(id) {
|
|
2325
2373
|
const filePath = join2(this.historyDir, `${id}.json`);
|
|
2326
2374
|
if (!existsSync2(filePath)) return false;
|
|
@@ -381,7 +381,7 @@ ${content}`);
|
|
|
381
381
|
}
|
|
382
382
|
}
|
|
383
383
|
async function runTaskMode(config, providers, configManager, topic) {
|
|
384
|
-
const { TaskOrchestrator } = await import("./task-orchestrator-
|
|
384
|
+
const { TaskOrchestrator } = await import("./task-orchestrator-FVBUXFLC.js");
|
|
385
385
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
386
386
|
let interrupted = false;
|
|
387
387
|
const onSigint = () => {
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
saveDevState,
|
|
24
24
|
sessionHasMeaningfulContent,
|
|
25
25
|
setupProxy
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-OBFFL5DJ.js";
|
|
27
27
|
import {
|
|
28
28
|
ToolRegistry,
|
|
29
29
|
askUserContext,
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
theme,
|
|
39
39
|
truncateOutput,
|
|
40
40
|
undoStack
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-NLT5FT2W.js";
|
|
42
42
|
import {
|
|
43
43
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
44
44
|
AUTHOR,
|
|
@@ -4170,21 +4170,27 @@ Session '${this.resumeSessionId}' not found.
|
|
|
4170
4170
|
}
|
|
4171
4171
|
if (Object.keys(mergedMcpServers).length > 0) {
|
|
4172
4172
|
this.mcpManager = new McpManager();
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4173
|
+
const mcpProjectCount = Object.keys(projectMcpServers).length;
|
|
4174
|
+
this.mcpManager.connectAll(mergedMcpServers).then(() => {
|
|
4175
|
+
const mcpTools = this.mcpManager.getAllTools();
|
|
4176
|
+
for (const tool of mcpTools) {
|
|
4177
|
+
this.toolRegistry.registerMcpTool(tool);
|
|
4178
|
+
}
|
|
4179
|
+
const connectedCount = this.mcpManager.getConnectedCount();
|
|
4180
|
+
const totalTools = this.mcpManager.getTotalToolCount();
|
|
4181
|
+
if (connectedCount > 0) {
|
|
4182
|
+
const sourceInfo = mcpProjectCount > 0 ? ` (${mcpProjectCount} from .mcp.json)` : "";
|
|
4183
|
+
process.stdout.write(
|
|
4184
|
+
theme.dim(`
|
|
4185
|
+
\u{1F50C} MCP: ${connectedCount} server(s), ${totalTools} tool(s)${sourceInfo}
|
|
4185
4186
|
`)
|
|
4186
|
-
|
|
4187
|
-
|
|
4187
|
+
);
|
|
4188
|
+
this.showPrompt();
|
|
4189
|
+
}
|
|
4190
|
+
}).catch((err) => {
|
|
4191
|
+
process.stderr.write(`[mcp] connectAll error: ${err instanceof Error ? err.message : err}
|
|
4192
|
+
`);
|
|
4193
|
+
});
|
|
4188
4194
|
}
|
|
4189
4195
|
this.setupClipboardPaste();
|
|
4190
4196
|
this.rl.on("SIGINT", () => {
|
|
@@ -5542,7 +5548,7 @@ program.command("web").description("Start Web UI server with browser-based chat
|
|
|
5542
5548
|
console.error("Error: Invalid port number. Must be between 1 and 65535.");
|
|
5543
5549
|
process.exit(1);
|
|
5544
5550
|
}
|
|
5545
|
-
const { startWebServer } = await import("./server-
|
|
5551
|
+
const { startWebServer } = await import("./server-KSH5U7QY.js");
|
|
5546
5552
|
await startWebServer({ port, host: options.host });
|
|
5547
5553
|
});
|
|
5548
5554
|
program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
|
|
@@ -5775,7 +5781,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
|
|
|
5775
5781
|
}),
|
|
5776
5782
|
config.get("customProviders")
|
|
5777
5783
|
);
|
|
5778
|
-
const { startHub } = await import("./hub-
|
|
5784
|
+
const { startHub } = await import("./hub-WF6CNNUT.js");
|
|
5779
5785
|
await startHub(
|
|
5780
5786
|
{
|
|
5781
5787
|
topic: topic ?? "",
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
renderDiff,
|
|
19
19
|
runHook,
|
|
20
20
|
setupProxy
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-OBFFL5DJ.js";
|
|
22
22
|
import {
|
|
23
23
|
AuthManager
|
|
24
24
|
} from "./chunk-BYNY5JPB.js";
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
spawnAgentContext,
|
|
33
33
|
truncateOutput,
|
|
34
34
|
undoStack
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-NLT5FT2W.js";
|
|
36
36
|
import {
|
|
37
37
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
38
38
|
AUTHOR,
|