@gird/ccli 2.19.0 → 2.21.0

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 (122) hide show
  1. package/README.md +4 -0
  2. package/dist/agent/ai.js.map +1 -1
  3. package/dist/agent/model-catalog.js +100 -0
  4. package/dist/agent/model-catalog.js.map +1 -0
  5. package/dist/agent/os.js +291 -2
  6. package/dist/agent/os.js.map +1 -1
  7. package/dist/agent/providers/anthropic.js +112 -4
  8. package/dist/agent/providers/anthropic.js.map +1 -1
  9. package/dist/agent/rag/db.js +142 -0
  10. package/dist/agent/rag/db.js.map +1 -0
  11. package/dist/agent/rag/embedding.js +135 -0
  12. package/dist/agent/rag/embedding.js.map +1 -0
  13. package/dist/agent/rag/indexer.js +104 -0
  14. package/dist/agent/rag/indexer.js.map +1 -0
  15. package/dist/agent/rag/parser.js +75 -0
  16. package/dist/agent/rag/parser.js.map +1 -0
  17. package/dist/agent/rag/search.js +47 -0
  18. package/dist/agent/rag/search.js.map +1 -0
  19. package/dist/cli/args/index.js +30 -0
  20. package/dist/cli/args/index.js.map +1 -1
  21. package/dist/cli/repl/index.js +4 -3
  22. package/dist/cli/repl/index.js.map +1 -1
  23. package/dist/cli/run/index.js +27 -18
  24. package/dist/cli/run/index.js.map +1 -1
  25. package/dist/cli/run/task.js +188 -32
  26. package/dist/cli/run/task.js.map +1 -1
  27. package/dist/cli/session/checkpoint.js +50 -34
  28. package/dist/cli/session/checkpoint.js.map +1 -1
  29. package/dist/cli/slash/config/account.js +84 -0
  30. package/dist/cli/slash/config/account.js.map +1 -0
  31. package/dist/cli/slash/config/alias.js +96 -0
  32. package/dist/cli/slash/config/alias.js.map +1 -0
  33. package/dist/cli/slash/config/login.js +80 -0
  34. package/dist/cli/slash/config/login.js.map +1 -0
  35. package/dist/cli/slash/config/model.js +50 -6
  36. package/dist/cli/slash/config/model.js.map +1 -1
  37. package/dist/cli/slash/config/models.js +45 -0
  38. package/dist/cli/slash/config/models.js.map +1 -0
  39. package/dist/cli/slash/index.js +25 -1
  40. package/dist/cli/slash/index.js.map +1 -1
  41. package/dist/cli/slash/system/agent.js +1 -1
  42. package/dist/cli/slash/system/agent.js.map +1 -1
  43. package/dist/cli/slash/system/compact.js +1 -1
  44. package/dist/cli/slash/system/compact.js.map +1 -1
  45. package/dist/cli/slash/system/goal.js +1 -1
  46. package/dist/cli/slash/system/goal.js.map +1 -1
  47. package/dist/cli/slash/system/help.js +6 -0
  48. package/dist/cli/slash/system/help.js.map +1 -1
  49. package/dist/cli/slash/system/indexer.js +25 -0
  50. package/dist/cli/slash/system/indexer.js.map +1 -0
  51. package/dist/cli/slash/system/plan.js +1 -1
  52. package/dist/cli/slash/system/plan.js.map +1 -1
  53. package/dist/cli/slash/system/revert.js +7 -5
  54. package/dist/cli/slash/system/revert.js.map +1 -1
  55. package/dist/cli/slash/system/upgrade.js +13 -0
  56. package/dist/cli/slash/system/upgrade.js.map +1 -0
  57. package/dist/cli/stats/index.js +6 -1
  58. package/dist/cli/stats/index.js.map +1 -1
  59. package/dist/cli/stats/usage.js +215 -0
  60. package/dist/cli/stats/usage.js.map +1 -0
  61. package/dist/cli/upgrade.js +90 -0
  62. package/dist/cli/upgrade.js.map +1 -0
  63. package/dist/config/config.js +344 -10
  64. package/dist/config/config.js.map +1 -1
  65. package/dist/config/credentials.js +104 -0
  66. package/dist/config/credentials.js.map +1 -0
  67. package/dist/config/project-context.js +135 -0
  68. package/dist/config/project-context.js.map +1 -0
  69. package/dist/harness/index.js +11 -3
  70. package/dist/harness/index.js.map +1 -1
  71. package/dist/index.js +31 -2
  72. package/dist/index.js.map +1 -1
  73. package/dist/server/webui-content.js +2 -0
  74. package/dist/server/webui-content.js.map +1 -0
  75. package/dist/server/webui.js +15 -4
  76. package/dist/server/webui.js.map +1 -1
  77. package/dist/tools/{skill-tool.js → agent/skill-tool.js} +1 -1
  78. package/dist/tools/agent/skill-tool.js.map +1 -0
  79. package/dist/tools/{todo.js → agent/todo.js} +1 -1
  80. package/dist/tools/agent/todo.js.map +1 -0
  81. package/dist/tools/agent/web-fetch.js.map +1 -0
  82. package/dist/tools/{edit-file.js → fs/edit-file.js} +8 -14
  83. package/dist/tools/fs/edit-file.js.map +1 -0
  84. package/dist/tools/fs/glob.js.map +1 -0
  85. package/dist/tools/{grep.js → fs/grep.js} +1 -1
  86. package/dist/tools/fs/grep.js.map +1 -0
  87. package/dist/tools/fs/list-dir.js +95 -0
  88. package/dist/tools/fs/list-dir.js.map +1 -0
  89. package/dist/tools/{read-file.js → fs/read-file.js} +1 -1
  90. package/dist/tools/fs/read-file.js.map +1 -0
  91. package/dist/tools/{write-file.js → fs/write-file.js} +8 -15
  92. package/dist/tools/fs/write-file.js.map +1 -0
  93. package/dist/tools/index.js +13 -11
  94. package/dist/tools/index.js.map +1 -1
  95. package/dist/tools/rag/search.js +65 -0
  96. package/dist/tools/rag/search.js.map +1 -0
  97. package/dist/tools/shared.js.map +1 -1
  98. package/dist/tools/shell/bash-background.js.map +1 -0
  99. package/dist/tools/shell/bash-output.js.map +1 -0
  100. package/dist/tools/shell/bash.js.map +1 -0
  101. package/dist/tools/shell/kill-bash.js.map +1 -0
  102. package/package.json +3 -1
  103. package/dist/tools/bash-background.js.map +0 -1
  104. package/dist/tools/bash-output.js.map +0 -1
  105. package/dist/tools/bash.js.map +0 -1
  106. package/dist/tools/edit-file.js.map +0 -1
  107. package/dist/tools/glob.js.map +0 -1
  108. package/dist/tools/grep.js.map +0 -1
  109. package/dist/tools/kill-bash.js.map +0 -1
  110. package/dist/tools/list-dir.js +0 -45
  111. package/dist/tools/list-dir.js.map +0 -1
  112. package/dist/tools/read-file.js.map +0 -1
  113. package/dist/tools/skill-tool.js.map +0 -1
  114. package/dist/tools/todo.js.map +0 -1
  115. package/dist/tools/web-fetch.js.map +0 -1
  116. package/dist/tools/write-file.js.map +0 -1
  117. /package/dist/tools/{web-fetch.js → agent/web-fetch.js} +0 -0
  118. /package/dist/tools/{glob.js → fs/glob.js} +0 -0
  119. /package/dist/tools/{bash-background.js → shell/bash-background.js} +0 -0
  120. /package/dist/tools/{bash-output.js → shell/bash-output.js} +0 -0
  121. /package/dist/tools/{bash.js → shell/bash.js} +0 -0
  122. /package/dist/tools/{kill-bash.js → shell/kill-bash.js} +0 -0
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Usage 统计持久化与成本估算。
3
+ *
4
+ * 每次 AI 回合结束时,把真实 token 消耗(优先后端返回,缺失时字符估算)
5
+ * 追加到 ~/.ccli/usage.jsonl。/account 可读取并展示本月累计与预估成本。
6
+ *
7
+ * 成本单价为常见模型的近似值,仅供参考;未知模型不估算成本。
8
+ */
9
+ import { homedir } from 'node:os';
10
+ import { join } from 'node:path';
11
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, } from 'node:fs';
12
+ /** 默认 usage 文件路径。 */
13
+ export function usagePath() {
14
+ return join(homedir(), '.ccli', 'usage.jsonl');
15
+ }
16
+ /**
17
+ * 常见模型单价(USD / 1M tokens)。
18
+ * 价格为近似值,仅用于 /account 展示预估成本;实际账单以各平台为准。
19
+ * 匹配规则:先精确匹配,再前缀匹配(如 qwen-plus-0919 → qwen-plus)。
20
+ */
21
+ const MODEL_PRICES = {
22
+ // 通义千问(OpenAI 兼容端点常见模型)
23
+ 'qwen-plus': { prompt: 0.8, completion: 2.0 },
24
+ 'qwen-max': { prompt: 2.4, completion: 9.6 },
25
+ 'qwen-turbo': { prompt: 0.5, completion: 2.0 },
26
+ 'qwen-vl-plus': { prompt: 2.0, completion: 5.0 },
27
+ 'qwen3.6-flash': { prompt: 0.166, completion: 0.993 },
28
+ 'qwen3.7-plus': { prompt: 0.276, completion: 1.103 },
29
+ 'qwen3.7-max': { prompt: 1.655, completion: 4.966 },
30
+ // OpenAI 官方
31
+ 'gpt-4o': { prompt: 2.5, completion: 10.0 },
32
+ 'gpt-4o-mini': { prompt: 0.15, completion: 0.6 },
33
+ 'o3-mini': { prompt: 1.1, completion: 4.4 },
34
+ // Anthropic
35
+ 'claude-3-5-haiku-20241022': { prompt: 0.8, completion: 4.0 },
36
+ 'claude-sonnet-4-5': { prompt: 3.0, completion: 15.0 },
37
+ 'claude-opus-4-5': { prompt: 15.0, completion: 75.0 },
38
+ // DeepSeek
39
+ 'deepseek-chat': { prompt: 0.14, completion: 0.28 },
40
+ 'deepseek-coder': { prompt: 0.14, completion: 0.28 },
41
+ 'deepseek-reasoner': { prompt: 0.55, completion: 2.19 },
42
+ 'deepseek-v4-flash': { prompt: 0.14, completion: 0.28 },
43
+ 'deepseek-v4-pro': { prompt: 0.435, completion: 0.87 },
44
+ // Gemini
45
+ 'gemini-2.5-flash': { prompt: 0.15, completion: 0.6 },
46
+ 'gemini-2.5-pro': { prompt: 1.25, completion: 10.0 },
47
+ // 智谱 GLM
48
+ 'glm-4': { prompt: 1.0, completion: 1.0 },
49
+ 'glm-4-flash': { prompt: 0.0, completion: 0.0 },
50
+ };
51
+ /** 查找模型单价;先精确匹配,再前缀匹配。 */
52
+ function findPrice(model) {
53
+ const exact = MODEL_PRICES[model];
54
+ if (exact)
55
+ return exact;
56
+ for (const key of Object.keys(MODEL_PRICES)) {
57
+ if (model.startsWith(key))
58
+ return MODEL_PRICES[key];
59
+ }
60
+ return undefined;
61
+ }
62
+ /**
63
+ * 估算一次调用的成本(USD)。
64
+ * 未知模型返回 undefined。
65
+ */
66
+ export function estimateCost(_provider, model, promptTokens, completionTokens) {
67
+ const price = findPrice(model);
68
+ if (!price)
69
+ return undefined;
70
+ const cost = (promptTokens / 1_000_000) * price.prompt +
71
+ (completionTokens / 1_000_000) * price.completion;
72
+ return cost;
73
+ }
74
+ /**
75
+ * 追加一条 usage 记录。
76
+ * 任何失败(磁盘满、权限等)都静默吞掉,不中断会话。
77
+ */
78
+ export function appendUsage(record) {
79
+ try {
80
+ const path = usagePath();
81
+ mkdirSync(join(homedir(), '.ccli'), { recursive: true });
82
+ const estimatedCostUSD = estimateCost(record.provider, record.model, record.promptTokens, record.completionTokens);
83
+ const line = JSON.stringify({
84
+ ts: new Date().toISOString(),
85
+ ...record,
86
+ ...(estimatedCostUSD !== undefined
87
+ ? { estimatedCostUSD }
88
+ : {}),
89
+ }) + '\n';
90
+ appendFileSync(path, line, 'utf8');
91
+ }
92
+ catch {
93
+ // usage 记录不能打断会话
94
+ }
95
+ }
96
+ /** 读取全部 usage 记录;文件不存在或损坏时返回空数组。 */
97
+ export function readUsageRecords() {
98
+ const path = usagePath();
99
+ if (!existsSync(path))
100
+ return [];
101
+ const raw = readFileSync(path, 'utf8');
102
+ if (!raw.trim())
103
+ return [];
104
+ const out = [];
105
+ for (const line of raw.split('\n')) {
106
+ if (!line.trim())
107
+ continue;
108
+ try {
109
+ out.push(JSON.parse(line));
110
+ }
111
+ catch {
112
+ // 跳过坏行
113
+ }
114
+ }
115
+ return out;
116
+ }
117
+ /**
118
+ * 按条件读取 usage,并按模型分组汇总。
119
+ * 返回数组按总 token 数降序排列。
120
+ */
121
+ export function readUsageByModel(filters = {}) {
122
+ const records = readUsageRecords().filter((r) => {
123
+ if (filters.provider && r.provider !== filters.provider)
124
+ return false;
125
+ if (filters.since) {
126
+ const ts = new Date(r.ts).getTime();
127
+ if (ts < filters.since.getTime())
128
+ return false;
129
+ }
130
+ if (filters.until) {
131
+ const ts = new Date(r.ts).getTime();
132
+ if (ts > filters.until.getTime())
133
+ return false;
134
+ }
135
+ return true;
136
+ });
137
+ const byModel = new Map();
138
+ for (const r of records) {
139
+ const existing = byModel.get(r.model);
140
+ const next = {
141
+ promptTokens: existing ? existing.promptTokens + r.promptTokens : r.promptTokens,
142
+ completionTokens: existing
143
+ ? existing.completionTokens + r.completionTokens
144
+ : r.completionTokens,
145
+ totalTokens: existing ? existing.totalTokens + r.totalTokens : r.totalTokens,
146
+ estimatedCostUSD: (existing ? existing.estimatedCostUSD : 0) + (r.estimatedCostUSD ?? 0),
147
+ recordCount: existing ? existing.recordCount + 1 : 1,
148
+ };
149
+ byModel.set(r.model, next);
150
+ }
151
+ return Array.from(byModel.entries())
152
+ .map(([model, summary]) => ({ model, summary }))
153
+ .sort((a, b) => b.summary.totalTokens - a.summary.totalTokens);
154
+ }
155
+ /**
156
+ * 按条件读取 usage 并汇总。
157
+ * 不传条件时返回全部记录累计。
158
+ */
159
+ export function readUsageSummary(filters = {}) {
160
+ const records = readUsageRecords().filter((r) => {
161
+ if (filters.provider && r.provider !== filters.provider)
162
+ return false;
163
+ if (filters.model && r.model !== filters.model)
164
+ return false;
165
+ if (filters.since) {
166
+ const ts = new Date(r.ts).getTime();
167
+ if (ts < filters.since.getTime())
168
+ return false;
169
+ }
170
+ if (filters.until) {
171
+ const ts = new Date(r.ts).getTime();
172
+ if (ts > filters.until.getTime())
173
+ return false;
174
+ }
175
+ return true;
176
+ });
177
+ return records.reduce((sum, r) => ({
178
+ promptTokens: sum.promptTokens + r.promptTokens,
179
+ completionTokens: sum.completionTokens + r.completionTokens,
180
+ totalTokens: sum.totalTokens + r.totalTokens,
181
+ estimatedCostUSD: sum.estimatedCostUSD + (r.estimatedCostUSD ?? 0),
182
+ recordCount: sum.recordCount + 1,
183
+ }), {
184
+ promptTokens: 0,
185
+ completionTokens: 0,
186
+ totalTokens: 0,
187
+ estimatedCostUSD: 0,
188
+ recordCount: 0,
189
+ });
190
+ }
191
+ /** 获取本月起止时间。 */
192
+ export function thisMonthRange() {
193
+ const now = new Date();
194
+ const since = new Date(now.getFullYear(), now.getMonth(), 1);
195
+ const until = new Date(now.getFullYear(), now.getMonth() + 1, 1);
196
+ return { since, until };
197
+ }
198
+ /** 把 token 数格式化为紧凑形式(如 1.2K、3.4M)。 */
199
+ export function formatTokensCompact(n) {
200
+ if (n >= 1_000_000) {
201
+ return `${(n / 1_000_000).toFixed(1)}M`;
202
+ }
203
+ if (n >= 1_000) {
204
+ return `${(n / 1_000).toFixed(1)}K`;
205
+ }
206
+ return String(n);
207
+ }
208
+ /** 格式化 usage 摘要供 /account 展示。 */
209
+ export function formatUsageSummary(summary) {
210
+ const cost = summary.estimatedCostUSD > 0
211
+ ? ` 预估成本: $${summary.estimatedCostUSD.toFixed(4)}`
212
+ : '';
213
+ return `本月: ${formatTokensCompact(summary.totalTokens)} tokens(输入 ${formatTokensCompact(summary.promptTokens)} / 输出 ${formatTokensCompact(summary.completionTokens)})${cost}`.trim();
214
+ }
215
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/cli/stats/usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import { createWriteStream, chmodSync } from 'node:fs';
2
+ import { rename } from 'node:fs/promises';
3
+ import { Readable } from 'node:stream';
4
+ import { pipeline } from 'node:stream/promises';
5
+ import { execSync } from 'node:child_process';
6
+ import { VERSION } from '../version.js';
7
+ /**
8
+ * 自动检测并升级 CLI 核心逻辑。
9
+ * 支持 npm 安装环境自动升级和单二进制 SEA 原子文件替换。
10
+ */
11
+ export async function runUpgrade(print) {
12
+ const log = print ?? console.log;
13
+ log('🔎 正在检测线上最新版本...');
14
+ try {
15
+ const res = await fetch('https://registry.npmjs.org/@gird/ccli/latest', {
16
+ signal: AbortSignal.timeout(10000)
17
+ });
18
+ if (!res.ok) {
19
+ return { ok: false, message: `无法获取线上版本: ${res.statusText}` };
20
+ }
21
+ const data = await res.json();
22
+ const latestVersion = data.version;
23
+ if (latestVersion === VERSION) {
24
+ return { ok: true, message: `当前已是最新版本 (v${VERSION})。` };
25
+ }
26
+ log(`✨ 检测到新版本 v${latestVersion} (本地当前版本 v${VERSION})`);
27
+ // 环境判断
28
+ const execPathLower = process.execPath.toLowerCase();
29
+ const isNpm = execPathLower.includes('node') || execPathLower.includes('npm');
30
+ if (isNpm) {
31
+ log('📦 检测到当前为 npm 安装环境,正在为您执行更新...');
32
+ try {
33
+ execSync('npm install -g @gird/ccli', { stdio: 'inherit' });
34
+ return { ok: true, message: '更新完成!请重新启动 ccli。' };
35
+ }
36
+ catch (e) {
37
+ return { ok: false, message: `npm 自动升级失败: ${e.message}。请手动运行: npm install -g @gird/ccli` };
38
+ }
39
+ }
40
+ else {
41
+ // SEA 单二进制模式
42
+ const platform = process.platform === 'darwin' ? 'macos' : (process.platform === 'win32' ? 'windows' : 'linux');
43
+ const arch = process.arch === 'arm64' ? 'arm64' : 'x64';
44
+ const suffix = platform === 'windows' ? '.exe' : '';
45
+ const binaryName = `ccli-${platform}-${arch}${suffix}`;
46
+ log(`📥 检测到当前为单二进制运行环境,正在从 GitHub 下载新版本 [${platform}-${arch}]...`);
47
+ const downloadUrl = `https://github.com/GridGit/ai-cli/releases/download/v${latestVersion}/${binaryName}`;
48
+ const tempPath = `${process.execPath}.tmp`;
49
+ const response = await fetch(downloadUrl);
50
+ if (!response.ok || !response.body) {
51
+ return {
52
+ ok: false,
53
+ message: `下载升级文件失败: ${response.statusText}。\n` +
54
+ `如果您的仓库是私有的,请访问 GitHub Releases 手动下载并替换当前二进制。`
55
+ };
56
+ }
57
+ const fileStream = createWriteStream(tempPath);
58
+ await pipeline(Readable.fromWeb(response.body), fileStream);
59
+ if (platform !== 'windows') {
60
+ chmodSync(tempPath, 0o755);
61
+ }
62
+ log('⚙️ 正在原子替换可执行程序...');
63
+ try {
64
+ await rename(tempPath, process.execPath);
65
+ }
66
+ catch (err) {
67
+ if (platform === 'windows') {
68
+ // Windows 锁定运行中的 exe,采用 rename 自身 -> 移动新文件 绕过限制
69
+ try {
70
+ const oldPath = `${process.execPath}.old`;
71
+ await rename(process.execPath, oldPath);
72
+ await rename(tempPath, process.execPath);
73
+ log('💡 Windows 系统热替换成功,旧的备份文件为 .old,重启后可手动删除。');
74
+ }
75
+ catch (winErr) {
76
+ return { ok: false, message: `Windows 原子替换失败: ${winErr.message}。请手动将下载的 ${tempPath} 重命名为 ${process.execPath}。` };
77
+ }
78
+ }
79
+ else {
80
+ return { ok: false, message: `替换可执行程序失败: ${err.message}` };
81
+ }
82
+ }
83
+ return { ok: true, message: `升级成功!当前二进制已被成功更新至 v${latestVersion},请重启 CLI 生效。` };
84
+ }
85
+ }
86
+ catch (e) {
87
+ return { ok: false, message: `升级检测出错: ${e.message}` };
88
+ }
89
+ }
90
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/cli/upgrade.ts"],"names":[],"mappings":"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"}