@ia-ccun/code-agent-cli 0.0.54 → 0.0.56-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 CHANGED
@@ -8,28 +8,10 @@
8
8
  // 设置终端标题
9
9
  process.title = "aicode-cli";
10
10
 
11
- // 防御 CWD 被删: 在所有 import 之前 chdir (node ESM 解析 import 时会读 cwd)
12
- // 不 import os.homedir() 因为那需要模块解析, 此时 cwd 还没改
13
- // 用 process.env.PWD 优先 (用户启动目录) → HOME fallback (防 PWD 缺失 ENOENT)
14
- // 先 PWD 试 (用户启动目录), 失败 fallback HOME (cwd 被删时 PWD 也指向已删目录, chdir 会抛 ENOENT)
15
- // catch 后再退一步: HOME 也失败则 chdir 到 / (绝对保证不会 ENOENT)
16
- try {
17
- process.chdir(process.env.PWD);
18
- } catch {
19
- try {
20
- process.chdir(process.env.HOME || "/");
21
- } catch {
22
- try {
23
- process.chdir("/");
24
- } catch {}
25
- }
26
- }
27
-
28
11
  import { spawn } from "child_process";
29
12
  import { fileURLToPath } from "url";
30
13
  import { dirname, join } from "path";
31
14
  import { existsSync, readFileSync, writeFileSync } from "fs";
32
- import { getConfig, getConfigDir, loadConfig } from "../dist/config-loader.js";
33
15
 
34
16
  const __filename = fileURLToPath(import.meta.url);
35
17
  const __dirname = dirname(__filename);
@@ -168,7 +150,6 @@ replaceCLIVersionPlaceholder();
168
150
  const localVersion = getLocalVersion();
169
151
  process.env.AICODE_CLI_VERSION = localVersion || "";
170
152
 
171
-
172
153
  async function checkForUpdates() {
173
154
  try {
174
155
  const { execFileSync } = await import("child_process");
@@ -0,0 +1,150 @@
1
+ /**
2
+ * @author: xujianjiang
3
+ * aicode-changelog extension
4
+ *
5
+ * 在 `session_start` 触发时从 <package>/config/changelog.md 读取最新 Release Note 并打印.
6
+ * 借鉴 aicode-banner: 走 ctx.ui.notify 不直写 console, 只在 startup + hasUI 时触发.
7
+ *
8
+ * ponytail:
9
+ * - 直接 fs.readFileSync 运行时发布的 changelog.md, 不二次拷贝
10
+ * - 用 ~/.aicode-cli/.changelog-seen.json 标记已读版本, 避免每次启动都刷屏
11
+ * - 跳过 RPC/JSON 模式 (无 UI) 和 resume/new/fork (非首次启动)
12
+ *
13
+ * 发布流程: 在 config/changelog.md 顶部加一段 `### Release Note: vX.Y.Z` 即可,
14
+ * 下次启动时若 marker 没记录过该版本则自动展示一次.
15
+ */
16
+
17
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
18
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
19
+ import { dirname, isAbsolute, join } from "node:path";
20
+ import { homedir } from "node:os";
21
+
22
+ /** 当前包的 name, 用于从 node_modules 树里识别 package 根 */
23
+ const PACKAGE_NAME = "@ia-ccun/code-agent-cli";
24
+
25
+ /** 运行时随包发布的 changelog 路径 (相对 package 根, config/ 在 package.json "files" 里自动 ship) */
26
+ const CHANGELOG_REL = "config/changelog.md";
27
+
28
+ /** 标记文件路径, 记录已经展示过哪个版本的 changelog */
29
+ const MARKER_PATH = join(homedir(), ".aicode-cli", ".changelog-seen.json");
30
+
31
+ /** 找 package 根: 从 process.argv[1] (pi-coding-agent 入口) 向上找 package.json. */
32
+ function findPackageRoot(): string | null {
33
+ const entry = process.argv[1];
34
+ if (!entry || !isAbsolute(entry)) return null;
35
+ let dir = dirname(entry);
36
+ while (dir !== dirname(dir)) {
37
+ const pkgPath = join(dir, "package.json");
38
+ if (existsSync(pkgPath)) {
39
+ try {
40
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8")) as {
41
+ name?: unknown;
42
+ };
43
+ if (pkg.name === PACKAGE_NAME) return dir;
44
+ } catch {
45
+ // 损坏的 package.json 跳过, 继续往上找
46
+ }
47
+ }
48
+ dir = dirname(dir);
49
+ }
50
+ return null;
51
+ }
52
+
53
+ /** 读取并解析 changelog.md 的最新 (顶部) Release Note 段. 失败返回 null. */
54
+ function readLatestReleaseNote(): { version: string; content: string } | null {
55
+ const root = findPackageRoot();
56
+ if (!root) return null;
57
+
58
+ let raw: string;
59
+ try {
60
+ raw = readFileSync(join(root, CHANGELOG_REL), "utf-8");
61
+ } catch {
62
+ return null;
63
+ }
64
+
65
+ // 按 "### Release Note: " 切分, 取第一段
66
+ const sections = raw.split(/^### Release Note: /m);
67
+ if (sections.length < 2) return null;
68
+
69
+ const head = sections[1]!;
70
+ const newlineIdx = head.indexOf("\n");
71
+ if (newlineIdx < 0) return null;
72
+
73
+ // 第一行是版本号 (e.g. "v0.0.53-beta.1"), 后面是正文; 去掉末尾 --- 分隔符和空行
74
+ const version = head.slice(0, newlineIdx).trim().replace(/^v/, "");
75
+ const content = head
76
+ .slice(newlineIdx + 1)
77
+ .replace(/\n*---\s*$/, "")
78
+ .trim();
79
+ if (!version || !content) return null;
80
+
81
+ return { version, content };
82
+ }
83
+
84
+ /** 轻度清理 markdown, 让 TUI 通知渲染得清爽一点. */
85
+ function cleanMarkdown(md: string): string {
86
+ return md
87
+ .replace(/^####\s+/gm, "") // 去掉 #### 前缀
88
+ .replace(/\*\*([^*]+)\*\*/g, "$1") // 去掉 ** 加粗
89
+ .replace(/`([^`]+)`/g, "$1"); // 去掉 ` code `
90
+ }
91
+
92
+ /** 读取已展示过的版本号, 失败返回 null. */
93
+ function readShownVersion(): string | null {
94
+ try {
95
+ if (!existsSync(MARKER_PATH)) return null;
96
+ const data = JSON.parse(readFileSync(MARKER_PATH, "utf-8")) as {
97
+ version?: unknown;
98
+ };
99
+ return typeof data.version === "string" ? data.version : null;
100
+ } catch {
101
+ return null;
102
+ }
103
+ }
104
+
105
+ /** 写入已展示的版本号, 失败静默忽略. */
106
+ function writeShownVersion(version: string): void {
107
+ try {
108
+ const dir = join(homedir(), ".aicode-cli");
109
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
110
+ writeFileSync(
111
+ MARKER_PATH,
112
+ JSON.stringify({ version, shownAt: Date.now() }, null, 2),
113
+ );
114
+ } catch {
115
+ // 标记失败不影响主流程
116
+ }
117
+ }
118
+
119
+ /** 拼接展示文本, 过长时截断. */
120
+ function buildDisplay(version: string, content: string, maxLen = 2000): string {
121
+ const text = `📋 v${version} 更新内容\n\n${content}`;
122
+ if (text.length <= maxLen) return text;
123
+ return `${text.slice(0, maxLen)}\n\n… (内容过长已截断, 完整内容见 changelog.md)`;
124
+ }
125
+
126
+ export default function (pi: ExtensionAPI) {
127
+ pi.on("session_start", (event, ctx) => {
128
+ // 只在 startup 打印, resume/new/fork 不重复刷屏 (与 aicode-banner 一致)
129
+ if (event.reason !== "startup") return;
130
+ // 没有 TUI (纯 RPC/JSON 模式) 不打印, 避免污染 stdout
131
+ if (!ctx.hasUI) return;
132
+
133
+ const note = readLatestReleaseNote();
134
+ // 读不到 changelog.md (老 package 没 ship / 文件格式异常) 或解析失败, 跳过
135
+ if (!note) return;
136
+ // 已经展示过该版本, 跳过 (避免每次启动都刷屏)
137
+ if (readShownVersion() === note.version) return;
138
+
139
+ // 渲染: 清理 markdown + 剥掉 ANSI 控制符 (TUI notify 不期望转义码)
140
+ const ansi = /\x1b\[[\d;]*m/g;
141
+ const text = buildDisplay(note.version, cleanMarkdown(note.content)).replace(
142
+ ansi,
143
+ "",
144
+ );
145
+ ctx.ui.notify(text, "info");
146
+
147
+ // 标记已读
148
+ writeShownVersion(note.version);
149
+ });
150
+ }
@@ -0,0 +1,98 @@
1
+ # Changelog
2
+
3
+ ### Release Note: v0.0.56
4
+
5
+ 本次为内部清理版本,简化 CLI 启动流程。建议所有用户升级。
6
+
7
+ #### 🔧 重构 (Refactor)
8
+
9
+ - **简化 CLI 启动流程**
10
+ - 移除 `bin/cli.js` 入口的 cwd 兜底逻辑(`process.chdir(PWD || homedir())` 及 `homedir` import)。
11
+ - 行为契约:cwd 被外部删除时 aicode 以原始 ENOENT 失败,不再静默跳转到 home。
12
+
13
+
14
+ #### ✅ 回归测试 (Regression)
15
+
16
+ - 7/7 case 通过(01-07)。
17
+
18
+ ---
19
+
20
+ ### Release Note: v0.0.53-beta.1
21
+
22
+ 本次为底层依赖升级版本,不引入功能变更,建议所有用户升级。
23
+
24
+ #### 🔧 依赖升级 (Dependency)
25
+
26
+ - 升级 4 个 pi 包到 ^0.85
27
+
28
+ #### ✨ 自带新能力 (Upstream Features)
29
+
30
+ - **`pi.on()` 返回 unsubscribe**:扩展可清理已订阅的事件 handler。
31
+
32
+ #### 📦 兼容性 (Compatibility)
33
+
34
+ - 自带 14 个扩展 100% 兼容 0.85.1,无需修改。
35
+ - RPC 协议层(与 aicode-idea-plugin-swing Kotlin 客户端)向后兼容,无需客户端升级。
36
+
37
+ #### 🐞 已验证修复 (Verified Upstream Fixes)
38
+
39
+ - `toolcall_start` 事件补全 id/name(0.84.3)
40
+ - In-memory session fork 在 turn 未 settled 时的崩溃(0.85.0)
41
+ - 全屏 transcript 渲染稳定性优化
42
+
43
+ ---
44
+
45
+ ### Release Note: v0.0.46
46
+
47
+ 感谢您的关注与使用!本次发布带来了多项功能增强、体验优化及关键问题修复,进一步提升工具的稳定性与智能化协作能力。
48
+
49
+ ---
50
+
51
+ #### ✨ 新特性 (New Features)
52
+
53
+ - **推荐使用更高效的命令行工具**
54
+ - 推荐使用 `fd` 替代 `find`,实现更快的文件搜索。
55
+ - 推荐使用 `rg`(ripgrep)替代 `grep`,获得更强大的文本搜索能力。
56
+ - 相关工具路径说明已记录在 `APPEND_SYSTEM.md` 中,便于查阅和配置。
57
+
58
+ - **完整时间戳显示于 Agent 完成消息**
59
+ - 在任务完成提示中增加年月日信息,提升日志可读性。
60
+ - 格式示例:`2026-04-15 09:45:40 | ✨ 消息处理完成`
61
+
62
+ - **AI 协作者签名机制正式引入**
63
+ - 提交信息中自动添加 `Co-Authored-By` 签名块,标识 AI 参与协作。
64
+ - 更新 `APPEND_SYSTEM.md` 中对 Agent 的描述说明。
65
+ - 在 Git 提交提示(prompt)中增加 AI 签名要求。
66
+ - 提交技能(commit skill)已更新以支持标准签名格式。
67
+
68
+ ---
69
+
70
+ #### 🐞 问题修复 (Bug Fixes)
71
+
72
+ - **修复自定义文件覆盖问题**
73
+ - 修复安装过程中 `custom.ts` 扩展文件未强制覆盖的问题,确保配置更新生效。
74
+
75
+ - **修正 npm 包名错误**
76
+ - 将 `/update` 命令中的包名从 `@ia-ccun/aicode-cli` 正确更新为 `@ia-ccun/code-agent-cli`,避免更新失败。
77
+
78
+ - **修复示例代码块格式问题**
79
+ - 为 `git-commit.md` 与 `git-worktree.md` 中的示例代码块添加代码围栏(code fences),提升可读性与 Markdown 渲染正确性。
80
+
81
+ ---
82
+
83
+ #### 📦 配置与文档更新
84
+
85
+ - 将 `SYSTEM.md` 和 `APPEND_SYSTEM.md` 加入强制覆盖文件列表,确保核心系统文档保持最新。
86
+ - 更新版本号至 `0.0.46`。
87
+
88
+ ---
89
+
90
+ > 💡 **提示**:我们持续优化开发体验,建议所有用户升级至最新版本以获取最佳功能支持。
91
+
92
+ 感谢 AICode CLI 的智能协作为本版本作出的重要贡献!
93
+
94
+ 🚀 **升级命令**:
95
+
96
+ ```bash
97
+ npm install -g @ia-ccun/code-agent-cli
98
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ia-ccun/code-agent-cli",
3
- "version": "0.0.54",
3
+ "version": "0.0.56-beta.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1 +1 @@
1
- 72167
1
+ 40743
@@ -1 +1 @@
1
- /Users/jianjiang/.aicode-regression-72044-1696000
1
+ /Users/jianjiang/.aicode-regression-40721-0710000