jinzd-ai-cli 0.4.233 → 0.4.235

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 (37) hide show
  1. package/dist/{auth-FSTAKSYF.js → auth-PE3Z5OHS.js} +1 -1
  2. package/dist/{batch-WWNPYQ6G.js → batch-Y7MHXVR7.js} +2 -2
  3. package/dist/{chat-index-O56HDGFI.js → chat-index-7HXBWQFH.js} +2 -2
  4. package/dist/{chat-index-WSI7ULRQ.js → chat-index-WYXYD7YP.js} +1 -1
  5. package/dist/{chunk-4KM53GLG.js → chunk-2QQKS56X.js} +1 -1
  6. package/dist/{chunk-NVUCDUXE.js → chunk-5MYPIQ3Y.js} +11 -5
  7. package/dist/{chunk-NXYXFRPA.js → chunk-7D5EJBHO.js} +3 -3
  8. package/dist/{chunk-5PKNKJYP.js → chunk-BFTTW5LS.js} +1 -1
  9. package/dist/{chunk-FQSAK75P.js → chunk-CDOQNIVV.js} +3 -3
  10. package/dist/{chunk-7KS3RGZ7.js → chunk-DHNYGJYB.js} +2 -2
  11. package/dist/{chunk-HX67JAK6.js → chunk-FYJGVFXL.js} +87 -54
  12. package/dist/{chunk-ACTO5C6K.js → chunk-GDXKFWFL.js} +1 -1
  13. package/dist/{chunk-EZGZOK6E.js → chunk-GFDRC2JZ.js} +1 -1
  14. package/dist/{chunk-4OAV7QMB.js → chunk-HHYMSEWS.js} +1 -1
  15. package/dist/{chunk-ZWU7FWHO.js → chunk-JMP3LJC2.js} +38 -91
  16. package/dist/chunk-KCEO2XJ4.js +420 -0
  17. package/dist/{chunk-M4FW2NPU.js → chunk-Q5GVANMH.js} +1 -1
  18. package/dist/{chunk-JVKAL5Q3.js → chunk-RYQBBEMM.js} +33 -3
  19. package/dist/{chunk-LF3OUJHK.js → chunk-UO3XWZFE.js} +302 -4
  20. package/dist/{chunk-TJK7AU65.js → chunk-WXFQ6LYN.js} +1 -1
  21. package/dist/{ci-V5V3JSJC.js → ci-OAFNH3MA.js} +4 -4
  22. package/dist/{ci-format-XS7LKBO5.js → ci-format-4LSXJNND.js} +2 -2
  23. package/dist/{constants-UROQJXLY.js → constants-ERIAS7GV.js} +1 -1
  24. package/dist/{doctor-cli-BY3FIV2B.js → doctor-cli-VFSVWZU6.js} +4 -4
  25. package/dist/electron-server.js +235 -224
  26. package/dist/{hub-L2QCRI5M.js → hub-X4EUYRIN.js} +2 -2
  27. package/dist/index.js +23 -23
  28. package/dist/{persist-I3JI27OK.js → persist-AMH5SQ4W.js} +3 -3
  29. package/dist/{pr-IJRUPR5C.js → pr-2CZN5JLE.js} +4 -4
  30. package/dist/{run-tests-FLCVJ6TK.js → run-tests-DXRJDPFF.js} +2 -2
  31. package/dist/{run-tests-NNXBS4EL.js → run-tests-YSRET52H.js} +1 -1
  32. package/dist/{server-W2X3C6GJ.js → server-5ZAXMKRI.js} +21 -20
  33. package/dist/{server-E6LZB72O.js → server-FGJGXHZD.js} +6 -6
  34. package/dist/{task-orchestrator-W55VKYTC.js → task-orchestrator-QMERCD77.js} +6 -6
  35. package/dist/{usage-MZCDTJWB.js → usage-633DUDNT.js} +2 -2
  36. package/package.json +2 -4
  37. package/dist/chunk-B5TYJO7V.js +0 -123
@@ -128,6 +128,293 @@ function scanString(input, options) {
128
128
  return hits;
129
129
  }
130
130
 
131
+ // src/session/session-index.ts
132
+ import { existsSync, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
133
+ import { join } from "path";
134
+
135
+ // src/session/session-meta.ts
136
+ import { readFileSync, openSync, readSync, closeSync } from "fs";
137
+ function safeDate(value) {
138
+ const d = new Date(value);
139
+ return isNaN(d.getTime()) ? /* @__PURE__ */ new Date(0) : d;
140
+ }
141
+ function extractJsonField(header, field) {
142
+ const re = new RegExp(`"${field}"\\s*:\\s*"([^"]*)"`, "i");
143
+ const m = header.match(re);
144
+ return m ? m[1] : void 0;
145
+ }
146
+ function extractJsonNumberField(header, field) {
147
+ const m = header.match(new RegExp(`"${field}"\\s*:\\s*(\\d+)`));
148
+ return m ? Number(m[1]) : void 0;
149
+ }
150
+ function readSessionMeta(filePath) {
151
+ const HEADER_SIZE = 1024;
152
+ let header;
153
+ try {
154
+ const fd = openSync(filePath, "r");
155
+ const buf = Buffer.alloc(HEADER_SIZE);
156
+ const bytesRead = readSync(fd, buf, 0, HEADER_SIZE, 0);
157
+ closeSync(fd);
158
+ header = buf.toString("utf-8", 0, bytesRead);
159
+ } catch {
160
+ return null;
161
+ }
162
+ const id = extractJsonField(header, "id");
163
+ const provider = extractJsonField(header, "provider");
164
+ const model = extractJsonField(header, "model");
165
+ const created = extractJsonField(header, "created");
166
+ const updated = extractJsonField(header, "updated");
167
+ const title = extractJsonField(header, "title");
168
+ if (id && provider && model) {
169
+ let messageCount = extractJsonNumberField(header, "messageCount");
170
+ if (messageCount === void 0) {
171
+ messageCount = 0;
172
+ try {
173
+ const full = readFileSync(filePath, "utf-8");
174
+ const matches = full.match(/"role"\s*:/g);
175
+ messageCount = matches ? matches.length : 0;
176
+ } catch {
177
+ }
178
+ }
179
+ let branchCount;
180
+ let activeBranch;
181
+ try {
182
+ const brMatch = header.match(/"branches"\s*:\s*\[/);
183
+ if (brMatch) {
184
+ const parentMatches = header.match(/"parentBranchId"/g);
185
+ branchCount = parentMatches ? parentMatches.length + 1 : 1;
186
+ }
187
+ activeBranch = extractJsonField(header, "activeBranchId");
188
+ } catch {
189
+ }
190
+ return {
191
+ id,
192
+ provider,
193
+ model,
194
+ messageCount,
195
+ created: safeDate(created),
196
+ updated: safeDate(updated),
197
+ title: title || void 0,
198
+ branchCount,
199
+ activeBranch
200
+ };
201
+ }
202
+ const data = JSON.parse(readFileSync(filePath, "utf-8"));
203
+ return {
204
+ id: data.id,
205
+ provider: data.provider,
206
+ model: data.model,
207
+ messageCount: data.messages?.length ?? 0,
208
+ created: safeDate(data.created),
209
+ updated: safeDate(data.updated),
210
+ title: data.title,
211
+ branchCount: data.branches?.length ?? 1,
212
+ activeBranch: data.activeBranchId
213
+ };
214
+ }
215
+
216
+ // src/session/session-index.ts
217
+ var INDEX_FILE = "sessions.index.json";
218
+ function indexFilePath(historyDir2) {
219
+ return join(historyDir2, INDEX_FILE);
220
+ }
221
+ function loadIndex(historyDir2) {
222
+ const fp = indexFilePath(historyDir2);
223
+ if (!existsSync(fp)) return null;
224
+ try {
225
+ const data = JSON.parse(readFileSync2(fp, "utf-8"));
226
+ if (data?.version === 1 && data.sessions && data.invertedIndex) {
227
+ return data;
228
+ }
229
+ return null;
230
+ } catch {
231
+ return null;
232
+ }
233
+ }
234
+ function saveIndex(historyDir2, idx) {
235
+ idx.built = (/* @__PURE__ */ new Date()).toISOString();
236
+ const fp = indexFilePath(historyDir2);
237
+ atomicWriteFileSync(fp, JSON.stringify(idx));
238
+ }
239
+ function rebuildIndex(historyDir2) {
240
+ if (!existsSync(historyDir2)) {
241
+ const empty = { version: 1, built: (/* @__PURE__ */ new Date()).toISOString(), sessions: {}, invertedIndex: {} };
242
+ return empty;
243
+ }
244
+ const files = readdirSync(historyDir2).filter((f) => f.endsWith(".json"));
245
+ const sessions = {};
246
+ const invertedIndex = /* @__PURE__ */ new Map();
247
+ for (const file of files) {
248
+ const filePath = join(historyDir2, file);
249
+ const meta = readSessionMeta(filePath);
250
+ if (!meta) continue;
251
+ let fileSize = 0;
252
+ try {
253
+ fileSize = statSync(filePath).size;
254
+ } catch {
255
+ }
256
+ let mtimeMs = 0;
257
+ try {
258
+ mtimeMs = statSync(filePath).mtimeMs;
259
+ } catch {
260
+ }
261
+ const entry = {
262
+ id: meta.id,
263
+ provider: meta.provider,
264
+ model: meta.model,
265
+ title: meta.title,
266
+ messageCount: meta.messageCount,
267
+ fileSize,
268
+ created: meta.created.toISOString(),
269
+ updated: meta.updated.toISOString(),
270
+ branchCount: meta.branchCount,
271
+ activeBranch: meta.activeBranch,
272
+ _mtimeMs: mtimeMs
273
+ };
274
+ sessions[meta.id] = entry;
275
+ addTokensToIndex(invertedIndex, meta.title ?? "", meta.id);
276
+ }
277
+ const serializedIndex = {};
278
+ for (const [token, ids] of invertedIndex) {
279
+ serializedIndex[token] = [...ids];
280
+ }
281
+ const idx = {
282
+ version: 1,
283
+ built: (/* @__PURE__ */ new Date()).toISOString(),
284
+ sessions,
285
+ invertedIndex: serializedIndex
286
+ };
287
+ saveIndex(historyDir2, idx);
288
+ return idx;
289
+ }
290
+ function updateSessionInIndex(historyDir2, meta, filePath) {
291
+ let idx = loadIndex(historyDir2);
292
+ if (!idx) {
293
+ rebuildIndex(historyDir2);
294
+ return;
295
+ }
296
+ let fileSize = 0;
297
+ try {
298
+ fileSize = statSync(filePath).size;
299
+ } catch {
300
+ }
301
+ let mtimeMs = 0;
302
+ try {
303
+ mtimeMs = statSync(filePath).mtimeMs;
304
+ } catch {
305
+ }
306
+ const id = meta.id;
307
+ for (const [token, ids] of Object.entries(idx.invertedIndex)) {
308
+ const filtered = ids.filter((sid) => sid !== id);
309
+ if (filtered.length === 0) {
310
+ delete idx.invertedIndex[token];
311
+ } else {
312
+ idx.invertedIndex[token] = filtered;
313
+ }
314
+ }
315
+ idx.sessions[id] = {
316
+ id,
317
+ provider: meta.provider,
318
+ model: meta.model,
319
+ title: meta.title,
320
+ messageCount: meta.messageCount,
321
+ fileSize,
322
+ created: meta.created.toISOString(),
323
+ updated: meta.updated.toISOString(),
324
+ _mtimeMs: mtimeMs
325
+ };
326
+ const tokens = tokenize(meta.title ?? "");
327
+ for (const token of tokens) {
328
+ const existing = idx.invertedIndex[token] ?? [];
329
+ if (!existing.includes(id)) {
330
+ existing.push(id);
331
+ idx.invertedIndex[token] = existing;
332
+ }
333
+ }
334
+ saveIndex(historyDir2, idx);
335
+ }
336
+ function removeSessionFromIndex(historyDir2, id) {
337
+ const idx = loadIndex(historyDir2);
338
+ if (!idx) return;
339
+ delete idx.sessions[id];
340
+ for (const [token, ids] of Object.entries(idx.invertedIndex)) {
341
+ const filtered = ids.filter((sid) => sid !== id);
342
+ if (filtered.length === 0) {
343
+ delete idx.invertedIndex[token];
344
+ } else {
345
+ idx.invertedIndex[token] = filtered;
346
+ }
347
+ }
348
+ saveIndex(historyDir2, idx);
349
+ }
350
+ function listFromIndex(historyDir2, opts) {
351
+ let idx = loadIndex(historyDir2);
352
+ if (!idx) {
353
+ idx = rebuildIndex(historyDir2);
354
+ }
355
+ return Object.values(idx.sessions).map((entry) => ({
356
+ id: entry.id,
357
+ provider: entry.provider,
358
+ model: entry.model,
359
+ title: entry.title,
360
+ messageCount: entry.messageCount,
361
+ created: new Date(entry.created),
362
+ updated: new Date(entry.updated),
363
+ fileSize: opts?.includeFileSize ? entry.fileSize : void 0,
364
+ branchCount: entry.branchCount,
365
+ activeBranch: entry.activeBranch
366
+ })).sort((a, b) => b.updated.getTime() - a.updated.getTime());
367
+ }
368
+ function searchCandidates(historyDir2, query) {
369
+ const idx = loadIndex(historyDir2);
370
+ if (!idx) return null;
371
+ const queryTokens = tokenize(query.toLowerCase());
372
+ if (queryTokens.length === 0) return null;
373
+ const scoreMap = /* @__PURE__ */ new Map();
374
+ for (const token of queryTokens) {
375
+ const matchingIds = idx.invertedIndex[token];
376
+ if (!matchingIds) continue;
377
+ for (const sid of matchingIds) {
378
+ scoreMap.set(sid, (scoreMap.get(sid) ?? 0) + 1);
379
+ }
380
+ }
381
+ const candidates = [...scoreMap.entries()].filter(([, score]) => score > 0).sort((a, b) => {
382
+ const scoreDiff = b[1] - a[1];
383
+ if (scoreDiff !== 0) return scoreDiff;
384
+ const aMeta = idx.sessions[a[0]];
385
+ const bMeta = idx.sessions[b[0]];
386
+ return (bMeta?.updated ?? "").localeCompare(aMeta?.updated ?? "");
387
+ }).map(([sid]) => sid);
388
+ return candidates.length > 0 ? candidates : null;
389
+ }
390
+ function getIndexMtimeMap(historyDir2) {
391
+ const idx = loadIndex(historyDir2);
392
+ if (!idx) return null;
393
+ const map = {};
394
+ for (const entry of Object.values(idx.sessions)) {
395
+ map[entry.id] = entry._mtimeMs;
396
+ }
397
+ return map;
398
+ }
399
+ function addTokensToIndex(invertedIndex, text, sessionId) {
400
+ for (const token of tokenize(text)) {
401
+ const s = invertedIndex.get(token) ?? /* @__PURE__ */ new Set();
402
+ s.add(sessionId);
403
+ invertedIndex.set(token, s);
404
+ }
405
+ }
406
+ function tokenize(text) {
407
+ const tokens = /* @__PURE__ */ new Set();
408
+ const cjkOnly = text.replace(/[^\u4e00-\u9fff\u3400-\u4dbf]/g, "");
409
+ for (let i = 0; i < cjkOnly.length - 1; i++) {
410
+ tokens.add(cjkOnly.slice(i, i + 2));
411
+ }
412
+ const english = text.replace(/[\u4e00-\u9fff\u3400-\u4dbf]/g, " ").toLowerCase();
413
+ const words = english.split(/[^a-z0-9]+/).filter((w) => w.length >= 2);
414
+ for (const w of words) tokens.add(w);
415
+ return [...tokens];
416
+ }
417
+
131
418
  // src/memory/chat-index.ts
132
419
  var MEMORY_DIR_NAME = "memory-index";
133
420
  var CHUNKS_FILE = "chunks.json";
@@ -285,14 +572,19 @@ function listSessionFiles() {
285
572
  const dir = historyDir();
286
573
  if (!fs.existsSync(dir)) return [];
287
574
  const out = [];
575
+ const indexMtimes = getIndexMtimeMap(dir);
288
576
  for (const name of fs.readdirSync(dir)) {
289
577
  if (!name.endsWith(".json")) continue;
290
578
  const id = name.replace(/\.json$/, "");
291
579
  const p = path.join(dir, name);
292
- try {
293
- const st = fs.statSync(p);
294
- out.push({ id, path: p, mtime: st.mtimeMs });
295
- } catch {
580
+ if (indexMtimes && indexMtimes[id] !== void 0) {
581
+ out.push({ id, path: p, mtime: indexMtimes[id] });
582
+ } else {
583
+ try {
584
+ const st = fs.statSync(p);
585
+ out.push({ id, path: p, mtime: st.mtimeMs });
586
+ } catch {
587
+ }
296
588
  }
297
589
  }
298
590
  return out;
@@ -461,6 +753,12 @@ export {
461
753
  redactString,
462
754
  redactJson,
463
755
  scanString,
756
+ safeDate,
757
+ readSessionMeta,
758
+ updateSessionInIndex,
759
+ removeSessionFromIndex,
760
+ listFromIndex,
761
+ searchCandidates,
464
762
  chunkSession,
465
763
  loadChatIndex,
466
764
  clearChatIndex,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  VERSION
4
- } from "./chunk-ACTO5C6K.js";
4
+ } from "./chunk-GDXKFWFL.js";
5
5
 
6
6
  // src/cli/ci-format.ts
7
7
  var DEFAULT_CI_THRESHOLDS = {
@@ -3,14 +3,14 @@ import {
3
3
  CI_COMMENT_MARKER,
4
4
  countSeverity,
5
5
  runCi
6
- } from "./chunk-FQSAK75P.js";
7
- import "./chunk-TJK7AU65.js";
6
+ } from "./chunk-CDOQNIVV.js";
7
+ import "./chunk-WXFQ6LYN.js";
8
8
  import "./chunk-HLWUDRBO.js";
9
9
  import "./chunk-QYQI7ZWK.js";
10
10
  import "./chunk-O3XSFPYH.js";
11
- import "./chunk-5PKNKJYP.js";
11
+ import "./chunk-BFTTW5LS.js";
12
12
  import "./chunk-5ULLIOVC.js";
13
- import "./chunk-ACTO5C6K.js";
13
+ import "./chunk-GDXKFWFL.js";
14
14
  import "./chunk-IW3Q7AE5.js";
15
15
  export {
16
16
  CI_COMMENT_MARKER,
@@ -6,8 +6,8 @@ import {
6
6
  formatCiResult,
7
7
  formatCiSarif,
8
8
  normalizeCiThresholds
9
- } from "./chunk-TJK7AU65.js";
10
- import "./chunk-ACTO5C6K.js";
9
+ } from "./chunk-WXFQ6LYN.js";
10
+ import "./chunk-GDXKFWFL.js";
11
11
  export {
12
12
  DEFAULT_CI_THRESHOLDS,
13
13
  detectCiGateSignals,
@@ -38,7 +38,7 @@ import {
38
38
  TEST_TIMEOUT,
39
39
  VERSION,
40
40
  buildUserIdentityPrompt
41
- } from "./chunk-ACTO5C6K.js";
41
+ } from "./chunk-GDXKFWFL.js";
42
42
  export {
43
43
  AGENTIC_BEHAVIOR_GUIDELINE,
44
44
  APP_NAME,
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  formatDoctorReport,
4
4
  runDoctorCli
5
- } from "./chunk-NXYXFRPA.js";
5
+ } from "./chunk-7D5EJBHO.js";
6
6
  import "./chunk-QYQI7ZWK.js";
7
- import "./chunk-EZGZOK6E.js";
7
+ import "./chunk-GFDRC2JZ.js";
8
8
  import "./chunk-O3XSFPYH.js";
9
- import "./chunk-5PKNKJYP.js";
9
+ import "./chunk-BFTTW5LS.js";
10
10
  import "./chunk-5ULLIOVC.js";
11
11
  import "./chunk-HOSJZMQS.js";
12
- import "./chunk-ACTO5C6K.js";
12
+ import "./chunk-GDXKFWFL.js";
13
13
  import "./chunk-IW3Q7AE5.js";
14
14
  export {
15
15
  formatDoctorReport,