@ia-ccun/code-agent-cli 0.0.52-release → 0.0.53-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.
Files changed (75) hide show
  1. package/bin/cli.js +6 -2
  2. package/config/agent/bin/README.md +102 -0
  3. package/config/agent/extensions/aicode-advisor.ts +13 -0
  4. package/config/agent/extensions/aicode-btw.ts +66 -14
  5. package/config/agent/extensions/aicode-cd.ts +834 -0
  6. package/config/agent/extensions/aicode-grillMe.ts +198 -0
  7. package/config/agent/extensions/aicode-pets.ts +362 -0
  8. package/config/agent/extensions/aicode-safety-guard.ts +552 -0
  9. package/config/agent/extensions/aicode-tips.ts +70 -16
  10. package/config/agent/extensions/aicode-todo-progress.ts +547 -0
  11. package/config/agent/extensions/custom.ts +93 -95
  12. package/config/agent/extensions/error-monitor.ts +1 -18
  13. package/config/agent/extensions/ponytail.ts +441 -0
  14. package/config/agent/extensions/tps.ts +87 -0
  15. package/config/agent/extensions/working-msg.ts +165 -50
  16. package/config/agent/help.md +0 -7
  17. package/config/agent/models.json +7 -7
  18. package/config/agent/settings.json +2 -1
  19. package/config/agent/skills/chroma/LICENSE +21 -0
  20. package/config/agent/skills/chroma/chroma-local/SKILL.md +165 -0
  21. package/config/agent/skills/chroma/chroma-local/cli.md +48 -0
  22. package/config/agent/skills/chroma/chroma-local/data-model.md +103 -0
  23. package/config/agent/skills/chroma/chroma-local/error-handling/python.md +166 -0
  24. package/config/agent/skills/chroma/chroma-local/error-handling/typescript.md +231 -0
  25. package/config/agent/skills/chroma/chroma-local/local-chroma/python.md +95 -0
  26. package/config/agent/skills/chroma/chroma-local/local-chroma/typescript.md +101 -0
  27. package/config/agent/skills/chroma/chroma-local/metadata/python.md +154 -0
  28. package/config/agent/skills/chroma/chroma-local/metadata/typescript.md +153 -0
  29. package/config/agent/skills/chroma/chroma-local/querying/python.md +147 -0
  30. package/config/agent/skills/chroma/chroma-local/querying/typescript.md +157 -0
  31. package/config/agent/skills/chroma/chroma-local/regex/python.md +69 -0
  32. package/config/agent/skills/chroma/chroma-local/regex/typescript.md +71 -0
  33. package/config/agent/skills/chroma/chroma-local/understanding-a-codebase.md +80 -0
  34. package/config/agent/skills/chroma/chroma-local/updating-deleting/python.md +159 -0
  35. package/config/agent/skills/chroma/chroma-local/updating-deleting/typescript.md +228 -0
  36. package/config/agent/skills/milvus-skill/LICENSE +202 -0
  37. package/config/agent/skills/milvus-skill/README.md +37 -0
  38. package/config/agent/skills/milvus-skill/SKILL.md +259 -0
  39. package/config/agent/skills/milvus-skill/references/collection.md +86 -0
  40. package/config/agent/skills/milvus-skill/references/database.md +24 -0
  41. package/config/agent/skills/milvus-skill/references/index.md +69 -0
  42. package/config/agent/skills/milvus-skill/references/partition.md +29 -0
  43. package/config/agent/skills/milvus-skill/references/patterns.md +150 -0
  44. package/config/agent/skills/milvus-skill/references/user-role.md +90 -0
  45. package/config/agent/skills/milvus-skill/references/vector.md +247 -0
  46. package/config/agent/skills/ponytail/SKILL.md +100 -0
  47. package/config/agent/skills/ponytail-audit/SKILL.md +40 -0
  48. package/config/agent/skills/ponytail-debt/SKILL.md +44 -0
  49. package/config/agent/skills/ponytail-help/SKILL.md +68 -0
  50. package/config/agent/skills/ponytail-review/SKILL.md +56 -0
  51. package/config/agent/skills/zread/README.md +115 -0
  52. package/config/agent/skills/zread/SKILL.md +103 -0
  53. package/config/agent/skills/zread/references/stdio-protocol.md +312 -0
  54. package/package.json +6 -5
  55. package/scripts/postinstall.js +58 -1
  56. package/scripts/regression/README.md +224 -0
  57. package/scripts/regression/cases/01-version-and-deps.sh +94 -0
  58. package/scripts/regression/cases/02-extension-loading.sh +130 -0
  59. package/scripts/regression/cases/03-rpc-protocol.sh +259 -0
  60. package/scripts/regression/cases/04-prompt-stream.sh +130 -0
  61. package/scripts/regression/cases/05-slash-commands-and-skills.sh +119 -0
  62. package/scripts/regression/cases/06-tool-execution.sh +115 -0
  63. package/scripts/regression/cases/07-pi-new-features.sh +141 -0
  64. package/scripts/regression/lib/common.sh +287 -0
  65. package/scripts/regression/results/.last_pid +1 -0
  66. package/scripts/regression/results/.last_workdir +1 -0
  67. package/scripts/regression/results/02-extension-loading.log +29 -0
  68. package/scripts/regression/results/03-prompt-stream.log +25 -0
  69. package/scripts/regression/results/03-rpc-protocol.log +38 -0
  70. package/scripts/regression/results/04-slash-commands-and-skills.log +10 -0
  71. package/scripts/regression/results/05-tool-execution.log +6 -0
  72. package/scripts/regression/results/06-pi-new-features.log +33 -0
  73. package/scripts/regression/run-all.sh +187 -0
  74. package/config/agent/dangerous-patterns.json +0 -106
  75. package/config/agent/extensions/bash-check.ts +0 -227
@@ -2,7 +2,7 @@
2
2
  * @author: xujianjiang
3
3
  * 自定义扩展示例
4
4
  *
5
- * 放置位置: config/agent/extensions/
5
+ * 放置位置:config/agent/extensions/
6
6
  * 安装后会复制到 ~/.pi/agent/extensions/
7
7
  *
8
8
  * 可以拦截内置工具、注册自定义工具和命令
@@ -10,82 +10,66 @@
10
10
 
11
11
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
12
12
  import type { AssistantMessage } from "@earendil-works/pi-ai";
13
- import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
14
13
 
15
14
  export default function (pi: ExtensionAPI) {
16
15
  // === 记录开始时间 ===
17
16
  let agentStartTime = 0;
18
17
 
19
- pi.on("agent_start", async () => {
20
- agentStartTime = Date.now();
21
- });
22
-
23
- // === 消息完成通知(只在最后一条显示)===
18
+ // === 拦截工具调用 ===
24
19
 
25
- pi.on("agent_end", async (event, ctx) => {
20
+ pi.on("tool_call", async (event, ctx) => {
26
21
  try {
27
- // 计算耗时
28
- const elapsed = Date.now() - agentStartTime;
29
- let timeStr: string;
30
- if (elapsed < 1000) {
31
- timeStr = `${elapsed}ms`;
32
- } else if (elapsed < 60000) {
33
- timeStr = `${(elapsed / 1000).toFixed(1)}s`;
34
- } else {
35
- const mins = Math.floor(elapsed / 60000);
36
- const secs = Math.floor((elapsed % 60000) / 1000);
37
- timeStr = `${mins}m ${secs}s`;
22
+ // 拦截 login 工具 - 阻止执行
23
+ if (event.toolName === "login") {
24
+ await ctx.ui.notify("⚠️ login 功能已禁用", "warning");
25
+ return { block: true, reason: "login 功能已禁用" };
38
26
  }
39
27
 
40
- // 格式化完整时间
41
- const now = new Date();
42
- 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')}`;
43
-
44
- // agent_end 表示一轮对话结束,显示完成提示
45
- ctx.ui.notify(`${timeStr2} | ✨ 消息处理完成 (${timeStr})`, "info");
28
+ // 拦截 logout 工具 - 阻止执行
29
+ if (event.toolName === "logout") {
30
+ await ctx.ui.notify("⚠️ logout 功能已禁用", "warning");
31
+ return { block: true, reason: "logout 功能已禁用" };
32
+ }
46
33
  } catch (e) {
47
34
  // 忽略错误(ctx 可能已过期)
48
35
  }
49
36
  });
50
37
 
51
- // === 拦截工具调用 ===
52
-
53
- pi.on("tool_call", async (event, ctx) => {
54
- // 拦截 login 工具 - 阻止执行
55
- if (event.toolName === "login") {
56
- await ctx.ui.notify("⚠️ login 功能已禁用", "warning");
57
- return { block: true, reason: "login 功能已禁用" };
58
- }
59
-
60
- // 拦截 logout 工具 - 阻止执行
61
- if (event.toolName === "logout") {
62
- await ctx.ui.notify("⚠️ logout 功能已禁用", "warning");
63
- return { block: true, reason: "logout 功能已禁用" };
64
- }
65
- });
66
-
67
38
  // === 注册自定义命令 ===
68
39
 
69
40
  pi.registerCommand("hello", {
70
41
  description: "打招呼命令",
71
42
  usage: "/hello [名字]",
72
43
  handler: async (args, ctx) => {
73
- const name = args || "大佬,您吃了吗";
74
- ctx.ui.notify(`你好,${name}!🤝`, "info");
44
+ try {
45
+ const name = args || "大佬,您吃了吗";
46
+ ctx.ui.notify(`你好,${name}!🤝`, "info");
47
+ } catch (e) {
48
+ // 忽略错误
49
+ }
75
50
  },
76
51
  });
77
52
 
78
53
  pi.registerCommand("status", {
79
54
  description: "显示当前会话状态",
80
55
  handler: async (_args, ctx) => {
81
- const info = `
56
+ try {
57
+ // 保存需要的数据,避免多次触发 getter
58
+ const model = ctx.session.model?.name || "未知";
59
+ const workspace = ctx.session.workspace || "未知";
60
+ const messages = ctx.session.messages?.length || 0;
61
+
62
+ const info = `
82
63
  📊 会话状态
83
64
 
84
- - 当前模型: ${ctx.session.model?.name || "未知"}
85
- - 项目目录: ${ctx.session.workspace || "未知"}
86
- - 消息数量: ${ctx.session.messages?.length || 0}
65
+ - 当前模型:${model}
66
+ - 项目目录:${workspace}
67
+ - 消息数量:${messages}
87
68
  `.trim();
88
- ctx.ui.notify(info, "info");
69
+ ctx.ui.notify(info, "info");
70
+ } catch (e) {
71
+ // 忽略错误(ctx 可能已过期)
72
+ }
89
73
  },
90
74
  });
91
75
 
@@ -93,35 +77,33 @@ export default function (pi: ExtensionAPI) {
93
77
  description: "清理当前会话上下文",
94
78
  usage: "/clear",
95
79
  handler: async (_args, ctx) => {
96
- // 获取当前会话条目数
97
- const entries = ctx.sessionManager.getBranch();
98
- const msgCount = entries.filter(e => e.type === "message").length;
99
-
100
- if (msgCount === 0) {
101
- ctx.ui.notify("会话已经是空的", "info");
102
- return;
103
- }
104
-
105
- // 确认清理
106
- const ok = await ctx.ui.confirm("清理会话", `确定要清理当前会话的所有 ${msgCount} 条消息吗?`);
107
- if (!ok) {
108
- ctx.ui.notify("已取消", "info");
109
- return;
110
- }
80
+ try {
81
+ // 获取当前会话条目数(在 await 前完成所有 ctx 访问)
82
+ const entries = ctx.sessionManager.getBranch();
83
+ const msgCount = entries.filter(e => e.type === "message").length;
84
+ const uiContext = ctx.ui; // ← 保存 UI context
85
+
86
+ if (msgCount === 0) {
87
+ uiContext.notify("会话已经是空的", "info");
88
+ return;
89
+ }
111
90
 
112
- // 创建新会话来清空上下文
113
- const result = await ctx.newSession({
114
- setup: async (_sm) => {
115
- // 新会话默认为空
116
- },
117
- });
91
+ // 确认清理
92
+ const ok = await uiContext.confirm("清理会话", `确定要清理当前会话的所有 ${msgCount} 条消息吗?`);
93
+ if (!ok) {
94
+ uiContext.notify("已取消", "info");
95
+ return;
96
+ }
118
97
 
119
- if (result.cancelled) {
120
- ctx.ui.notify("已取消", "info");
121
- return;
98
+ // 创建新会话来清空上下文
99
+ await ctx.newSession({
100
+ withSession: async (newCtx) => {
101
+ newCtx.ui.notify(`✅ 已清理 ${msgCount} 条消息,进入新会话`, "success");
102
+ },
103
+ });
104
+ } catch (e) {
105
+ // 忽略错误(ctx 可能已过期)
122
106
  }
123
-
124
- ctx.ui.notify(`✅ 已清理 ${msgCount} 条消息,进入新会话`, "success");
125
107
  },
126
108
  });
127
109
 
@@ -131,8 +113,12 @@ export default function (pi: ExtensionAPI) {
131
113
  description: "退出当前会话",
132
114
  usage: "/exit",
133
115
  handler: async (_args, ctx) => {
134
- ctx.ui.notify("👋 再见!", "info");
135
- ctx.shutdown();
116
+ try {
117
+ ctx.ui.notify("👋 再见!", "info");
118
+ ctx.shutdown();
119
+ } catch (e) {
120
+ // 忽略错误
121
+ }
136
122
  },
137
123
  });
138
124
 
@@ -142,28 +128,40 @@ export default function (pi: ExtensionAPI) {
142
128
  description: "更新 aicode-cli 工具",
143
129
  usage: "/update",
144
130
  handler: async (_args, ctx) => {
145
- const ok = await ctx.ui.confirm("更新确认", "确定要更新 aicode-cli 吗?");
146
- if (!ok) {
147
- ctx.ui.notify("已取消", "info");
148
- return;
149
- }
150
-
151
- ctx.ui.notify("🔄 正在更新 aicode-cli...", "info");
152
- const { exec } = await import("child_process");
153
- exec("npm install -g @ia-ccun/code-agent-cli", (error, stdout, stderr) => {
154
- if (error) {
155
- ctx.ui.notify(`❌ 更新失败: ${error.message},请重试`, "error");
156
- } else {
157
- ctx.ui.notify("✅ aicode-cli 更新成功!请重启 CLI", "success");
131
+ try {
132
+ // ← 在 await 前保存 UI context
133
+ const uiContext = ctx.ui;
134
+
135
+ const ok = await uiContext.confirm("更新确认", "确定要更新 aicode-cli 吗?");
136
+ if (!ok) {
137
+ uiContext.notify("已取消", "info");
138
+ return;
158
139
  }
159
- });
140
+
141
+ uiContext.notify("🔄 正在更新 aicode-cli...", "info");
142
+
143
+ // 使用 Promise 包装 exec
144
+ const { exec } = await import("child_process");
145
+ await new Promise<void>((resolve) => {
146
+ exec("npm install -g @ia-ccun/code-agent-cli", (error, stdout, stderr) => {
147
+ if (error) {
148
+ uiContext.notify(`❌ 更新失败:${error.message},请重试`, "error");
149
+ } else {
150
+ uiContext.notify("✅ aicode-cli 更新成功!请重启 CLI", "success");
151
+ }
152
+ resolve();
153
+ });
154
+ });
155
+ } catch (e) {
156
+ // 忽略错误(ctx 可能已过期)
157
+ }
160
158
  },
161
159
  });
162
160
 
163
161
  // === 注册自定义工具 ===
164
162
 
165
- // 注意: 注册自定义工具需要更复杂的参数定义
166
- // 详情请参考: https://github.com/mariozechner/pi-coding-agent/docs/extensions.md
163
+ // 注意:注册自定义工具需要更复杂的参数定义
164
+ // 详情请参考:https://github.com/mariozechner/pi-coding-agent/docs/extensions.md
167
165
 
168
166
  // === 注册 /version 命令 ===
169
167
 
@@ -204,7 +202,7 @@ export default function (pi: ExtensionAPI) {
204
202
  (latestParts[0] === localParts[0] && latestParts[1] === localParts[1] && latestParts[2] > localParts[2]);
205
203
 
206
204
  if (needsUpdate) {
207
- updateMsg = `\n\n⚠️ 发现新版本 v${localVersion} → v${latestVersion}\n 运行: npm install -g @ia-ccun/code-agent-cli`;
205
+ updateMsg = `\n\n⚠️ 发现新版本 v${localVersion} → v${latestVersion}\n 运行:npm install -g @ia-ccun/code-agent-cli`;
208
206
  } else {
209
207
  updateMsg = "\n\n✅ 已是最新版本";
210
208
  }
@@ -215,8 +213,8 @@ export default function (pi: ExtensionAPI) {
215
213
  const info = `
216
214
  📦 版本信息
217
215
 
218
- 当前版本: v${localVersion}
219
- 最新版本: v${latestVersion}
216
+ 当前版本:v${localVersion}
217
+ 最新版本:v${latestVersion}
220
218
  ${updateMsg}
221
219
  `.trim();
222
220
 
@@ -122,22 +122,5 @@ export default function (pi: ExtensionAPI) {
122
122
  }
123
123
  });
124
124
 
125
- // Summary on session shutdown
126
- pi.on("session_shutdown", () => {
127
- const uptime = Math.round((Date.now() - startTime) / 1000);
128
- const totalErrors = toolErrorCount + bashErrorCount;
129
-
130
- if (totalErrors > 0) {
131
- console.log(`
132
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
133
- 📊 Error Monitor 会话统计
134
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
135
- 总错误数: ${totalErrors}
136
- 工具错误数: ${toolErrorCount}
137
- Bash 错误数: ${bashErrorCount}
138
- 运行时长: ${uptime}秒
139
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
140
- `);
141
- }
142
- });
125
+ // Session shutdown - silent (errors already logged to file)
143
126
  }