jinzd-ai-cli 0.4.307 → 0.4.309
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/README.zh-CN.md +1 -1
- package/THIRD_PARTY_NOTICES.md +3 -0
- package/dist/{agent-client-6GX6QQDU.js → agent-client-TIEAYZXV.js} +4 -1
- package/dist/{auth-PE3Z5OHS.js → auth-QTQNZ6IX.js} +2 -2
- package/dist/{batch-HMADXNOD.js → batch-H4WWSZQ3.js} +3 -3
- package/dist/{chat-index-2D5GK2DB.js → chat-index-7CLR4CBG.js} +4 -3
- package/dist/{chat-index-DGUOUUQW.js → chat-index-RLVLQRRC.js} +3 -2
- package/dist/{chunk-CIM2PV2F.js → chunk-2E5W2E64.js} +2 -2
- package/dist/chunk-2XMUCC42.js +67 -0
- package/dist/{chunk-VAV2IJ3R.js → chunk-3CNPJLVI.js} +1 -1
- package/dist/{chunk-KRCYR46A.js → chunk-3GEO2LPO.js} +264 -55
- package/dist/{chunk-OAXLMF3U.js → chunk-3YVNDYOY.js} +1 -1
- package/dist/{chunk-5GQL4TSZ.js → chunk-4BXTGXZ6.js} +2 -2
- package/dist/{chunk-RYQBBEMM.js → chunk-4PR5AVJ5.js} +115 -19
- package/dist/{chunk-GHWZVPUV.js → chunk-6JHACXB3.js} +7 -5
- package/dist/{chunk-IUVDZVZ4.js → chunk-AXTLYOA7.js} +24 -17
- package/dist/{chunk-XJOK5353.js → chunk-B3MPYI4E.js} +2 -2
- package/dist/chunk-BMLQPSHP.js +69 -0
- package/dist/{chunk-NRSYBKWA.js → chunk-C7CKDFJS.js} +1 -1
- package/dist/{chunk-SJFZPS65.js → chunk-EAVX3RLD.js} +1 -1
- package/dist/{chunk-VXEF2SWG.js → chunk-EHMMBIZT.js} +16 -12
- package/dist/chunk-FVXNEZEW.js +161 -0
- package/dist/{chunk-AHL6KOGM.js → chunk-HXINWG37.js} +2 -2
- package/dist/{chunk-3CKJOTVM.js → chunk-IW6Q66WS.js} +4 -4
- package/dist/chunk-JJFJWD35.js +162 -0
- package/dist/{chunk-NYNSYLFY.js → chunk-JL44HGZC.js} +1 -1
- package/dist/{chunk-3TBXHLSC.js → chunk-K4F7QEGW.js} +1 -1
- package/dist/{chunk-NUJTNH76.js → chunk-LBWKMTT3.js} +1 -1
- package/dist/{chunk-YKJO3SI4.js → chunk-LONB36SP.js} +16 -3
- package/dist/{chunk-WQ3OMEC4.js → chunk-M6HLYG33.js} +1 -1
- package/dist/{chunk-I4GQRMFV.js → chunk-M6YV5KSS.js} +6 -4
- package/dist/{chunk-KBDKKHXB.js → chunk-O6CGOVD4.js} +2 -2
- package/dist/{chunk-L2RJPVHV.js → chunk-O7MMYJAD.js} +266 -512
- package/dist/chunk-QMFMST2T.js +39 -0
- package/dist/{chunk-AQF6IXSR.js → chunk-RBCKX2FZ.js} +11 -6
- package/dist/{chunk-4W6VDVQU.js → chunk-RLERORUI.js} +246 -56
- package/dist/{chunk-MI4SFZGX.js → chunk-RMEJR3AW.js} +5 -2
- package/dist/{chunk-UFW4S3RU.js → chunk-RVMCY6DP.js} +1 -1
- package/dist/{chunk-LF67HWWR.js → chunk-RWRZVQCB.js} +1 -1
- package/dist/{chunk-NQJSPMY2.js → chunk-SCG2VBPB.js} +4 -4
- package/dist/chunk-SXIJLSVF.js +41 -0
- package/dist/{chunk-YFDQIUQ3.js → chunk-T42GXE7Y.js} +18 -18
- package/dist/chunk-TDQW2YHK.js +65 -0
- package/dist/{chunk-45UVJXFQ.js → chunk-W2UOVGRC.js} +1 -1
- package/dist/{ci-QD2Q7NWY.js → ci-H6GPHG4T.js} +7 -7
- package/dist/{ci-format-42XIZO5P.js → ci-format-U47GSGYU.js} +2 -2
- package/dist/{constants-5CMEFZQB.js → constants-GYJTB6KI.js} +1 -1
- package/dist/{constants-NMASHFDL.js → constants-SNJR6546.js} +1 -1
- package/dist/doctor-cli-J6LAQ5LU.js +18 -0
- package/dist/electron-server.js +922 -842
- package/dist/file-checkpoint-64A2AXHE.js +7 -0
- package/dist/{file-checkpoint-NKBHGC7L.js → file-checkpoint-VVPUJNCI.js} +2 -1
- package/dist/{hub-ZLF6GMQD.js → hub-G5FMMTVZ.js} +3 -3
- package/dist/{hub-server-CBKCP5VD.js → hub-server-JLC7CNP7.js} +55 -17
- package/dist/index.js +48 -42
- package/dist/{indexer-P3FPRTPJ.js → indexer-GKIWSSRP.js} +3 -3
- package/dist/indexer-VRXDZ74A.js +10 -0
- package/dist/{persist-S77WRVLD.js → persist-ZZXRWFBX.js} +4 -4
- package/dist/{persistent-memory-GJE7HKVK.js → persistent-memory-EXJBXL33.js} +3 -3
- package/dist/{persistent-memory-MBSBTBGY.js → persistent-memory-LEE454DW.js} +3 -3
- package/dist/{pr-SXRW24JG.js → pr-6PUHVJ6K.js} +7 -7
- package/dist/{project-trust-MUG325AW.js → project-trust-6CJB5ZMX.js} +1 -1
- package/dist/{project-trust-NKYHL3VZ.js → project-trust-KGG2BWKC.js} +1 -1
- package/dist/run-tests-2C7MWZBN.js +12 -0
- package/dist/run-tests-33ZVQE3Q.js +13 -0
- package/dist/{semantic-7GM5M4MU.js → semantic-N227CLSC.js} +4 -4
- package/dist/{semantic-QOBAXEQ4.js → semantic-TRQAZSRY.js} +4 -4
- package/dist/{server-GGEO7SA2.js → server-AJH5TBVO.js} +231 -103
- package/dist/{server-MO3EU2XD.js → server-CYAB56O3.js} +16 -14
- package/dist/{store-SIKHCUYJ.js → store-2N6PPPBP.js} +2 -2
- package/dist/{store-CMSSWZF7.js → store-76VVFDXM.js} +2 -2
- package/dist/{task-orchestrator-JGEEQ2OE.js → task-orchestrator-HNRV3YUD.js} +15 -14
- package/dist/{usage-B7RIAPPT.js → usage-ZN5DU6Z7.js} +4 -4
- package/dist/{vector-store-JAXWDZYW.js → vector-store-T2DVUMY4.js} +2 -2
- package/dist/{vector-store-PWIOQFTP.js → vector-store-V6UGEYWK.js} +2 -2
- package/dist/web/client/app.js +7 -0
- package/dist/web/client/app.js.br +0 -0
- package/dist/web/client/app.js.gz +0 -0
- package/dist/web/client/util.js +14 -23
- package/dist/web/client/util.js.br +0 -0
- package/dist/web/client/util.js.gz +0 -0
- package/dist/web/client/vendor/DOMPurify-LICENSE.txt +202 -0
- package/dist/web/client/vendor/purify.es.mjs +2722 -0
- package/dist/web/client/vendor/purify.es.mjs.br +0 -0
- package/dist/web/client/vendor/purify.es.mjs.gz +0 -0
- package/package.json +4 -2
- package/dist/chunk-4BKXL7SM.js +0 -98
- package/dist/chunk-6BUTA5VW.js +0 -38
- package/dist/chunk-IW3Q7AE5.js +0 -40
- package/dist/chunk-SKET65WZ.js +0 -96
- package/dist/doctor-cli-IOVSHBDI.js +0 -18
- package/dist/file-checkpoint-CGH6OJVI.js +0 -6
- package/dist/indexer-FPKY7LCT.js +0 -10
- package/dist/run-tests-EQCAMFQE.js +0 -10
- package/dist/run-tests-V3N7YV3P.js +0 -9
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getExecutionConfigDir,
|
|
3
|
+
scopedState
|
|
4
|
+
} from "./chunk-QMFMST2T.js";
|
|
5
|
+
|
|
6
|
+
// src/security/file-access.ts
|
|
7
|
+
import { existsSync, realpathSync, openSync, readSync, closeSync, statSync } from "fs";
|
|
8
|
+
import { basename, dirname, resolve, join } from "path";
|
|
9
|
+
import { homedir } from "os";
|
|
10
|
+
function canonicalPath(value) {
|
|
11
|
+
let cursor = resolve(value);
|
|
12
|
+
const missing = [];
|
|
13
|
+
while (!existsSync(cursor)) {
|
|
14
|
+
const parent = dirname(cursor);
|
|
15
|
+
if (parent === cursor) throw new Error("Cannot resolve path");
|
|
16
|
+
missing.unshift(basename(cursor));
|
|
17
|
+
cursor = parent;
|
|
18
|
+
}
|
|
19
|
+
return resolve(realpathSync(cursor), ...missing);
|
|
20
|
+
}
|
|
21
|
+
function isCredentialVault(value) {
|
|
22
|
+
const normalize = (p) => process.platform === "win32" ? p.toLowerCase() : p;
|
|
23
|
+
const target = normalize(canonicalPath(value));
|
|
24
|
+
const hostRoot = normalize(canonicalPath(join(homedir(), ".aicli")));
|
|
25
|
+
if (basename(target) === "config.json" && normalize(dirname(dirname(dirname(target)))) === hostRoot && basename(dirname(dirname(target))) === "users") return true;
|
|
26
|
+
return [getExecutionConfigDir(), join(homedir(), ".aicli")].some((root) => ["config.json", "users.json"].some((file) => {
|
|
27
|
+
const vault = canonicalPath(join(root, file));
|
|
28
|
+
if (target === normalize(vault)) return true;
|
|
29
|
+
try {
|
|
30
|
+
const a = statSync(target), b = statSync(vault);
|
|
31
|
+
return a.ino !== 0 && a.dev === b.dev && a.ino === b.ino;
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
function assertReadablePath(value) {
|
|
38
|
+
if (isCredentialVault(value)) throw new Error("[Refused] Credential vault files cannot be read by tools. Use aicli config or an external editor.");
|
|
39
|
+
}
|
|
40
|
+
var MAX_SNAPSHOT_BYTES = 2 * 1024 * 1024;
|
|
41
|
+
var MAX_SNAPSHOT_TOTAL_BYTES = 16 * 1024 * 1024;
|
|
42
|
+
function readSnapshot(value) {
|
|
43
|
+
const fd = openSync(value, "r");
|
|
44
|
+
try {
|
|
45
|
+
const buffer = Buffer.alloc(MAX_SNAPSHOT_BYTES + 1);
|
|
46
|
+
let bytes = 0;
|
|
47
|
+
while (bytes < buffer.length) {
|
|
48
|
+
const n = readSync(fd, buffer, bytes, buffer.length - bytes, null);
|
|
49
|
+
if (!n) break;
|
|
50
|
+
bytes += n;
|
|
51
|
+
}
|
|
52
|
+
if (bytes > MAX_SNAPSHOT_BYTES) throw new Error("File exceeds 2 MiB snapshot limit; edit refused because a complete undo snapshot cannot be kept.");
|
|
53
|
+
return buffer.subarray(0, bytes).toString("utf8");
|
|
54
|
+
} finally {
|
|
55
|
+
closeSync(fd);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/tools/file-checkpoint.ts
|
|
60
|
+
import { existsSync as existsSync2, writeFileSync, unlinkSync } from "fs";
|
|
61
|
+
var MAX_SNAPSHOTS = 200;
|
|
62
|
+
var FileCheckpointStore = class {
|
|
63
|
+
stateKey = /* @__PURE__ */ Symbol("snapshots");
|
|
64
|
+
get snapshots() {
|
|
65
|
+
return scopedState(this.stateKey, () => ({ items: [] })).items;
|
|
66
|
+
}
|
|
67
|
+
set snapshots(items) {
|
|
68
|
+
scopedState(this.stateKey, () => ({ items: [] })).items = items;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 在文件写入前调用,保存当前文件内容。
|
|
72
|
+
* 同一 messageIndex 下同一文件只记录首次快照。
|
|
73
|
+
*/
|
|
74
|
+
snapshot(filePath, messageIndex) {
|
|
75
|
+
const exists = this.snapshots.some(
|
|
76
|
+
(s) => s.filePath === filePath && s.messageIndex === messageIndex
|
|
77
|
+
);
|
|
78
|
+
if (exists) return;
|
|
79
|
+
let content = null;
|
|
80
|
+
if (existsSync2(filePath)) {
|
|
81
|
+
content = readSnapshot(filePath);
|
|
82
|
+
}
|
|
83
|
+
this.snapshots.push({
|
|
84
|
+
filePath,
|
|
85
|
+
content,
|
|
86
|
+
messageIndex,
|
|
87
|
+
timestamp: Date.now()
|
|
88
|
+
});
|
|
89
|
+
while (this.snapshots.length > MAX_SNAPSHOTS || this.snapshots.reduce((n, e) => n + Buffer.byteLength(e.content ?? ""), 0) > MAX_SNAPSHOT_TOTAL_BYTES) {
|
|
90
|
+
this.snapshots.shift();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 恢复所有在指定消息索引之后被修改的文件到该索引时的状态。
|
|
95
|
+
* @returns 恢复和删除的文件数量
|
|
96
|
+
*/
|
|
97
|
+
restoreToMessageIndex(targetIndex) {
|
|
98
|
+
const modifiedAfter = this.snapshots.filter((s) => s.messageIndex > targetIndex);
|
|
99
|
+
const uniqueFiles = [...new Set(modifiedAfter.map((s) => s.filePath))];
|
|
100
|
+
let restored = 0;
|
|
101
|
+
let deleted = 0;
|
|
102
|
+
const files = [];
|
|
103
|
+
for (const filePath of uniqueFiles) {
|
|
104
|
+
const beforeSnapshots = this.snapshots.filter((s) => s.filePath === filePath && s.messageIndex <= targetIndex).sort((a, b) => b.messageIndex - a.messageIndex);
|
|
105
|
+
const restoreTo = beforeSnapshots[0];
|
|
106
|
+
try {
|
|
107
|
+
if (restoreTo) {
|
|
108
|
+
if (restoreTo.content === null) {
|
|
109
|
+
if (existsSync2(filePath)) {
|
|
110
|
+
unlinkSync(filePath);
|
|
111
|
+
deleted++;
|
|
112
|
+
files.push(filePath);
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
writeFileSync(filePath, restoreTo.content, "utf-8");
|
|
116
|
+
restored++;
|
|
117
|
+
files.push(filePath);
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
const earliest = this.snapshots.filter((s) => s.filePath === filePath).sort((a, b) => a.messageIndex - b.messageIndex)[0];
|
|
121
|
+
if (earliest && earliest.content === null) {
|
|
122
|
+
if (existsSync2(filePath)) {
|
|
123
|
+
unlinkSync(filePath);
|
|
124
|
+
deleted++;
|
|
125
|
+
files.push(filePath);
|
|
126
|
+
}
|
|
127
|
+
} else if (earliest) {
|
|
128
|
+
writeFileSync(filePath, earliest.content, "utf-8");
|
|
129
|
+
restored++;
|
|
130
|
+
files.push(filePath);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
} catch {
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
this.snapshots = this.snapshots.filter((s) => s.messageIndex <= targetIndex);
|
|
137
|
+
return { restored, deleted, files };
|
|
138
|
+
}
|
|
139
|
+
/** 获取所有快照(供调试/显示) */
|
|
140
|
+
getSnapshots() {
|
|
141
|
+
return this.snapshots;
|
|
142
|
+
}
|
|
143
|
+
/** 获取有快照的消息索引列表(去重排序) */
|
|
144
|
+
getMessageIndices() {
|
|
145
|
+
return [...new Set(this.snapshots.map((s) => s.messageIndex))].sort((a, b) => a - b);
|
|
146
|
+
}
|
|
147
|
+
/** 清空所有快照(新会话/清除时调用) */
|
|
148
|
+
clear() {
|
|
149
|
+
this.snapshots = [];
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
var fileCheckpoints = new FileCheckpointStore();
|
|
153
|
+
|
|
154
|
+
export {
|
|
155
|
+
canonicalPath,
|
|
156
|
+
isCredentialVault,
|
|
157
|
+
assertReadablePath,
|
|
158
|
+
MAX_SNAPSHOT_TOTAL_BYTES,
|
|
159
|
+
readSnapshot,
|
|
160
|
+
fileCheckpoints
|
|
161
|
+
};
|
|
@@ -8,12 +8,12 @@ import {
|
|
|
8
8
|
} from "./chunk-HOSJZMQS.js";
|
|
9
9
|
import {
|
|
10
10
|
atomicWriteFileSync
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-BMLQPSHP.js";
|
|
12
12
|
import {
|
|
13
13
|
MEMORY_FILE_NAME,
|
|
14
14
|
MEMORY_MAX_CHARS,
|
|
15
15
|
MEMORY_STORE_FILE_NAME
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-3CNPJLVI.js";
|
|
17
17
|
|
|
18
18
|
// src/memory/persistent-memory.ts
|
|
19
19
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
evaluateCiGate,
|
|
4
4
|
normalizeCiThresholds
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-K4F7QEGW.js";
|
|
6
6
|
import {
|
|
7
7
|
buildReviewPrompt,
|
|
8
8
|
buildSecurityReviewPrompt,
|
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
} from "./chunk-6YZEZFX5.js";
|
|
14
14
|
import {
|
|
15
15
|
ProviderRegistry
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-EHMMBIZT.js";
|
|
17
17
|
import {
|
|
18
18
|
ConfigManager
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-RBCKX2FZ.js";
|
|
20
20
|
import {
|
|
21
21
|
VERSION
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-3CNPJLVI.js";
|
|
23
23
|
|
|
24
24
|
// src/cli/ci.ts
|
|
25
25
|
import { execFileSync } from "child_process";
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getExecutionConfigDir,
|
|
4
|
+
scopedState
|
|
5
|
+
} from "./chunk-SXIJLSVF.js";
|
|
6
|
+
|
|
7
|
+
// src/security/file-access.ts
|
|
8
|
+
import { existsSync, realpathSync, openSync, readSync, closeSync, statSync } from "fs";
|
|
9
|
+
import { basename, dirname, resolve, join } from "path";
|
|
10
|
+
import { homedir } from "os";
|
|
11
|
+
function canonicalPath(value) {
|
|
12
|
+
let cursor = resolve(value);
|
|
13
|
+
const missing = [];
|
|
14
|
+
while (!existsSync(cursor)) {
|
|
15
|
+
const parent = dirname(cursor);
|
|
16
|
+
if (parent === cursor) throw new Error("Cannot resolve path");
|
|
17
|
+
missing.unshift(basename(cursor));
|
|
18
|
+
cursor = parent;
|
|
19
|
+
}
|
|
20
|
+
return resolve(realpathSync(cursor), ...missing);
|
|
21
|
+
}
|
|
22
|
+
function isCredentialVault(value) {
|
|
23
|
+
const normalize = (p) => process.platform === "win32" ? p.toLowerCase() : p;
|
|
24
|
+
const target = normalize(canonicalPath(value));
|
|
25
|
+
const hostRoot = normalize(canonicalPath(join(homedir(), ".aicli")));
|
|
26
|
+
if (basename(target) === "config.json" && normalize(dirname(dirname(dirname(target)))) === hostRoot && basename(dirname(dirname(target))) === "users") return true;
|
|
27
|
+
return [getExecutionConfigDir(), join(homedir(), ".aicli")].some((root) => ["config.json", "users.json"].some((file) => {
|
|
28
|
+
const vault = canonicalPath(join(root, file));
|
|
29
|
+
if (target === normalize(vault)) return true;
|
|
30
|
+
try {
|
|
31
|
+
const a = statSync(target), b = statSync(vault);
|
|
32
|
+
return a.ino !== 0 && a.dev === b.dev && a.ino === b.ino;
|
|
33
|
+
} catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
function assertReadablePath(value) {
|
|
39
|
+
if (isCredentialVault(value)) throw new Error("[Refused] Credential vault files cannot be read by tools. Use aicli config or an external editor.");
|
|
40
|
+
}
|
|
41
|
+
var MAX_SNAPSHOT_BYTES = 2 * 1024 * 1024;
|
|
42
|
+
var MAX_SNAPSHOT_TOTAL_BYTES = 16 * 1024 * 1024;
|
|
43
|
+
function readSnapshot(value) {
|
|
44
|
+
const fd = openSync(value, "r");
|
|
45
|
+
try {
|
|
46
|
+
const buffer = Buffer.alloc(MAX_SNAPSHOT_BYTES + 1);
|
|
47
|
+
let bytes = 0;
|
|
48
|
+
while (bytes < buffer.length) {
|
|
49
|
+
const n = readSync(fd, buffer, bytes, buffer.length - bytes, null);
|
|
50
|
+
if (!n) break;
|
|
51
|
+
bytes += n;
|
|
52
|
+
}
|
|
53
|
+
if (bytes > MAX_SNAPSHOT_BYTES) throw new Error("File exceeds 2 MiB snapshot limit; edit refused because a complete undo snapshot cannot be kept.");
|
|
54
|
+
return buffer.subarray(0, bytes).toString("utf8");
|
|
55
|
+
} finally {
|
|
56
|
+
closeSync(fd);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/tools/file-checkpoint.ts
|
|
61
|
+
import { existsSync as existsSync2, writeFileSync, unlinkSync } from "fs";
|
|
62
|
+
var MAX_SNAPSHOTS = 200;
|
|
63
|
+
var FileCheckpointStore = class {
|
|
64
|
+
stateKey = /* @__PURE__ */ Symbol("snapshots");
|
|
65
|
+
get snapshots() {
|
|
66
|
+
return scopedState(this.stateKey, () => ({ items: [] })).items;
|
|
67
|
+
}
|
|
68
|
+
set snapshots(items) {
|
|
69
|
+
scopedState(this.stateKey, () => ({ items: [] })).items = items;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 在文件写入前调用,保存当前文件内容。
|
|
73
|
+
* 同一 messageIndex 下同一文件只记录首次快照。
|
|
74
|
+
*/
|
|
75
|
+
snapshot(filePath, messageIndex) {
|
|
76
|
+
const exists = this.snapshots.some(
|
|
77
|
+
(s) => s.filePath === filePath && s.messageIndex === messageIndex
|
|
78
|
+
);
|
|
79
|
+
if (exists) return;
|
|
80
|
+
let content = null;
|
|
81
|
+
if (existsSync2(filePath)) {
|
|
82
|
+
content = readSnapshot(filePath);
|
|
83
|
+
}
|
|
84
|
+
this.snapshots.push({
|
|
85
|
+
filePath,
|
|
86
|
+
content,
|
|
87
|
+
messageIndex,
|
|
88
|
+
timestamp: Date.now()
|
|
89
|
+
});
|
|
90
|
+
while (this.snapshots.length > MAX_SNAPSHOTS || this.snapshots.reduce((n, e) => n + Buffer.byteLength(e.content ?? ""), 0) > MAX_SNAPSHOT_TOTAL_BYTES) {
|
|
91
|
+
this.snapshots.shift();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 恢复所有在指定消息索引之后被修改的文件到该索引时的状态。
|
|
96
|
+
* @returns 恢复和删除的文件数量
|
|
97
|
+
*/
|
|
98
|
+
restoreToMessageIndex(targetIndex) {
|
|
99
|
+
const modifiedAfter = this.snapshots.filter((s) => s.messageIndex > targetIndex);
|
|
100
|
+
const uniqueFiles = [...new Set(modifiedAfter.map((s) => s.filePath))];
|
|
101
|
+
let restored = 0;
|
|
102
|
+
let deleted = 0;
|
|
103
|
+
const files = [];
|
|
104
|
+
for (const filePath of uniqueFiles) {
|
|
105
|
+
const beforeSnapshots = this.snapshots.filter((s) => s.filePath === filePath && s.messageIndex <= targetIndex).sort((a, b) => b.messageIndex - a.messageIndex);
|
|
106
|
+
const restoreTo = beforeSnapshots[0];
|
|
107
|
+
try {
|
|
108
|
+
if (restoreTo) {
|
|
109
|
+
if (restoreTo.content === null) {
|
|
110
|
+
if (existsSync2(filePath)) {
|
|
111
|
+
unlinkSync(filePath);
|
|
112
|
+
deleted++;
|
|
113
|
+
files.push(filePath);
|
|
114
|
+
}
|
|
115
|
+
} else {
|
|
116
|
+
writeFileSync(filePath, restoreTo.content, "utf-8");
|
|
117
|
+
restored++;
|
|
118
|
+
files.push(filePath);
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
const earliest = this.snapshots.filter((s) => s.filePath === filePath).sort((a, b) => a.messageIndex - b.messageIndex)[0];
|
|
122
|
+
if (earliest && earliest.content === null) {
|
|
123
|
+
if (existsSync2(filePath)) {
|
|
124
|
+
unlinkSync(filePath);
|
|
125
|
+
deleted++;
|
|
126
|
+
files.push(filePath);
|
|
127
|
+
}
|
|
128
|
+
} else if (earliest) {
|
|
129
|
+
writeFileSync(filePath, earliest.content, "utf-8");
|
|
130
|
+
restored++;
|
|
131
|
+
files.push(filePath);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
} catch {
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
this.snapshots = this.snapshots.filter((s) => s.messageIndex <= targetIndex);
|
|
138
|
+
return { restored, deleted, files };
|
|
139
|
+
}
|
|
140
|
+
/** 获取所有快照(供调试/显示) */
|
|
141
|
+
getSnapshots() {
|
|
142
|
+
return this.snapshots;
|
|
143
|
+
}
|
|
144
|
+
/** 获取有快照的消息索引列表(去重排序) */
|
|
145
|
+
getMessageIndices() {
|
|
146
|
+
return [...new Set(this.snapshots.map((s) => s.messageIndex))].sort((a, b) => a - b);
|
|
147
|
+
}
|
|
148
|
+
/** 清空所有快照(新会话/清除时调用) */
|
|
149
|
+
clear() {
|
|
150
|
+
this.snapshots = [];
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
var fileCheckpoints = new FileCheckpointStore();
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
canonicalPath,
|
|
157
|
+
isCredentialVault,
|
|
158
|
+
assertReadablePath,
|
|
159
|
+
MAX_SNAPSHOT_TOTAL_BYTES,
|
|
160
|
+
readSnapshot,
|
|
161
|
+
fileCheckpoints
|
|
162
|
+
};
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-RS7SKYTS.js";
|
|
5
5
|
import {
|
|
6
6
|
atomicWriteFileSync
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BMLQPSHP.js";
|
|
8
8
|
|
|
9
9
|
// src/core/pricing.ts
|
|
10
10
|
var CNY_PER_USD = 6.9;
|
|
@@ -16,15 +16,28 @@ function deepSeekCnyPricing(cacheRead, input, output) {
|
|
|
16
16
|
output: output / CNY_PER_USD
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
+
var DEEPSEEK_V4_PRO_ROUTED_TO_FLASH_AT = /* @__PURE__ */ new Date("2026-09-14T04:00:00.000Z");
|
|
20
|
+
var DEEPSEEK_V41_FLASH_ROUTING_CONFIRMED_AT = /* @__PURE__ */ new Date("2026-09-11T00:00:00.000Z");
|
|
21
|
+
function isDeepSeekPeakHour(at) {
|
|
22
|
+
const weekday = at.getUTCDay();
|
|
23
|
+
if (weekday === 0 || weekday === 6) return false;
|
|
24
|
+
const hour = at.getUTCHours();
|
|
25
|
+
return hour >= 1 && hour < 4 || hour >= 6 && hour < 10;
|
|
26
|
+
}
|
|
27
|
+
function deepSeekFlash41Pricing(at) {
|
|
28
|
+
return isDeepSeekPeakHour(at) ? { cacheRead: 6e-3, input: 0.3, output: 1.2 } : { cacheRead: 3e-3, input: 0.15, output: 0.6 };
|
|
29
|
+
}
|
|
19
30
|
function getDeepSeekV4Pricing(model, at) {
|
|
31
|
+
if (model.startsWith("deepseek-flash")) return deepSeekFlash41Pricing(at);
|
|
20
32
|
const isPro = model.startsWith("deepseek-v4-pro");
|
|
21
33
|
const isFlash = model.startsWith("deepseek-v4-flash");
|
|
22
34
|
if (!isPro && !isFlash) return null;
|
|
35
|
+
if (isPro && at >= DEEPSEEK_V4_PRO_ROUTED_TO_FLASH_AT) return deepSeekFlash41Pricing(at);
|
|
36
|
+
if (isFlash && at >= DEEPSEEK_V41_FLASH_ROUTING_CONFIRMED_AT) return deepSeekFlash41Pricing(at);
|
|
23
37
|
if (at < DEEPSEEK_TIME_PRICING_EFFECTIVE_AT) {
|
|
24
38
|
return isPro ? deepSeekCnyPricing(0.025, 3, 6) : deepSeekCnyPricing(0.02, 1, 2);
|
|
25
39
|
}
|
|
26
|
-
const
|
|
27
|
-
const isPeak = beijingHour >= 9 && beijingHour < 12 || beijingHour >= 14 && beijingHour < 18;
|
|
40
|
+
const isPeak = isDeepSeekPeakHour(at);
|
|
28
41
|
if (isPro) {
|
|
29
42
|
return isPeak ? deepSeekCnyPricing(0.3, 9, 27) : deepSeekCnyPricing(0.15, 4.5, 13.5);
|
|
30
43
|
}
|
|
@@ -8,12 +8,14 @@ import {
|
|
|
8
8
|
} from "./chunk-FSC6KEWU.js";
|
|
9
9
|
import {
|
|
10
10
|
atomicWriteFileSync
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-2XMUCC42.js";
|
|
12
|
+
import {
|
|
13
|
+
getExecutionConfigDir
|
|
14
|
+
} from "./chunk-QMFMST2T.js";
|
|
12
15
|
|
|
13
16
|
// src/memory/chat-index.ts
|
|
14
17
|
import fs from "fs";
|
|
15
18
|
import path from "path";
|
|
16
|
-
import os from "os";
|
|
17
19
|
import crypto from "crypto";
|
|
18
20
|
|
|
19
21
|
// src/session/session-index.ts
|
|
@@ -311,7 +313,7 @@ var VEC_MAGIC = 1094929750;
|
|
|
311
313
|
var VEC_VERSION = 1;
|
|
312
314
|
var VEC_HEADER_BYTES = 16;
|
|
313
315
|
function memoryIndexDir() {
|
|
314
|
-
return path.join(
|
|
316
|
+
return path.join(getExecutionConfigDir(), MEMORY_DIR_NAME);
|
|
315
317
|
}
|
|
316
318
|
function chunksPath() {
|
|
317
319
|
return path.join(memoryIndexDir(), CHUNKS_FILE);
|
|
@@ -320,7 +322,7 @@ function vectorsPath() {
|
|
|
320
322
|
return path.join(memoryIndexDir(), VECTORS_FILE);
|
|
321
323
|
}
|
|
322
324
|
function historyDir() {
|
|
323
|
-
return path.join(
|
|
325
|
+
return path.join(getExecutionConfigDir(), "history");
|
|
324
326
|
}
|
|
325
327
|
var MAX_CHUNK_CHARS = 1200;
|
|
326
328
|
var MIN_CHUNK_CHARS = 40;
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
loadVectorStore,
|
|
3
3
|
saveVectorStore,
|
|
4
4
|
searchVectorStore
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-3YVNDYOY.js";
|
|
6
6
|
import {
|
|
7
7
|
EMBEDDING_DIM,
|
|
8
8
|
embed,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
loadIndex,
|
|
13
13
|
symbolFingerprint
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-W2UOVGRC.js";
|
|
15
15
|
|
|
16
16
|
// src/symbols/semantic.ts
|
|
17
17
|
function pathTokens(absFile, root) {
|