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.
Files changed (96) hide show
  1. package/README.md +2 -1
  2. package/README.zh-CN.md +1 -1
  3. package/THIRD_PARTY_NOTICES.md +3 -0
  4. package/dist/{agent-client-6GX6QQDU.js → agent-client-TIEAYZXV.js} +4 -1
  5. package/dist/{auth-PE3Z5OHS.js → auth-QTQNZ6IX.js} +2 -2
  6. package/dist/{batch-HMADXNOD.js → batch-H4WWSZQ3.js} +3 -3
  7. package/dist/{chat-index-2D5GK2DB.js → chat-index-7CLR4CBG.js} +4 -3
  8. package/dist/{chat-index-DGUOUUQW.js → chat-index-RLVLQRRC.js} +3 -2
  9. package/dist/{chunk-CIM2PV2F.js → chunk-2E5W2E64.js} +2 -2
  10. package/dist/chunk-2XMUCC42.js +67 -0
  11. package/dist/{chunk-VAV2IJ3R.js → chunk-3CNPJLVI.js} +1 -1
  12. package/dist/{chunk-KRCYR46A.js → chunk-3GEO2LPO.js} +264 -55
  13. package/dist/{chunk-OAXLMF3U.js → chunk-3YVNDYOY.js} +1 -1
  14. package/dist/{chunk-5GQL4TSZ.js → chunk-4BXTGXZ6.js} +2 -2
  15. package/dist/{chunk-RYQBBEMM.js → chunk-4PR5AVJ5.js} +115 -19
  16. package/dist/{chunk-GHWZVPUV.js → chunk-6JHACXB3.js} +7 -5
  17. package/dist/{chunk-IUVDZVZ4.js → chunk-AXTLYOA7.js} +24 -17
  18. package/dist/{chunk-XJOK5353.js → chunk-B3MPYI4E.js} +2 -2
  19. package/dist/chunk-BMLQPSHP.js +69 -0
  20. package/dist/{chunk-NRSYBKWA.js → chunk-C7CKDFJS.js} +1 -1
  21. package/dist/{chunk-SJFZPS65.js → chunk-EAVX3RLD.js} +1 -1
  22. package/dist/{chunk-VXEF2SWG.js → chunk-EHMMBIZT.js} +16 -12
  23. package/dist/chunk-FVXNEZEW.js +161 -0
  24. package/dist/{chunk-AHL6KOGM.js → chunk-HXINWG37.js} +2 -2
  25. package/dist/{chunk-3CKJOTVM.js → chunk-IW6Q66WS.js} +4 -4
  26. package/dist/chunk-JJFJWD35.js +162 -0
  27. package/dist/{chunk-NYNSYLFY.js → chunk-JL44HGZC.js} +1 -1
  28. package/dist/{chunk-3TBXHLSC.js → chunk-K4F7QEGW.js} +1 -1
  29. package/dist/{chunk-NUJTNH76.js → chunk-LBWKMTT3.js} +1 -1
  30. package/dist/{chunk-YKJO3SI4.js → chunk-LONB36SP.js} +16 -3
  31. package/dist/{chunk-WQ3OMEC4.js → chunk-M6HLYG33.js} +1 -1
  32. package/dist/{chunk-I4GQRMFV.js → chunk-M6YV5KSS.js} +6 -4
  33. package/dist/{chunk-KBDKKHXB.js → chunk-O6CGOVD4.js} +2 -2
  34. package/dist/{chunk-L2RJPVHV.js → chunk-O7MMYJAD.js} +266 -512
  35. package/dist/chunk-QMFMST2T.js +39 -0
  36. package/dist/{chunk-AQF6IXSR.js → chunk-RBCKX2FZ.js} +11 -6
  37. package/dist/{chunk-4W6VDVQU.js → chunk-RLERORUI.js} +246 -56
  38. package/dist/{chunk-MI4SFZGX.js → chunk-RMEJR3AW.js} +5 -2
  39. package/dist/{chunk-UFW4S3RU.js → chunk-RVMCY6DP.js} +1 -1
  40. package/dist/{chunk-LF67HWWR.js → chunk-RWRZVQCB.js} +1 -1
  41. package/dist/{chunk-NQJSPMY2.js → chunk-SCG2VBPB.js} +4 -4
  42. package/dist/chunk-SXIJLSVF.js +41 -0
  43. package/dist/{chunk-YFDQIUQ3.js → chunk-T42GXE7Y.js} +18 -18
  44. package/dist/chunk-TDQW2YHK.js +65 -0
  45. package/dist/{chunk-45UVJXFQ.js → chunk-W2UOVGRC.js} +1 -1
  46. package/dist/{ci-QD2Q7NWY.js → ci-H6GPHG4T.js} +7 -7
  47. package/dist/{ci-format-42XIZO5P.js → ci-format-U47GSGYU.js} +2 -2
  48. package/dist/{constants-5CMEFZQB.js → constants-GYJTB6KI.js} +1 -1
  49. package/dist/{constants-NMASHFDL.js → constants-SNJR6546.js} +1 -1
  50. package/dist/doctor-cli-J6LAQ5LU.js +18 -0
  51. package/dist/electron-server.js +922 -842
  52. package/dist/file-checkpoint-64A2AXHE.js +7 -0
  53. package/dist/{file-checkpoint-NKBHGC7L.js → file-checkpoint-VVPUJNCI.js} +2 -1
  54. package/dist/{hub-ZLF6GMQD.js → hub-G5FMMTVZ.js} +3 -3
  55. package/dist/{hub-server-CBKCP5VD.js → hub-server-JLC7CNP7.js} +55 -17
  56. package/dist/index.js +48 -42
  57. package/dist/{indexer-P3FPRTPJ.js → indexer-GKIWSSRP.js} +3 -3
  58. package/dist/indexer-VRXDZ74A.js +10 -0
  59. package/dist/{persist-S77WRVLD.js → persist-ZZXRWFBX.js} +4 -4
  60. package/dist/{persistent-memory-GJE7HKVK.js → persistent-memory-EXJBXL33.js} +3 -3
  61. package/dist/{persistent-memory-MBSBTBGY.js → persistent-memory-LEE454DW.js} +3 -3
  62. package/dist/{pr-SXRW24JG.js → pr-6PUHVJ6K.js} +7 -7
  63. package/dist/{project-trust-MUG325AW.js → project-trust-6CJB5ZMX.js} +1 -1
  64. package/dist/{project-trust-NKYHL3VZ.js → project-trust-KGG2BWKC.js} +1 -1
  65. package/dist/run-tests-2C7MWZBN.js +12 -0
  66. package/dist/run-tests-33ZVQE3Q.js +13 -0
  67. package/dist/{semantic-7GM5M4MU.js → semantic-N227CLSC.js} +4 -4
  68. package/dist/{semantic-QOBAXEQ4.js → semantic-TRQAZSRY.js} +4 -4
  69. package/dist/{server-GGEO7SA2.js → server-AJH5TBVO.js} +231 -103
  70. package/dist/{server-MO3EU2XD.js → server-CYAB56O3.js} +16 -14
  71. package/dist/{store-SIKHCUYJ.js → store-2N6PPPBP.js} +2 -2
  72. package/dist/{store-CMSSWZF7.js → store-76VVFDXM.js} +2 -2
  73. package/dist/{task-orchestrator-JGEEQ2OE.js → task-orchestrator-HNRV3YUD.js} +15 -14
  74. package/dist/{usage-B7RIAPPT.js → usage-ZN5DU6Z7.js} +4 -4
  75. package/dist/{vector-store-JAXWDZYW.js → vector-store-T2DVUMY4.js} +2 -2
  76. package/dist/{vector-store-PWIOQFTP.js → vector-store-V6UGEYWK.js} +2 -2
  77. package/dist/web/client/app.js +7 -0
  78. package/dist/web/client/app.js.br +0 -0
  79. package/dist/web/client/app.js.gz +0 -0
  80. package/dist/web/client/util.js +14 -23
  81. package/dist/web/client/util.js.br +0 -0
  82. package/dist/web/client/util.js.gz +0 -0
  83. package/dist/web/client/vendor/DOMPurify-LICENSE.txt +202 -0
  84. package/dist/web/client/vendor/purify.es.mjs +2722 -0
  85. package/dist/web/client/vendor/purify.es.mjs.br +0 -0
  86. package/dist/web/client/vendor/purify.es.mjs.gz +0 -0
  87. package/package.json +4 -2
  88. package/dist/chunk-4BKXL7SM.js +0 -98
  89. package/dist/chunk-6BUTA5VW.js +0 -38
  90. package/dist/chunk-IW3Q7AE5.js +0 -40
  91. package/dist/chunk-SKET65WZ.js +0 -96
  92. package/dist/doctor-cli-IOVSHBDI.js +0 -18
  93. package/dist/file-checkpoint-CGH6OJVI.js +0 -6
  94. package/dist/indexer-FPKY7LCT.js +0 -10
  95. package/dist/run-tests-EQCAMFQE.js +0 -10
  96. 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-IW3Q7AE5.js";
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-VAV2IJ3R.js";
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-3TBXHLSC.js";
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-VXEF2SWG.js";
16
+ } from "./chunk-EHMMBIZT.js";
17
17
  import {
18
18
  ConfigManager
19
- } from "./chunk-AQF6IXSR.js";
19
+ } from "./chunk-RBCKX2FZ.js";
20
20
  import {
21
21
  VERSION
22
- } from "./chunk-VAV2IJ3R.js";
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
+ };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  atomicWriteFileSync
4
- } from "./chunk-IW3Q7AE5.js";
4
+ } from "./chunk-BMLQPSHP.js";
5
5
 
6
6
  // src/session/session-index.ts
7
7
  import { existsSync, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  VERSION
4
- } from "./chunk-VAV2IJ3R.js";
4
+ } from "./chunk-3CNPJLVI.js";
5
5
 
6
6
  // src/cli/ci-format.ts
7
7
  var DEFAULT_CI_THRESHOLDS = {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  SessionManager
4
- } from "./chunk-IUVDZVZ4.js";
4
+ } from "./chunk-AXTLYOA7.js";
5
5
 
6
6
  // src/hub/persist.ts
7
7
  import { join } from "path";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-RS7SKYTS.js";
5
5
  import {
6
6
  atomicWriteFileSync
7
- } from "./chunk-IW3Q7AE5.js";
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 beijingHour = (at.getUTCHours() + 8) % 24;
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
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  atomicWriteFileSync
4
- } from "./chunk-IW3Q7AE5.js";
4
+ } from "./chunk-BMLQPSHP.js";
5
5
 
6
6
  // src/symbols/store.ts
7
7
  import fs from "fs";
@@ -8,12 +8,14 @@ import {
8
8
  } from "./chunk-FSC6KEWU.js";
9
9
  import {
10
10
  atomicWriteFileSync
11
- } from "./chunk-6BUTA5VW.js";
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(os.homedir(), ".aicli", MEMORY_DIR_NAME);
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(os.homedir(), ".aicli", "history");
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-OAXLMF3U.js";
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-45UVJXFQ.js";
14
+ } from "./chunk-W2UOVGRC.js";
15
15
 
16
16
  // src/symbols/semantic.ts
17
17
  function pathTokens(absFile, root) {