jinzd-ai-cli 0.4.294 → 0.4.297
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-6YCLYEII.js → batch-YFQ34DHW.js} +2 -2
- package/dist/{chunk-FARHJ42Q.js → chunk-3GIKUDYZ.js} +4 -4
- package/dist/{chunk-MMP6SIB7.js → chunk-56AX43FT.js} +1 -1
- package/dist/{chunk-CUMSLQKQ.js → chunk-6PBWL3XI.js} +1 -1
- package/dist/{chunk-HBFES3RR.js → chunk-CF6RC7OB.js} +4 -4
- package/dist/{chunk-UPJMIP5S.js → chunk-D7GLDXPQ.js} +1 -1
- package/dist/{chunk-AIQMQCVF.js → chunk-DPNKOXJF.js} +48 -11
- package/dist/{chunk-SM7VOJ3B.js → chunk-EFHAMIQF.js} +204 -167
- package/dist/{chunk-QKZUWT3S.js → chunk-FBOVBL7P.js} +12 -1
- package/dist/{chunk-BOG6LVIC.js → chunk-FZUMKY6C.js} +1 -1
- package/dist/{chunk-3H7TVTAE.js → chunk-GNJ3XLS3.js} +1 -1
- package/dist/{chunk-7KYONZUN.js → chunk-J6CYL6RN.js} +1 -1
- package/dist/{chunk-P3BJAJ34.js → chunk-LXORMKZ6.js} +1 -1
- package/dist/{chunk-OMA6DEAR.js → chunk-NB2V7H5C.js} +1 -1
- package/dist/{chunk-ZBHRTOWC.js → chunk-O33BYKAD.js} +1 -1
- package/dist/{chunk-4J6R2VFW.js → chunk-YKJO3SI4.js} +33 -4
- package/dist/{ci-SIS77LEG.js → ci-AR2RLLJD.js} +5 -5
- package/dist/{ci-format-LRMGY4ND.js → ci-format-S7RRDV4A.js} +2 -2
- package/dist/{constants-QRUMNMCK.js → constants-VZBWOKZZ.js} +1 -1
- package/dist/{constants-C7LOS6F4.js → constants-W52VYKDV.js} +1 -1
- package/dist/{doctor-cli-UB5KUBVI.js → doctor-cli-VX36CZND.js} +5 -5
- package/dist/electron-server.js +138 -24
- package/dist/{hub-UWBNCMD4.js → hub-LJL3X7KR.js} +1 -1
- package/dist/index.js +24 -23
- package/dist/{persistent-memory-TUCWY6O3.js → persistent-memory-CMXW4WSP.js} +2 -2
- package/dist/{persistent-memory-GQPXSWDK.js → persistent-memory-WEZMJBIV.js} +2 -2
- package/dist/{pr-MVUT6IOA.js → pr-GTDFMNKY.js} +5 -5
- package/dist/{run-tests-RSIXZR3O.js → run-tests-ILHN2PYU.js} +2 -2
- package/dist/{run-tests-BNKQT42K.js → run-tests-MTWA2NNV.js} +2 -2
- package/dist/{server-ILSFJUK5.js → server-QXP5NHE7.js} +15 -15
- package/dist/{server-YNVHKFGZ.js → server-WFXEEX2E.js} +5 -5
- package/dist/{task-orchestrator-7YEWEKS6.js → task-orchestrator-HZPIN4PT.js} +5 -5
- package/dist/{usage-DXX4VHOQ.js → usage-UEN6LLOG.js} +3 -3
- package/package.json +3 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
computeCost,
|
|
4
4
|
formatCost
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YKJO3SI4.js";
|
|
6
6
|
import {
|
|
7
7
|
clearRecentlyDeniedAutoActions,
|
|
8
8
|
estimateTokens,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
setPreferredAgentName,
|
|
17
17
|
truncateForPersist,
|
|
18
18
|
undoStack
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-DPNKOXJF.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-J6CYL6RN.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-3GIKUDYZ.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-FZUMKY6C.js";
|
|
84
84
|
import {
|
|
85
85
|
isCleanDocumentBody,
|
|
86
86
|
stripOuterCodeFence
|
|
@@ -109,7 +109,195 @@ import {
|
|
|
109
109
|
MCP_TOOL_PREFIX,
|
|
110
110
|
REPO_URL,
|
|
111
111
|
VERSION
|
|
112
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-6PBWL3XI.js";
|
|
113
|
+
|
|
114
|
+
// src/skills/manager.ts
|
|
115
|
+
import { existsSync, readdirSync, mkdirSync, statSync } from "fs";
|
|
116
|
+
import { join } from "path";
|
|
117
|
+
|
|
118
|
+
// src/skills/types.ts
|
|
119
|
+
import { readFileSync } from "fs";
|
|
120
|
+
import { basename } from "path";
|
|
121
|
+
function parseSimpleYaml(yaml) {
|
|
122
|
+
const result = {};
|
|
123
|
+
for (const line of yaml.split("\n")) {
|
|
124
|
+
const match = line.replace(/\r$/, "").match(/^(\w+)\s*:\s*(.+)$/);
|
|
125
|
+
if (match) {
|
|
126
|
+
result[match[1]] = match[2].trim().replace(/^['"]|['"]$/g, "");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
function parseYamlArray(value) {
|
|
132
|
+
const bracketMatch = value.match(/^\[(.+)]$/);
|
|
133
|
+
if (bracketMatch) {
|
|
134
|
+
return bracketMatch[1].split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, ""));
|
|
135
|
+
}
|
|
136
|
+
return [value.trim()];
|
|
137
|
+
}
|
|
138
|
+
function parseSkillFile(filePath) {
|
|
139
|
+
let raw;
|
|
140
|
+
try {
|
|
141
|
+
raw = readFileSync(filePath, "utf-8");
|
|
142
|
+
} catch {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const frontmatterMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
146
|
+
if (!frontmatterMatch) {
|
|
147
|
+
return {
|
|
148
|
+
meta: {
|
|
149
|
+
name: basename(filePath, ".md"),
|
|
150
|
+
description: ""
|
|
151
|
+
},
|
|
152
|
+
content: raw.trim(),
|
|
153
|
+
filePath
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const [, yaml, content] = frontmatterMatch;
|
|
157
|
+
const parsed = parseSimpleYaml(yaml);
|
|
158
|
+
return {
|
|
159
|
+
meta: {
|
|
160
|
+
name: parsed["name"] ?? basename(filePath, ".md"),
|
|
161
|
+
description: parsed["description"] ?? "",
|
|
162
|
+
tools: parsed["tools"] ? parseYamlArray(parsed["tools"]) : void 0
|
|
163
|
+
},
|
|
164
|
+
content: content.trim(),
|
|
165
|
+
filePath
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/skills/manager.ts
|
|
170
|
+
var SKILL_CONTENT_WARN_CHARS_DEFAULT = 1e4;
|
|
171
|
+
var SkillManager = class {
|
|
172
|
+
skills = /* @__PURE__ */ new Map();
|
|
173
|
+
activeSkill = null;
|
|
174
|
+
skillsDir;
|
|
175
|
+
/** 超大技能文件警告阈值,由调用方从 config 传入;0 = 静默,undefined = 用默认 10000 */
|
|
176
|
+
warnThreshold;
|
|
177
|
+
constructor(skillsDir, warnThreshold) {
|
|
178
|
+
this.skillsDir = skillsDir;
|
|
179
|
+
this.warnThreshold = warnThreshold ?? SKILL_CONTENT_WARN_CHARS_DEFAULT;
|
|
180
|
+
}
|
|
181
|
+
/** 发现并加载 skillsDir 以及额外插件目录下的技能,返回加载数量 */
|
|
182
|
+
loadSkills(extraDirs = []) {
|
|
183
|
+
this.skills.clear();
|
|
184
|
+
this.loadSkillDir(this.skillsDir, true);
|
|
185
|
+
for (const dir of extraDirs) this.loadSkillDir(dir, false);
|
|
186
|
+
return this.skills.size;
|
|
187
|
+
}
|
|
188
|
+
loadSkillDir(dir, createIfMissing) {
|
|
189
|
+
if (!existsSync(dir)) {
|
|
190
|
+
if (createIfMissing) {
|
|
191
|
+
try {
|
|
192
|
+
mkdirSync(dir, { recursive: true });
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
let entries;
|
|
199
|
+
try {
|
|
200
|
+
entries = readdirSync(dir);
|
|
201
|
+
} catch {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
for (const entry of entries) {
|
|
205
|
+
let filePath;
|
|
206
|
+
const fullPath = join(dir, entry);
|
|
207
|
+
if (entry.endsWith(".md")) {
|
|
208
|
+
filePath = fullPath;
|
|
209
|
+
} else {
|
|
210
|
+
try {
|
|
211
|
+
if (statSync(fullPath).isDirectory()) {
|
|
212
|
+
const skillMd = join(fullPath, "SKILL.md");
|
|
213
|
+
if (existsSync(skillMd)) filePath = skillMd;
|
|
214
|
+
else continue;
|
|
215
|
+
} else {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
} catch {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const skill = parseSkillFile(filePath);
|
|
223
|
+
if (skill) {
|
|
224
|
+
if (skill.meta.name === "SKILL" && !entry.endsWith(".md")) skill.meta.name = entry;
|
|
225
|
+
if (!this.skills.has(skill.meta.name)) this.skills.set(skill.meta.name, skill);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/** 列出所有已加载的技能 */
|
|
230
|
+
listSkills() {
|
|
231
|
+
return [...this.skills.values()];
|
|
232
|
+
}
|
|
233
|
+
/** 按 name 激活技能。返回被激活的 Skill,未找到返回 null。 */
|
|
234
|
+
activate(name) {
|
|
235
|
+
const skill = this.skills.get(name);
|
|
236
|
+
if (!skill) return null;
|
|
237
|
+
this.activeSkill = skill;
|
|
238
|
+
if (this.warnThreshold > 0 && skill.content.length > this.warnThreshold) {
|
|
239
|
+
process.stderr.write(
|
|
240
|
+
`\u26A0 Skill '${skill.meta.name}' is ${skill.content.length} chars (>${this.warnThreshold}) \u2014 this will be injected into the system prompt now. Adjust threshold with: /config set ui.skillSizeWarn <n|0>
|
|
241
|
+
`
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
return skill;
|
|
245
|
+
}
|
|
246
|
+
/** 停用当前技能 */
|
|
247
|
+
deactivate() {
|
|
248
|
+
this.activeSkill = null;
|
|
249
|
+
}
|
|
250
|
+
/** 获取当前激活的技能(null 表示无激活技能) */
|
|
251
|
+
getActive() {
|
|
252
|
+
return this.activeSkill;
|
|
253
|
+
}
|
|
254
|
+
/** 获取激活技能的 prompt 内容(null 表示无激活技能) */
|
|
255
|
+
getActivePromptContent() {
|
|
256
|
+
return this.activeSkill?.content ?? null;
|
|
257
|
+
}
|
|
258
|
+
/** 获取激活技能的工具白名单 Set(null 表示无限制) */
|
|
259
|
+
getActiveToolFilter() {
|
|
260
|
+
if (!this.activeSkill?.meta.tools) return null;
|
|
261
|
+
return new Set(this.activeSkill.meta.tools);
|
|
262
|
+
}
|
|
263
|
+
/** 获取技能目录路径 */
|
|
264
|
+
getSkillsDir() {
|
|
265
|
+
return this.skillsDir;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
function levenshtein(a, b) {
|
|
269
|
+
const m = a.length, n = b.length;
|
|
270
|
+
if (m === 0) return n;
|
|
271
|
+
if (n === 0) return m;
|
|
272
|
+
let prev = Array.from({ length: n + 1 }, (_, j) => j);
|
|
273
|
+
for (let i = 1; i <= m; i++) {
|
|
274
|
+
const cur = [i];
|
|
275
|
+
for (let j = 1; j <= n; j++) {
|
|
276
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
277
|
+
cur[j] = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + cost);
|
|
278
|
+
}
|
|
279
|
+
prev = cur;
|
|
280
|
+
}
|
|
281
|
+
return prev[n];
|
|
282
|
+
}
|
|
283
|
+
function suggestSkillName(names, input) {
|
|
284
|
+
const norm = (s) => s.toLowerCase().replace(/[-_\s]/g, "");
|
|
285
|
+
const target = norm(input);
|
|
286
|
+
if (!target) return null;
|
|
287
|
+
const exact = names.find((n) => norm(n) === target);
|
|
288
|
+
if (exact) return exact;
|
|
289
|
+
const limit = Math.min(3, Math.max(1, Math.floor(target.length / 4)));
|
|
290
|
+
let best = null;
|
|
291
|
+
let bestScore = Infinity;
|
|
292
|
+
for (const n of names) {
|
|
293
|
+
const d = levenshtein(norm(n), target);
|
|
294
|
+
if (d <= limit && d < bestScore) {
|
|
295
|
+
best = n;
|
|
296
|
+
bestScore = d;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return best;
|
|
300
|
+
}
|
|
113
301
|
|
|
114
302
|
// src/mcp/client.ts
|
|
115
303
|
import { spawn } from "child_process";
|
|
@@ -628,161 +816,6 @@ var McpManager = class {
|
|
|
628
816
|
}
|
|
629
817
|
};
|
|
630
818
|
|
|
631
|
-
// src/skills/manager.ts
|
|
632
|
-
import { existsSync, readdirSync, mkdirSync, statSync } from "fs";
|
|
633
|
-
import { join } from "path";
|
|
634
|
-
|
|
635
|
-
// src/skills/types.ts
|
|
636
|
-
import { readFileSync } from "fs";
|
|
637
|
-
import { basename } from "path";
|
|
638
|
-
function parseSimpleYaml(yaml) {
|
|
639
|
-
const result = {};
|
|
640
|
-
for (const line of yaml.split("\n")) {
|
|
641
|
-
const match = line.replace(/\r$/, "").match(/^(\w+)\s*:\s*(.+)$/);
|
|
642
|
-
if (match) {
|
|
643
|
-
result[match[1]] = match[2].trim().replace(/^['"]|['"]$/g, "");
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
return result;
|
|
647
|
-
}
|
|
648
|
-
function parseYamlArray(value) {
|
|
649
|
-
const bracketMatch = value.match(/^\[(.+)]$/);
|
|
650
|
-
if (bracketMatch) {
|
|
651
|
-
return bracketMatch[1].split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, ""));
|
|
652
|
-
}
|
|
653
|
-
return [value.trim()];
|
|
654
|
-
}
|
|
655
|
-
function parseSkillFile(filePath) {
|
|
656
|
-
let raw;
|
|
657
|
-
try {
|
|
658
|
-
raw = readFileSync(filePath, "utf-8");
|
|
659
|
-
} catch {
|
|
660
|
-
return null;
|
|
661
|
-
}
|
|
662
|
-
const frontmatterMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
663
|
-
if (!frontmatterMatch) {
|
|
664
|
-
return {
|
|
665
|
-
meta: {
|
|
666
|
-
name: basename(filePath, ".md"),
|
|
667
|
-
description: ""
|
|
668
|
-
},
|
|
669
|
-
content: raw.trim(),
|
|
670
|
-
filePath
|
|
671
|
-
};
|
|
672
|
-
}
|
|
673
|
-
const [, yaml, content] = frontmatterMatch;
|
|
674
|
-
const parsed = parseSimpleYaml(yaml);
|
|
675
|
-
return {
|
|
676
|
-
meta: {
|
|
677
|
-
name: parsed["name"] ?? basename(filePath, ".md"),
|
|
678
|
-
description: parsed["description"] ?? "",
|
|
679
|
-
tools: parsed["tools"] ? parseYamlArray(parsed["tools"]) : void 0
|
|
680
|
-
},
|
|
681
|
-
content: content.trim(),
|
|
682
|
-
filePath
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// src/skills/manager.ts
|
|
687
|
-
var SKILL_CONTENT_WARN_CHARS_DEFAULT = 1e4;
|
|
688
|
-
var SkillManager = class {
|
|
689
|
-
skills = /* @__PURE__ */ new Map();
|
|
690
|
-
activeSkill = null;
|
|
691
|
-
skillsDir;
|
|
692
|
-
/** 超大技能文件警告阈值,由调用方从 config 传入;0 = 静默,undefined = 用默认 10000 */
|
|
693
|
-
warnThreshold;
|
|
694
|
-
constructor(skillsDir, warnThreshold) {
|
|
695
|
-
this.skillsDir = skillsDir;
|
|
696
|
-
this.warnThreshold = warnThreshold ?? SKILL_CONTENT_WARN_CHARS_DEFAULT;
|
|
697
|
-
}
|
|
698
|
-
/** 发现并加载 skillsDir 以及额外插件目录下的技能,返回加载数量 */
|
|
699
|
-
loadSkills(extraDirs = []) {
|
|
700
|
-
this.skills.clear();
|
|
701
|
-
this.loadSkillDir(this.skillsDir, true);
|
|
702
|
-
for (const dir of extraDirs) this.loadSkillDir(dir, false);
|
|
703
|
-
return this.skills.size;
|
|
704
|
-
}
|
|
705
|
-
loadSkillDir(dir, createIfMissing) {
|
|
706
|
-
if (!existsSync(dir)) {
|
|
707
|
-
if (createIfMissing) {
|
|
708
|
-
try {
|
|
709
|
-
mkdirSync(dir, { recursive: true });
|
|
710
|
-
} catch {
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
return;
|
|
714
|
-
}
|
|
715
|
-
let entries;
|
|
716
|
-
try {
|
|
717
|
-
entries = readdirSync(dir);
|
|
718
|
-
} catch {
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
|
-
for (const entry of entries) {
|
|
722
|
-
let filePath;
|
|
723
|
-
const fullPath = join(dir, entry);
|
|
724
|
-
if (entry.endsWith(".md")) {
|
|
725
|
-
filePath = fullPath;
|
|
726
|
-
} else {
|
|
727
|
-
try {
|
|
728
|
-
if (statSync(fullPath).isDirectory()) {
|
|
729
|
-
const skillMd = join(fullPath, "SKILL.md");
|
|
730
|
-
if (existsSync(skillMd)) filePath = skillMd;
|
|
731
|
-
else continue;
|
|
732
|
-
} else {
|
|
733
|
-
continue;
|
|
734
|
-
}
|
|
735
|
-
} catch {
|
|
736
|
-
continue;
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
const skill = parseSkillFile(filePath);
|
|
740
|
-
if (skill) {
|
|
741
|
-
if (skill.meta.name === "SKILL" && !entry.endsWith(".md")) skill.meta.name = entry;
|
|
742
|
-
if (!this.skills.has(skill.meta.name)) this.skills.set(skill.meta.name, skill);
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
/** 列出所有已加载的技能 */
|
|
747
|
-
listSkills() {
|
|
748
|
-
return [...this.skills.values()];
|
|
749
|
-
}
|
|
750
|
-
/** 按 name 激活技能。返回被激活的 Skill,未找到返回 null。 */
|
|
751
|
-
activate(name) {
|
|
752
|
-
const skill = this.skills.get(name);
|
|
753
|
-
if (!skill) return null;
|
|
754
|
-
this.activeSkill = skill;
|
|
755
|
-
if (this.warnThreshold > 0 && skill.content.length > this.warnThreshold) {
|
|
756
|
-
process.stderr.write(
|
|
757
|
-
`\u26A0 Skill '${skill.meta.name}' is ${skill.content.length} chars (>${this.warnThreshold}) \u2014 this will be injected into the system prompt now. Adjust threshold with: /config set ui.skillSizeWarn <n|0>
|
|
758
|
-
`
|
|
759
|
-
);
|
|
760
|
-
}
|
|
761
|
-
return skill;
|
|
762
|
-
}
|
|
763
|
-
/** 停用当前技能 */
|
|
764
|
-
deactivate() {
|
|
765
|
-
this.activeSkill = null;
|
|
766
|
-
}
|
|
767
|
-
/** 获取当前激活的技能(null 表示无激活技能) */
|
|
768
|
-
getActive() {
|
|
769
|
-
return this.activeSkill;
|
|
770
|
-
}
|
|
771
|
-
/** 获取激活技能的 prompt 内容(null 表示无激活技能) */
|
|
772
|
-
getActivePromptContent() {
|
|
773
|
-
return this.activeSkill?.content ?? null;
|
|
774
|
-
}
|
|
775
|
-
/** 获取激活技能的工具白名单 Set(null 表示无限制) */
|
|
776
|
-
getActiveToolFilter() {
|
|
777
|
-
if (!this.activeSkill?.meta.tools) return null;
|
|
778
|
-
return new Set(this.activeSkill.meta.tools);
|
|
779
|
-
}
|
|
780
|
-
/** 获取技能目录路径 */
|
|
781
|
-
getSkillsDir() {
|
|
782
|
-
return this.skillsDir;
|
|
783
|
-
}
|
|
784
|
-
};
|
|
785
|
-
|
|
786
819
|
// src/core/proxy.ts
|
|
787
820
|
async function setupProxy(configProxy) {
|
|
788
821
|
const proxyUrl = process.env.HTTPS_PROXY ?? process.env.HTTP_PROXY ?? process.env.https_proxy ?? process.env.http_proxy ?? configProxy;
|
|
@@ -2393,7 +2426,7 @@ No tools match "${filter}".
|
|
|
2393
2426
|
const { join: join6 } = await import("path");
|
|
2394
2427
|
const { existsSync: existsSync6 } = await import("fs");
|
|
2395
2428
|
const { getGitRoot } = await import("./git-context-EXOEHQSF.js");
|
|
2396
|
-
const { MCP_PROJECT_CONFIG_NAME } = await import("./constants-
|
|
2429
|
+
const { MCP_PROJECT_CONFIG_NAME } = await import("./constants-W52VYKDV.js");
|
|
2397
2430
|
const { approveProject, hashMcpFile } = await import("./project-trust-NKYHL3VZ.js");
|
|
2398
2431
|
const cwd = process.cwd();
|
|
2399
2432
|
const projectRoot = getGitRoot(cwd) ?? cwd;
|
|
@@ -2542,9 +2575,13 @@ No tools match "${filter}".
|
|
|
2542
2575
|
ctx.renderer.printSuccess(`Reloaded: ${count} skill(s) found.`);
|
|
2543
2576
|
return;
|
|
2544
2577
|
}
|
|
2545
|
-
const
|
|
2578
|
+
const allSkills = manager.listSkills();
|
|
2579
|
+
const target = allSkills.find((s) => s.meta.name === sub);
|
|
2546
2580
|
if (!target) {
|
|
2547
|
-
|
|
2581
|
+
const guess = suggestSkillName(allSkills.map((s) => s.meta.name), sub);
|
|
2582
|
+
ctx.renderer.renderError(
|
|
2583
|
+
guess ? `Skill '${sub}' not found. Did you mean '${guess}'? (/skill ${guess})` : `Skill '${sub}' not found. Use /skill list to see available skills.`
|
|
2584
|
+
);
|
|
2548
2585
|
return;
|
|
2549
2586
|
}
|
|
2550
2587
|
const prev = manager.getActive();
|
|
@@ -3497,7 +3534,7 @@ function createReviewCommands() {
|
|
|
3497
3534
|
usage: "/test [command|filter]",
|
|
3498
3535
|
async execute(args, ctx) {
|
|
3499
3536
|
try {
|
|
3500
|
-
const { executeTests } = await import("./run-tests-
|
|
3537
|
+
const { executeTests } = await import("./run-tests-MTWA2NNV.js");
|
|
3501
3538
|
const argStr = args.join(" ").trim();
|
|
3502
3539
|
let testArgs = {};
|
|
3503
3540
|
if (argStr) {
|
|
@@ -5633,6 +5670,8 @@ export {
|
|
|
5633
5670
|
agentUnknownMessage,
|
|
5634
5671
|
parseSkillCommand,
|
|
5635
5672
|
skillHistoryNote,
|
|
5673
|
+
parseSimpleYaml,
|
|
5674
|
+
SkillManager,
|
|
5636
5675
|
applyProfileCommand,
|
|
5637
5676
|
readGitDiff,
|
|
5638
5677
|
parseRewindArgs,
|
|
@@ -5663,7 +5702,6 @@ export {
|
|
|
5663
5702
|
getClipboardHint,
|
|
5664
5703
|
CommandRegistry,
|
|
5665
5704
|
createDefaultCommands,
|
|
5666
|
-
parseSimpleYaml,
|
|
5667
5705
|
persistToolRound,
|
|
5668
5706
|
autoTrimSessionIfNeeded,
|
|
5669
5707
|
estimateConversationTokens,
|
|
@@ -5677,7 +5715,6 @@ export {
|
|
|
5677
5715
|
loadDevState,
|
|
5678
5716
|
clearDevState,
|
|
5679
5717
|
McpManager,
|
|
5680
|
-
SkillManager,
|
|
5681
5718
|
snapshotFile,
|
|
5682
5719
|
armDeferredSave,
|
|
5683
5720
|
decideDeferredSave,
|
|
@@ -2061,7 +2061,18 @@ var OPENROUTER_CONFIG = {
|
|
|
2061
2061
|
{ id: "meta-llama/llama-4-maverick", displayName: "Llama 4 Maverick", contextWindow: 1048576, supportsStreaming: true },
|
|
2062
2062
|
{ id: "meta-llama/llama-4-scout", displayName: "Llama 4 Scout", contextWindow: 512e3, supportsStreaming: true },
|
|
2063
2063
|
{ id: "qwen/qwen3-coder", displayName: "Qwen3 Coder", contextWindow: 262144, supportsStreaming: true },
|
|
2064
|
-
{ id: "mistralai/mistral-large", displayName: "Mistral Large", contextWindow: 131072, supportsStreaming: true }
|
|
2064
|
+
{ id: "mistralai/mistral-large", displayName: "Mistral Large", contextWindow: 131072, supportsStreaming: true },
|
|
2065
|
+
// ── 国产旗舰(2026-08-29 对 /api/v1/models 实测取回的真实 id、上下文与价格)──
|
|
2066
|
+
// 走 OpenRouter 的理由不只是"多一个入口":DeepSeek V4 Flash 在这里比直连国内**便宜一个
|
|
2067
|
+
// 数量级**(详见 pricing.ts 的对照注释)。id 一律 `vendor/model` 形式,与直连 provider
|
|
2068
|
+
// 的裸 id 不冲突。
|
|
2069
|
+
{ id: "deepseek/deepseek-v4-flash-0731", displayName: "DeepSeek V4 Flash (0731) \u2014 \u6781\u5EC9\u4EF7, 1.31M", contextWindow: 1310720, supportsStreaming: true, supportsThinking: true },
|
|
2070
|
+
{ id: "deepseek/deepseek-v4-pro-0813", displayName: "DeepSeek V4 Pro (0813), 1M", contextWindow: 1048576, supportsStreaming: true, supportsThinking: true },
|
|
2071
|
+
{ id: "z-ai/glm-5.3-flash", displayName: "GLM-5.3 Flash (\u591A\u6A21\u6001, 1.31M)", contextWindow: 1310720, supportsStreaming: true, supportsThinking: true },
|
|
2072
|
+
{ id: "z-ai/glm-5.3", displayName: "GLM-5.3 (\u65D7\u8230, 1.31M)", contextWindow: 1310720, supportsStreaming: true, supportsThinking: true },
|
|
2073
|
+
{ id: "z-ai/glm-4.6", displayName: "GLM-4.6 (\u4E2D\u6587\u5199\u4F5C, 200K)", contextWindow: 204800, supportsStreaming: true },
|
|
2074
|
+
{ id: "moonshotai/kimi-k3", displayName: "Kimi K3 (1M)", contextWindow: 1048576, supportsStreaming: true, supportsThinking: true },
|
|
2075
|
+
{ id: "minimax/minimax-m3", displayName: "MiniMax M3 (1M)", contextWindow: 1048576, supportsStreaming: true }
|
|
2065
2076
|
]
|
|
2066
2077
|
};
|
|
2067
2078
|
var OpenRouterProvider = createStaticProviderClass(OPENROUTER_CONFIG);
|
|
@@ -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-6PBWL3XI.js";
|
|
17
17
|
|
|
18
18
|
// src/memory/persistent-memory.ts
|
|
19
19
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
MEMORY_FILE_NAME,
|
|
13
13
|
MEMORY_MAX_CHARS,
|
|
14
14
|
MEMORY_STORE_FILE_NAME
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-D7GLDXPQ.js";
|
|
16
16
|
|
|
17
17
|
// src/memory/persistent-memory.ts
|
|
18
18
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
|
|
@@ -113,14 +113,42 @@ var PRICING_TABLE = {
|
|
|
113
113
|
"glm-5.1-air": { input: 0.4, output: 1.2 },
|
|
114
114
|
"glm-z1": { input: 0.5, output: 1.5 },
|
|
115
115
|
"glm-z1-air": { input: 0.2, output: 0.6 },
|
|
116
|
-
"glm-z1-flash": { input: 0, output: 0 }
|
|
116
|
+
"glm-z1-flash": { input: 0, output: 0 },
|
|
117
117
|
// ── MiniMax (海螺) ────────────────────────────────────────────
|
|
118
118
|
// GAP (v0.4.184): MiniMax-M3 / M2.x are unpriced — no verified rate anchor yet.
|
|
119
119
|
// Unpriced → `aicli usage` shows "—" (unknown), not a false $0.00. Add when confirmed.
|
|
120
120
|
// ── OpenRouter (pass-through — actual cost depends on underlying model) ──
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
121
|
+
// 绝大多数 id 仍**刻意留空**:真实价由底层模型 + OpenRouter 加价决定,静态表覆盖不了
|
|
122
|
+
// 396 个模型,未收录的照旧显示 "—"(未知)而不是假的 $0.00。
|
|
123
|
+
//
|
|
124
|
+
// 下面这批是 curated 列表里的国产旗舰,**2026-08-29 对 `/api/v1/models` 实测取回的一手
|
|
125
|
+
// 价格**(该端点直接返回每 token 单价,这里换算成每百万 token 的美元数)。收录它们是因为
|
|
126
|
+
// 东叔真的会用,而 `aicli usage` 记不到价就等于这条路的花费不进预算告警。
|
|
127
|
+
//
|
|
128
|
+
// ⚠ 这是**快照**,不是实时价:OpenRouter 的价格随底层供应商变动,且它自己就有多家供应商
|
|
129
|
+
// 轮转。偏差方向未知(不像智谱那次能靠"记恢复价"保证高估),故注明取数日期,发现明显不符
|
|
130
|
+
// 时以 `/api/v1/models` 为准重取。
|
|
131
|
+
//
|
|
132
|
+
// 与直连国内的对照(同一模型、同一天):
|
|
133
|
+
// deepseek-v4-flash-0731 直连闲时 $0.217/$0.652、峰时 $0.435/$1.304
|
|
134
|
+
// OpenRouter $0.045/$0.090 → **便宜约 5–14 倍**
|
|
135
|
+
// deepseek-v4-pro-0813 直连闲时 $0.652/$1.957 ≈ OpenRouter $0.660/$1.980(基本持平)
|
|
136
|
+
// 直连峰时 $1.304/$3.913 → OpenRouter 便宜约一半
|
|
137
|
+
// glm-5.3-flash 直连恢复价 $0.116/$0.406、5 折促销价 $0.058/$0.203
|
|
138
|
+
// OpenRouter $0.075/$0.250 → 比恢复价便宜、比促销价略贵
|
|
139
|
+
// kimi-k3 两边同价($3.00/$15.00)
|
|
140
|
+
"deepseek/deepseek-v4-flash-0731": { input: 0.045, output: 0.09 },
|
|
141
|
+
"deepseek/deepseek-v4-flash-0731:batch": { input: 0.14, output: 0.28 },
|
|
142
|
+
"deepseek/deepseek-v4-flash": { input: 0.086, output: 0.171 },
|
|
143
|
+
"deepseek/deepseek-v4-pro-0813": { input: 0.66, output: 1.98 },
|
|
144
|
+
"deepseek/deepseek-v4-pro-0813:batch": { input: 1.32, output: 3.96 },
|
|
145
|
+
"deepseek/deepseek-v4-pro": { input: 0.701, output: 1.402 },
|
|
146
|
+
"z-ai/glm-5.3-flash": { input: 0.075, output: 0.25 },
|
|
147
|
+
"z-ai/glm-5.3-flash:batch": { input: 0.15, output: 0.5 },
|
|
148
|
+
"z-ai/glm-5.3": { input: 1.4, output: 4.4 },
|
|
149
|
+
"z-ai/glm-4.6": { input: 0.43, output: 1.75 },
|
|
150
|
+
"moonshotai/kimi-k3": { input: 3, output: 15 },
|
|
151
|
+
"minimax/minimax-m3": { input: 0.3, output: 1.2 }
|
|
124
152
|
// ── Ollama (local, zero cost) ─────────────────────────────────
|
|
125
153
|
// Handled via provider check below (FREE_PROVIDERS → genuine $0.00, not "unknown").
|
|
126
154
|
};
|
|
@@ -130,6 +158,7 @@ function getPricing(provider, model, at = /* @__PURE__ */ new Date()) {
|
|
|
130
158
|
return { input: 0, output: 0 };
|
|
131
159
|
}
|
|
132
160
|
const key = model.toLowerCase();
|
|
161
|
+
if (key.endsWith(":free")) return { input: 0, output: 0 };
|
|
133
162
|
if (provider.toLowerCase() === "deepseek") {
|
|
134
163
|
const dynamicPricing = getDeepSeekV4Pricing(key, at);
|
|
135
164
|
if (dynamicPricing) return dynamicPricing;
|
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
CI_COMMENT_MARKER,
|
|
4
4
|
countSeverity,
|
|
5
5
|
runCi
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-CF6RC7OB.js";
|
|
7
|
+
import "./chunk-GNJ3XLS3.js";
|
|
8
8
|
import "./chunk-HLWUDRBO.js";
|
|
9
9
|
import "./chunk-6YZEZFX5.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-FBOVBL7P.js";
|
|
11
|
+
import "./chunk-O33BYKAD.js";
|
|
12
12
|
import "./chunk-Y56UGZPX.js";
|
|
13
13
|
import "./chunk-TU3L3PW7.js";
|
|
14
14
|
import "./chunk-IW3Q7AE5.js";
|
|
15
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-6PBWL3XI.js";
|
|
16
16
|
export {
|
|
17
17
|
CI_COMMENT_MARKER,
|
|
18
18
|
countSeverity,
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
import {
|
|
3
3
|
formatDoctorReport,
|
|
4
4
|
runDoctorCli
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-3GIKUDYZ.js";
|
|
6
|
+
import "./chunk-FZUMKY6C.js";
|
|
7
7
|
import "./chunk-RS7SKYTS.js";
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-FBOVBL7P.js";
|
|
9
|
+
import "./chunk-O33BYKAD.js";
|
|
10
10
|
import "./chunk-Y56UGZPX.js";
|
|
11
11
|
import "./chunk-TU3L3PW7.js";
|
|
12
12
|
import "./chunk-HOSJZMQS.js";
|
|
13
13
|
import "./chunk-IW3Q7AE5.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-6PBWL3XI.js";
|
|
15
15
|
export {
|
|
16
16
|
formatDoctorReport,
|
|
17
17
|
runDoctorCli
|