@ia-ccun/code-agent-cli 0.0.50-beta.9 → 0.0.51-beta.1
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/bin/cli.js +1 -2
- package/config/agent/extensions/aicode-tips.ts +16 -1
- package/config/agent/extensions/bash-check.ts +1 -1
- package/config/agent/extensions/context-monitor.ts +1 -1
- package/config/agent/extensions/context.ts +3 -3
- package/config/agent/extensions/custom-footer.ts +3 -3
- package/config/agent/extensions/custom.ts +27 -20
- package/config/agent/extensions/error-monitor.ts +1 -1
- package/config/agent/extensions/msg-debug.ts +16 -1
- package/config/agent/extensions/review.ts +3 -3
- package/config/agent/extensions/working-msg.ts +2 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
- package/scripts/postinstall.js +4 -4
package/bin/cli.js
CHANGED
|
@@ -193,8 +193,7 @@ async function checkForUpdates() {
|
|
|
193
193
|
}
|
|
194
194
|
checkForUpdates();
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
const piAgentPathUrl = new URL('../node_modules/@mariozechner/pi-coding-agent/dist/cli.js', import.meta.url);
|
|
196
|
+
const piAgentPathUrl = new URL('../node_modules/@earendil-works/pi-coding-agent/dist/cli.js', import.meta.url);
|
|
198
197
|
const piAgentPath = fileURLToPath(piAgentPathUrl); // 解码中文路径
|
|
199
198
|
|
|
200
199
|
// 获取本地版本号
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* 技巧列表包含快捷键、命令使用及联系方式提示
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { ExtensionAPI, ExtensionContext } from "@
|
|
9
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
10
10
|
|
|
11
11
|
const AICODE_TIPS = [
|
|
12
12
|
"@ 快速搜索项目文件",
|
|
@@ -102,6 +102,21 @@ const AICODE_TIPS = [
|
|
|
102
102
|
"插话消息会打断 AI 正在执行的工具,等待响应",
|
|
103
103
|
"排队消息静默等待,AI 空闲时自动发送",
|
|
104
104
|
"可在 /settings 中调整消息发送模式和行为偏好",
|
|
105
|
+
// 记忆功能使用技巧
|
|
106
|
+
"💡 记忆功能自动记录会话中的关键经验,下次会话自动应用",
|
|
107
|
+
"💡 在对话中说'记住这个'可手动保存经验到记忆库",
|
|
108
|
+
"💡 记忆功能支持选择性注入 (selective),只注入相关记忆避免干扰",
|
|
109
|
+
"💡 说'忘记 XXX'可删除特定记忆条目",
|
|
110
|
+
"💡 记忆会在会话结束时自动整合优化,提炼更有价值的经验",
|
|
111
|
+
"💡 记忆功能示例:记住代码规范后,后续开发自动遵循该规范",
|
|
112
|
+
"💡 记忆功能示例:记录常见错误模式,主动避免重复犯错",
|
|
113
|
+
"💡 记忆功能示例:保存项目特定配置,新会话自动加载上下文",
|
|
114
|
+
// Subagent 使用方法
|
|
115
|
+
"🤖 说'使用 subagent 探索当前代码关于权限校验的实现'可快速定位相关代码",
|
|
116
|
+
"🤖 说'使用 subagent 为这个功能制定实施计划'可生成详细的开发步骤",
|
|
117
|
+
"🤖 说'使用 subagent 执行这个计划'可自动完成代码实现",
|
|
118
|
+
"🤖 说'使用 subagent 审查刚写的代码'可获得代码质量反馈",
|
|
119
|
+
"🤖 说'使用 subagent 给这个方案提点意见'可获得第二视角的评估建议",
|
|
105
120
|
// 联系方式提示
|
|
106
121
|
"⚠️ 任何疑问或需求可联系 xujianjiang,支持需求对接开发、系统集成与扩展",
|
|
107
122
|
"⚠️ 内网手册参考 UniDoc《2026.03 AICode Agent CLI 编码智能体使用手册》",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* 危险模式配置: config/agent/dangerous-patterns.json
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import type { ExtensionAPI } from "@
|
|
13
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
14
14
|
import { readFileSync, existsSync } from "fs";
|
|
15
15
|
import { join } from "path";
|
|
16
16
|
import { homedir } from "os";
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* - 100% : 阻止继续并强制提示压缩
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import type { ExtensionAPI, ExtensionContext, ToolResultEvent } from "@
|
|
17
|
+
import type { ExtensionAPI, ExtensionContext, ToolResultEvent } from "@earendil-works/pi-coding-agent";
|
|
18
18
|
|
|
19
19
|
interface ContextThresholds {
|
|
20
20
|
info: number; // 70%
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
* - current context window usage + session totals (tokens/cost)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext, ToolResultEvent } from "@
|
|
13
|
-
import { DynamicBorder } from "@
|
|
14
|
-
import { Container, Key, Text, matchesKey, type Component, type TUI } from "@
|
|
12
|
+
import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext, ToolResultEvent } from "@earendil-works/pi-coding-agent";
|
|
13
|
+
import { DynamicBorder } from "@earendil-works/pi-coding-agent";
|
|
14
|
+
import { Container, Key, Text, matchesKey, type Component, type TUI } from "@earendil-works/pi-tui";
|
|
15
15
|
import os from "node:os";
|
|
16
16
|
import path from "node:path";
|
|
17
17
|
import fs from "node:fs/promises";
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* [gold] [dim] [dim] [color ctx] [accent]
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { AssistantMessage } from "@
|
|
10
|
-
import type { ExtensionAPI } from "@
|
|
11
|
-
import { truncateToWidth, visibleWidth } from "@
|
|
9
|
+
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
10
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
11
|
+
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
12
12
|
|
|
13
13
|
function fmtTokens(n: number): string {
|
|
14
14
|
if (n < 1000) return n.toString();
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* 可以拦截内置工具、注册自定义工具和命令
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { ExtensionAPI } from "@
|
|
12
|
-
import type { AssistantMessage } from "@
|
|
13
|
-
import { truncateToWidth, visibleWidth } from "@
|
|
11
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
12
|
+
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
13
|
+
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
14
14
|
|
|
15
15
|
export default function (pi: ExtensionAPI) {
|
|
16
16
|
// === 记录开始时间 ===
|
|
@@ -23,25 +23,32 @@ export default function (pi: ExtensionAPI) {
|
|
|
23
23
|
// === 消息完成通知(只在最后一条显示)===
|
|
24
24
|
|
|
25
25
|
pi.on("agent_end", async (event, ctx) => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
timeStr
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
26
|
+
try {
|
|
27
|
+
// 检查 ctx 是否仍然有效
|
|
28
|
+
ctx.runtime.assertActive();
|
|
29
|
+
|
|
30
|
+
// 计算耗时
|
|
31
|
+
const elapsed = Date.now() - agentStartTime;
|
|
32
|
+
let timeStr: string;
|
|
33
|
+
if (elapsed < 1000) {
|
|
34
|
+
timeStr = `${elapsed}ms`;
|
|
35
|
+
} else if (elapsed < 60000) {
|
|
36
|
+
timeStr = `${(elapsed / 1000).toFixed(1)}s`;
|
|
37
|
+
} else {
|
|
38
|
+
const mins = Math.floor(elapsed / 60000);
|
|
39
|
+
const secs = Math.floor((elapsed % 60000) / 1000);
|
|
40
|
+
timeStr = `${mins}m ${secs}s`;
|
|
41
|
+
}
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
// 格式化完整时间
|
|
44
|
+
const now = new Date();
|
|
45
|
+
const timeStr2 = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
// agent_end 表示一轮对话结束,显示完成提示
|
|
48
|
+
ctx.ui.notify(`${timeStr2} | ✨ 消息处理完成 (${timeStr})`, "info");
|
|
49
|
+
} catch (e) {
|
|
50
|
+
// ctx 已过期,忽略通知
|
|
51
|
+
}
|
|
45
52
|
});
|
|
46
53
|
|
|
47
54
|
// === 拦截工具调用 ===
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Logs errors to ~/.aicode-cli/logs/aicode-error-YYYY-MM-DD.log
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { ExtensionAPI } from "@
|
|
9
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
10
10
|
import fs from "fs";
|
|
11
11
|
import os from "os";
|
|
12
12
|
import path from "path";
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
import { appendFileSync, existsSync, mkdirSync } from "node:fs";
|
|
17
17
|
import { join } from "node:path";
|
|
18
|
-
import type { ExtensionAPI } from "@
|
|
18
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
19
19
|
|
|
20
20
|
// 北京时间格式化函数 (UTC+8)
|
|
21
21
|
function formatBeijingTime(date: Date = new Date()): string {
|
|
@@ -125,6 +125,21 @@ ${JSON.stringify({ ...payload, messages: filteredMessages }, null, 2)}
|
|
|
125
125
|
const timestamp = formatBeijingTime();
|
|
126
126
|
const { response, usage, cached } = event;
|
|
127
127
|
|
|
128
|
+
// Check if response is defined
|
|
129
|
+
if (!response) {
|
|
130
|
+
const logEntry = `
|
|
131
|
+
================================================================================
|
|
132
|
+
[${timestamp}] AFTER PROVIDER RESPONSE
|
|
133
|
+
================================================================================
|
|
134
|
+
Cached: ${cached ? "YES" : "NO"}
|
|
135
|
+
Error: Response is undefined
|
|
136
|
+
|
|
137
|
+
================================================================================
|
|
138
|
+
`;
|
|
139
|
+
appendFileSync(logFile, logEntry, "utf8");
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
128
143
|
const logEntry = `
|
|
129
144
|
================================================================================
|
|
130
145
|
[${timestamp}] AFTER PROVIDER RESPONSE
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
* Note: PR review requires a clean working tree (no uncommitted changes to tracked files).
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
import type { ExtensionAPI, ExtensionContext, ExtensionCommandContext } from "@
|
|
31
|
-
import { DynamicBorder, BorderedLoader } from "@
|
|
32
|
-
import { Container, type SelectItem, SelectList, Text } from "@
|
|
30
|
+
import type { ExtensionAPI, ExtensionContext, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
31
|
+
import { DynamicBorder, BorderedLoader } from "@earendil-works/pi-coding-agent";
|
|
32
|
+
import { Container, type SelectItem, SelectList, Text } from "@earendil-works/pi-tui";
|
|
33
33
|
import path from "node:path";
|
|
34
34
|
import { promises as fs } from "node:fs";
|
|
35
35
|
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* 自定义工作消息,格式类似 Claude Code: ✶ xxx… (时间 · tokens)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { ExtensionAPI, TurnEndEvent } from "@
|
|
9
|
-
import type { AssistantMessage } from "@
|
|
8
|
+
import type { ExtensionAPI, TurnEndEvent } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
10
10
|
|
|
11
11
|
// 主题色 #49bccf
|
|
12
12
|
const accentColor = "\x1b[38;2;73;188;207m";
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* aicode-cli
|
|
3
3
|
* AI Coding Agent CLI
|
|
4
4
|
*
|
|
5
|
-
* 基于 @mariozechner/pi-coding-agent 的封装
|
|
6
5
|
*/
|
|
7
|
-
export * from '@
|
|
6
|
+
export * from '@earendil-works/pi-coding-agent';
|
|
8
7
|
export { defaultConfig, type AppConfig } from './config.js';
|
|
9
8
|
export { getConfig, getConfigDir, loadConfig } from './config-loader.js';
|
|
10
9
|
export { defaultBanner, generateBanner } from './banner.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,iCAAiC,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGzE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
* aicode-cli
|
|
3
3
|
* AI Coding Agent CLI
|
|
4
4
|
*
|
|
5
|
-
* 基于 @mariozechner/pi-coding-agent 的封装
|
|
6
5
|
*/
|
|
7
|
-
|
|
8
|
-
export * from '@mariozechner/pi-coding-agent';
|
|
6
|
+
export * from '@earendil-works/pi-coding-agent';
|
|
9
7
|
// 导出配置相关
|
|
10
8
|
export { defaultConfig } from './config.js';
|
|
11
9
|
export { getConfig, getConfigDir, loadConfig } from './config-loader.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,iCAAiC,CAAC;AAEhD,SAAS;AACT,OAAO,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEzE,YAAY;AACZ,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ia-ccun/code-agent-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.51-beta.1",
|
|
4
4
|
"description": "AI Coding Agent CLI - 基于OpenClaw🦞底层Agent(pi)原理封装的编码智能体(供学习使用)。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"prepare": "husky"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@
|
|
39
|
-
"@
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
38
|
+
"@earendil-works/pi-agent-core": "^0.74.0",
|
|
39
|
+
"@earendil-works/pi-ai": "^0.74.0",
|
|
40
|
+
"@earendil-works/pi-coding-agent": "^0.74.0",
|
|
41
|
+
"@earendil-works/pi-tui": "^0.74.0"
|
|
42
42
|
},
|
|
43
43
|
"overrides": {
|
|
44
44
|
"glob": "^11.0.0",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"@typescript-eslint/parser": "^8.57.0",
|
|
51
51
|
"eslint": "^10.0.3",
|
|
52
52
|
"husky": "^9.1.7",
|
|
53
|
+
"playwright": "^1.60.0",
|
|
53
54
|
"shx": "^0.4.0",
|
|
54
55
|
"typescript": "^5.7.2",
|
|
55
56
|
"typescript-eslint": "^8.57.0"
|
package/scripts/postinstall.js
CHANGED
|
@@ -21,7 +21,7 @@ const piDir = join(homeDir, '.pi');
|
|
|
21
21
|
// ============================================================================
|
|
22
22
|
// Fix pi-coding-agent APP_NAME
|
|
23
23
|
// ============================================================================
|
|
24
|
-
const piAgentPackageJson = join(__dirname, '..', 'node_modules', '@
|
|
24
|
+
const piAgentPackageJson = join(__dirname, '..', 'node_modules', '@earendil-works', 'pi-coding-agent', 'package.json');
|
|
25
25
|
if (existsSync(piAgentPackageJson)) {
|
|
26
26
|
try {
|
|
27
27
|
const piPkg = JSON.parse(readFileSync(piAgentPackageJson, 'utf-8'));
|
|
@@ -39,7 +39,7 @@ if (existsSync(piAgentPackageJson)) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// Fix pi-coding-agent cli.js process.title
|
|
42
|
-
const piAgentCliJs = join(__dirname, '..', 'node_modules', '@
|
|
42
|
+
const piAgentCliJs = join(__dirname, '..', 'node_modules', '@earendil-works', 'pi-coding-agent', 'dist', 'cli.js');
|
|
43
43
|
if (existsSync(piAgentCliJs)) {
|
|
44
44
|
try {
|
|
45
45
|
let cliContent = readFileSync(piAgentCliJs, 'utf-8');
|
|
@@ -54,7 +54,7 @@ if (existsSync(piAgentCliJs)) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
// Fix pi-coding-agent config.js APP_NAME default
|
|
57
|
-
const piAgentConfigJs = join(__dirname, '..', 'node_modules', '@
|
|
57
|
+
const piAgentConfigJs = join(__dirname, '..', 'node_modules', '@earendil-works', 'pi-coding-agent', 'dist', 'config.js');
|
|
58
58
|
if (existsSync(piAgentConfigJs)) {
|
|
59
59
|
try {
|
|
60
60
|
let configContent = readFileSync(piAgentConfigJs, 'utf-8');
|
|
@@ -69,7 +69,7 @@ if (existsSync(piAgentConfigJs)) {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// Fix pi-coding-agent slash commands - change "Quit pi" to "Quit aicode-cli"
|
|
72
|
-
const slashCommandsJs = join(__dirname, '..', 'node_modules', '@
|
|
72
|
+
const slashCommandsJs = join(__dirname, '..', 'node_modules', '@earendil-works', 'pi-coding-agent', 'dist', 'core', 'slash-commands.js');
|
|
73
73
|
if (existsSync(slashCommandsJs)) {
|
|
74
74
|
try {
|
|
75
75
|
let content = readFileSync(slashCommandsJs, 'utf-8');
|