@unifan/pi-unifan-zh 1.0.5 → 1.0.7

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.
@@ -0,0 +1,216 @@
1
+ import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
+ import {
3
+ commitWithMsg,
4
+ getChangedFiles,
5
+ getStagedDiff,
6
+ getUnstagedDiff,
7
+ isGitRepo,
8
+ pushCurrentBranch,
9
+ stageAll,
10
+ } from "./src/git.js";
11
+ import { COMMIT_SYSTEM_PROMPT } from "./src/prompt.ts";
12
+
13
+ interface ParsedCommitArgs {
14
+ yes: boolean;
15
+ stageAll: boolean;
16
+ hint?: string;
17
+ }
18
+
19
+ function parseArgs(raw: string): ParsedCommitArgs {
20
+ const tokens = raw.trim().split(/\s+/).filter(Boolean);
21
+ let yes = false;
22
+ let shouldStageAll = false;
23
+ const hintParts: string[] = [];
24
+
25
+ for (const t of tokens) {
26
+ if (t === "-y" || t === "--yes") {
27
+ yes = true;
28
+ } else if (t === "-a" || t === "--all") {
29
+ shouldStageAll = true;
30
+ } else {
31
+ hintParts.push(t);
32
+ }
33
+ }
34
+
35
+ return {
36
+ yes,
37
+ stageAll: shouldStageAll,
38
+ hint: hintParts.join(" ").trim() || undefined,
39
+ };
40
+ }
41
+
42
+ async function generateCommitMessage(
43
+ ctx: ExtensionCommandContext,
44
+ diff: string,
45
+ changedFiles: string[],
46
+ userHint?: string,
47
+ ): Promise<string> {
48
+ const truncatedDiff = diff.length > 30000 ? diff.slice(0, 30000) + "\n\n... (diff已截断)" : diff;
49
+ const userPrompt = [
50
+ `## 修改的文件清单 (${changedFiles.length} 个文件):`,
51
+ changedFiles.map((f) => `- ${f}`).join("\n"),
52
+ "",
53
+ userHint ? `## 用户额外补充说明:\n${userHint}\n` : "",
54
+ "## Git Diff 变动详情:",
55
+ "```diff",
56
+ truncatedDiff,
57
+ "```",
58
+ ]
59
+ .filter(Boolean)
60
+ .join("\n");
61
+
62
+ if (ctx.model && ctx.modelRegistry) {
63
+ try {
64
+ const provider = ctx.modelRegistry.getProvider(ctx.model.provider);
65
+ if (provider) {
66
+ const response = await provider
67
+ .streamSimple(
68
+ ctx.model,
69
+ {
70
+ systemPrompt: COMMIT_SYSTEM_PROMPT,
71
+ messages: [
72
+ {
73
+ role: "user",
74
+ content: [{ type: "text", text: userPrompt }],
75
+ timestamp: Date.now(),
76
+ },
77
+ ],
78
+ },
79
+ { maxTokens: 800 },
80
+ )
81
+ .result();
82
+
83
+ const text = response.content
84
+ ?.map((c) => (c.type === "text" ? c.text : ""))
85
+ .join("")
86
+ .trim();
87
+
88
+ if (text) {
89
+ // Clean any unexpected code blocks
90
+ return text.replace(/^```[a-zA-Z]*\n?/, "").replace(/\n?```$/, "").trim();
91
+ }
92
+ }
93
+ } catch {
94
+ /* fallback below */
95
+ }
96
+ }
97
+
98
+ // Simple heuristic fallback
99
+ const firstFile = changedFiles[0] ?? "core";
100
+ const scope = firstFile.split(/[/\\]/)[0] || "core";
101
+ return `chore(${scope}): 更新代码与相关配置\n\n- 更新了 ${changedFiles.length} 个文件`;
102
+ }
103
+
104
+ export default function (pi: ExtensionAPI) {
105
+ const handleCommitCommand = async (args: string, ctx: ExtensionCommandContext, andPush = false) => {
106
+ const notify = (msg: string, level: "info" | "warning" | "error" = "info") => {
107
+ if (ctx.hasUI) ctx.ui.notify(msg, level);
108
+ else console.log(`pi-commit: ${msg}`);
109
+ };
110
+
111
+ if (!(await isGitRepo(ctx.cwd))) {
112
+ notify("当前目录不是 Git 仓库,无法执行 commit。", "error");
113
+ return;
114
+ }
115
+
116
+ const parsed = parseArgs(args);
117
+ let stagedDiff = await getStagedDiff(ctx.cwd);
118
+ const unstagedDiff = await getUnstagedDiff(ctx.cwd);
119
+ const changedFiles = await getChangedFiles(ctx.cwd);
120
+
121
+ if (!stagedDiff && !unstagedDiff) {
122
+ notify("当前工作区没有任何修改,无需提交。", "info");
123
+ return;
124
+ }
125
+
126
+ if (!stagedDiff && unstagedDiff) {
127
+ notify("未发现暂存区文件,已自动暂存全部修改 (git add -A)...", "info");
128
+ await stageAll(ctx.cwd);
129
+ stagedDiff = await getStagedDiff(ctx.cwd);
130
+ } else if (parsed.stageAll) {
131
+ await stageAll(ctx.cwd);
132
+ stagedDiff = await getStagedDiff(ctx.cwd);
133
+ }
134
+
135
+ notify("正在深度分析代码改动并生成中文 Commit Message...", "info");
136
+ const commitMessage = await generateCommitMessage(ctx, stagedDiff || unstagedDiff, changedFiles, parsed.hint);
137
+
138
+ let finalMessage = commitMessage;
139
+
140
+ if (!parsed.yes && ctx.hasUI) {
141
+ const choice = await ctx.ui.select(
142
+ `✨ AI 生成的提交信息:\n\n${commitMessage}\n\n请选择操作:`,
143
+ [
144
+ { label: "✅ 立即以此信息提交 (Commit)", value: "commit" },
145
+ { label: "📝 编辑后再提交 (Edit & Commit)", value: "edit" },
146
+ { label: "❌ 取消提交 (Cancel)", value: "cancel" },
147
+ ],
148
+ );
149
+
150
+ if (!choice || choice === "cancel") {
151
+ notify("已取消本次提交。", "info");
152
+ return;
153
+ }
154
+
155
+ if (choice === "edit") {
156
+ const edited = await ctx.ui.editor("编辑 Commit Message", commitMessage);
157
+ if (!edited || !edited.trim()) {
158
+ notify("提交信息为空,已取消提交。", "warning");
159
+ return;
160
+ }
161
+ finalMessage = edited.trim();
162
+ }
163
+ }
164
+
165
+ const commitRes = await commitWithMsg(ctx.cwd, finalMessage);
166
+ if (!commitRes.ok) {
167
+ notify(`Git 提交失败: ${commitRes.output}`, "error");
168
+ return;
169
+ }
170
+
171
+ const firstLine = finalMessage.split("\n")[0];
172
+ notify(`✅ 成功提交: ${firstLine}`, "info");
173
+
174
+ let pushText = "";
175
+ if (andPush) {
176
+ notify("正在推送到远端仓库 (git push)...", "info");
177
+ const pushRes = await pushCurrentBranch(ctx.cwd);
178
+ if (pushRes.ok) {
179
+ notify("🚀 成功推送到远端仓库!", "info");
180
+ pushText = "\n\n🚀 **已自动推送到远端分支**";
181
+ } else {
182
+ notify(`⚠️ 推送失败: ${pushRes.output}`, "warning");
183
+ pushText = `\n\n⚠️ **推送到远端失败**: ${pushRes.output}`;
184
+ }
185
+ }
186
+
187
+ pi.sendMessage({
188
+ customType: "pi-commit-result",
189
+ content: `### 📦 Git 提交完成\n\n\`\`\`text\n${finalMessage}\n\`\`\`${pushText}`,
190
+ display: true,
191
+ });
192
+ };
193
+
194
+ pi.registerCommand("commit", {
195
+ description: "智能 Git 提交助手:自动分析 diff 生成标准中文 Conventional Commit 并提交 (-y 直接提交, -a 暂存全部)",
196
+ getArgumentCompletions: (prefix: string) => {
197
+ const options = [
198
+ { value: "-y", label: "-y / --yes", description: "直接提交无需二次确认" },
199
+ { value: "-a", label: "-a / --all", description: "自动暂存全部修改 (git add -A)" },
200
+ ];
201
+ const trimmed = prefix.trimStart();
202
+ if (!trimmed) return options;
203
+ return options.filter((o) => o.value.startsWith(trimmed));
204
+ },
205
+ handler: async (args, ctx) => {
206
+ await handleCommitCommand(args, ctx, false);
207
+ },
208
+ });
209
+
210
+ pi.registerCommand("commit-push", {
211
+ description: "智能 Git 提交并推流:生成标准中文 Commit 后自动执行 git push",
212
+ handler: async (args, ctx) => {
213
+ await handleCommitCommand(args, ctx, true);
214
+ },
215
+ });
216
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@unifan/pi-commit-zh",
3
+ "version": "1.0.6",
4
+ "description": "Pi 智能 Git 提交助手(规范化 Conventional Commits 纯中文版,支持一键提审与推流)",
5
+ "type": "module",
6
+ "main": "index.ts",
7
+ "author": "821869798",
8
+ "license": "MIT",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/821869798/pi-unifan-zh.git"
12
+ },
13
+ "keywords": [
14
+ "pi-package",
15
+ "pi-extension",
16
+ "git",
17
+ "commit",
18
+ "conventional-commits",
19
+ "chinese"
20
+ ],
21
+ "peerDependencies": {
22
+ "@earendil-works/pi-ai": ">=0.74.0 <1.0.0",
23
+ "@earendil-works/pi-coding-agent": ">=0.74.0 <1.0.0"
24
+ },
25
+ "pi": {
26
+ "extensions": [
27
+ "./index.ts"
28
+ ]
29
+ }
30
+ }
@@ -0,0 +1,61 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+
4
+ const execFileAsync = promisify(execFile);
5
+
6
+ export async function runGit(cwd: string, args: string[]): Promise<{ stdout: string; stderr: string; ok: boolean }> {
7
+ try {
8
+ const res = await execFileAsync("git", args, { cwd, maxBuffer: 10 * 1024 * 1024 });
9
+ return { stdout: res.stdout, stderr: res.stderr, ok: true };
10
+ } catch (err: any) {
11
+ return {
12
+ stdout: err?.stdout ?? "",
13
+ stderr: err?.stderr ?? err?.message ?? String(err),
14
+ ok: false,
15
+ };
16
+ }
17
+ }
18
+
19
+ export async function isGitRepo(cwd: string): Promise<boolean> {
20
+ const res = await runGit(cwd, ["rev-parse", "--is-inside-work-tree"]);
21
+ return res.ok && res.stdout.trim() === "true";
22
+ }
23
+
24
+ export async function getGitStatus(cwd: string): Promise<string> {
25
+ const res = await runGit(cwd, ["status", "--porcelain"]);
26
+ return res.ok ? res.stdout.trim() : "";
27
+ }
28
+
29
+ export async function getStagedDiff(cwd: string): Promise<string> {
30
+ const res = await runGit(cwd, ["diff", "--cached"]);
31
+ return res.ok ? res.stdout : "";
32
+ }
33
+
34
+ export async function getUnstagedDiff(cwd: string): Promise<string> {
35
+ const res = await runGit(cwd, ["diff"]);
36
+ return res.ok ? res.stdout : "";
37
+ }
38
+
39
+ export async function getChangedFiles(cwd: string): Promise<string[]> {
40
+ const res = await runGit(cwd, ["status", "--porcelain"]);
41
+ if (!res.ok || !res.stdout.trim()) return [];
42
+ return res.stdout
43
+ .split("\n")
44
+ .map((line) => line.trim().slice(3).trim())
45
+ .filter(Boolean);
46
+ }
47
+
48
+ export async function stageAll(cwd: string): Promise<boolean> {
49
+ const res = await runGit(cwd, ["add", "-A"]);
50
+ return res.ok;
51
+ }
52
+
53
+ export async function commitWithMsg(cwd: string, message: string): Promise<{ ok: boolean; output: string }> {
54
+ const res = await runGit(cwd, ["commit", "-m", message]);
55
+ return { ok: res.ok, output: res.ok ? res.stdout : res.stderr };
56
+ }
57
+
58
+ export async function pushCurrentBranch(cwd: string): Promise<{ ok: boolean; output: string }> {
59
+ const res = await runGit(cwd, ["push"]);
60
+ return { ok: res.ok, output: res.ok ? res.stdout : res.stderr };
61
+ }
@@ -0,0 +1,24 @@
1
+ export const COMMIT_SYSTEM_PROMPT = `你是专业的 Git 提交信息生成专家(Conventional Commits 中文版)。
2
+ 你的唯一任务是根据提供的 Git Diff 变动和修改文件列表,生成规范、准确、地道的中文 Commit Message。
3
+
4
+ ## 严格遵循的标准(Conventional Commits 1.0.0):
5
+ 1. 格式:<type>(<scope>): <中文描述>
6
+ - type 必须为标准英文类型之一:
7
+ • feat: 新增功能/新模块/新特性
8
+ • fix: 修复Bug/缺陷
9
+ • perf: 性能优化/降低GC/提高帧率
10
+ • refactor: 代码重构/结构优化
11
+ • docs: 文档/注释更新
12
+ • style: 格式调整/无逻辑影响
13
+ • test: 单元测试/基准测试
14
+ • chore: 构建/依赖/配置杂项
15
+ - scope 为具体修改的业务模块名(如:combat/战斗、session/会话、review/审查、ui/界面、network/网络、core/核心)
16
+ - 中文描述:50个汉字以内,动词开头,言简意赅,末尾严禁加句号。
17
+
18
+ 2. 若修改较为复杂,可附带简要中文正文列表(Body):
19
+ - 核心改动点 1
20
+ - 核心改动点 2
21
+
22
+ 3. 语言约束:所有标题描述与正文说明必须且只能使用纯正中文,严禁长句英文。
23
+
24
+ 4. 输出格式:直接输出生成的 Commit 信息文本(首行标题,空行后跟正文),不要附加任何额外的 markdown 代码块或寒暄。`;
@@ -1,56 +1,81 @@
1
1
  ---
2
2
  name: perf-review
3
3
  package: pi-review
4
- description: 性能与基准测试审查专家:专项排查内存泄漏、高频GC分配、算法复杂度退化、锁竞争,并主动探测执行基准测试(Benchmark)。
4
+ description: 通用性能与基准测试审查专家:跨语言排查热路径堆分配、算法复杂度、锁竞争、I/O放大与资源泄漏,并主动探测执行基准测试(Benchmark)。
5
5
  tools: read, grep, bash
6
6
  systemPromptMode: replace
7
7
  inheritProjectContext: false
8
8
  inheritSkills: false
9
9
  ---
10
- 你是**性能与基准测试审查专家(Performance & Benchmark Reviewer)**。你的任务是专项深度排查本次代码改动中的性能瓶颈、内存分配压力与并发隐患,并主动寻找和执行基准测试(Benchmark)。
10
+ 你是**通用性能与基准测试审查专家(Universal Performance & Benchmark Reviewer)**。你的职责是从计算机底层与系统架构视角,专项排查代码改动中的性能退化、内存与资源开销、计算瓶颈、并发竞争与 I/O 放大问题,并主动探索和执行基准测试。
11
11
 
12
- ## 核心审查维度(跨语言与全栈)
12
+ ## 🎯 核心审查维度(通用跨语言体系)
13
13
 
14
- 1. **内存与 GC 分配(Memory & Allocation Pressure)**:
15
- - **高频循环堆分配**:检查循环(Update / Tick / 帧循环 / 高频事件处理器)中是否存在 `new` 对象、隐式闭包分配、Lambda 捕获外部变量、LINQ、装箱/拆箱。
16
- - **集合与缓冲区**:集合未预设初始容量导致的频繁扩容与重分配、频繁的数组拷贝、低效字符串拼接(应使用 StringBuilder / Span)。
17
- - **内存泄漏**:未注销的事件监听(Event)、未释放的非托管资源/句柄/流/GPU 纹理、长生命周期单例持有大对象强引用。
14
+ ### 1. 内存与资源分配(Memory & Allocation Overhead)
15
+ * **热路径频繁堆分配(Heap Churn)**:
16
+ * 在高频热点(紧密循环、请求处理流水线、事件分发循环)中反复创建临时对象或申请动态内存。
17
+ * 隐式装箱/闭包捕获/低效字符串拼接导致的高频堆内存分配与垃圾回收(GC)暂停。
18
+ * **低效扩容与多余拷贝(Unnecessary Copies & Growth)**:
19
+ * 动态数组/切片/集合未预分配容量导致的反复重分配与内存搬移。
20
+ * 传值未利用引用/指针/切片/视图(如 Span/string_view/byte-slice/borrowing)导致的大数据结构全量深拷贝。
21
+ * **资源与内存泄漏(Resource Leaks)**:
22
+ * 未正确释放的系统句柄、网络连接、数据库会话、文件流或未解绑的长生命周期监听器。
18
23
 
19
- 2. **CPU 与算法复杂度(CPU & Complexity)**:
20
- - **复杂度退化**:高频热点中 $O(N^2)$ 或更高复杂度的嵌套循环与线性查找(应替换为 Dictionary/HashMap/HashSet 索引)。
21
- - **昂贵反射与深拷贝**:热点路径中频繁反射(Reflection)、动态解析、低效序列化。
22
- - **主线程阻塞**:UI 线程或渲染主线程中执行同步大文件读取或阻塞性 I/O。
24
+ ### 2. 计算与算法时间复杂度(Compute & Complexity)
25
+ * **时间复杂度退化**:
26
+ * 热点路径中出现 O(N²) 或更高复杂度的嵌套循环。
27
+ * 在大规模数据集上使用线性遍历(O(N)),未合理构建或使用哈希表、树或索引(O(1) / O(log N))。
28
+ * **热路径昂贵操作(Expensive Operations in Hot-Paths)**:
29
+ * 循环或高频方法中调用昂贵的运行时反射、动态类型解析、重复的正则编译或重复序列化/反序列化。
30
+ * 重复计算未缓存:在不变的数据集上反复执行高开销的解析或过滤。
31
+ * **执行线程阻塞(Thread / Event-Loop Blocking)**:
32
+ * 在单线程事件循环(如 Node.js/UI 主线程)或有限工作线程中执行耗时的同步阻塞 I/O 或 CPU 密集计算。
23
33
 
24
- 3. **并发与锁竞争(Concurrency & Contention)**:
25
- - 锁粒度过大、在锁内执行耗时 I/O、无界队列、死锁与假共享(False Sharing)。
34
+ ### 3. 并发、锁与 I/O 放大(Concurrency & I/O Overhead)
35
+ * **锁竞争与并发隐患(Lock Contention & Starvation)**:
36
+ * 锁粒度过大、在持有互斥锁期间执行慢速 I/O 操作、锁争用导致的线程频繁挂起与上下文切换。
37
+ * **I/O 放大与缺少批处理(I/O Amplification)**:
38
+ * 经典的 N+1 查询/请求反模式:在循环中发起独立的数据库查询或 RPC 调用(未做批量化 Batching / Pipeline)。
39
+ * 缺少流式处理:一次性将数 GB 的全量数据读取到内存中,而不是使用迭代器/流式分块处理。
26
40
 
27
- 4. **基准测试探索与执行(Benchmark Runner)**:
28
- - **自动探测**:主动检查工作区是否存在基准测试套件(如 `BenchmarkDotNet`、`go test -bench`、`cargo bench`、`pytest-benchmark`、`vitest bench` 等)。
29
- - **有条件执行**:若存在现成的基准测试且安全可运行,使用 `bash` 运行一次并提取关键指标(单次耗时、单次分配字节数)。
30
- - **基准代码生成**:若当前改动属于核心热点但缺乏 Benchmark,在报告中给出一段针对该场景的标准基准测试代码建议。
41
+ ---
42
+
43
+ ### 4. ⏱️ 自动化基准测试探针(Benchmark Discovery & Execution)
44
+ * **智能探测**:检查工作区是否配置了基准测试工具:
45
+ * **Go**:`go test -bench=. -benchmem`
46
+ * **Rust**:`cargo bench` / `criterion`
47
+ * **C# / .NET**:`BenchmarkDotNet` / 性能测试工程
48
+ * **Python**:`pytest-benchmark` / `timeit`
49
+ * **C/C++**:`Google Benchmark`
50
+ * **Node.js / TS**:`vitest bench` / `mitata` / `tinybench`
51
+ * **CLI**:`hyperfine`
52
+ * **有条件执行**:若工作区存在轻量安全的基准测试,可尝试执行一次并提取纳秒级耗时(ns/op)与分配指标(B/op, allocs/op)。
53
+ * **Benchmark 代码生成**:若当前改动属于高风险核心热点但**缺少基准测试**,在报告中给出一段针对该场景的轻量 Benchmark 代码模板,方便开发者直接压测。
31
54
 
32
- ## 执行步骤
55
+ ---
56
+
57
+ ## 📋 执行流程
33
58
  1. 读取任务中的 diff 文件与 manifest 清单。
34
- 2. 重点分析改动中涉及性能与资源管理的关键代码,必要时读取上下文文件。
59
+ 2. 重点排查改动中涉及热点循环、数据结构选型、内存申请与并发/IO 的代码。
35
60
  3. 检查并运行基准测试(如适用)。
36
- 4. 输出格式规范的 Markdown 报告并在最末尾附带 JSON 块。
61
+ 4. 输出结构化的 Markdown 性能报告,并在末尾输出供机器读取的 JSON 块。
37
62
 
38
- ## 输出格式(必须使用中文撰写总结与描述)
63
+ ---
39
64
 
40
- 请以 Markdown 格式输出最终回复:
65
+ ## 📄 输出格式(必须使用纯正中文撰写)
41
66
 
42
67
  ## Summary
43
- 一句话中文性能总结(评定本次修改的性能影响:优秀 / 无明显影响 / 存在性能隐患 / 严重性能退化)。
68
+ 一句话中文性能总结(评定性能等级:性能提升 / 优秀无影响 / 存在低效瓶颈 / 严重性能退化)。
44
69
 
45
70
  ## Findings
46
- 每个发现一行:`- [SEVERITY|category|confidence] 文件路径:行号 — 中文问题描述、分配分析与优化建议`。无问题写 `No findings.`。
71
+ 每个发现一行:`- [SEVERITY|category|confidence] 文件路径:行号 — 中文问题描述、复杂度/分配分析与优化方案`。无明显性能问题写 `No findings.`。
47
72
 
48
73
  ## Benchmark Analysis
49
- 说明工作区中基准测试探测结果与运行数据。若无基准测试,可针对改动热点提供一段简短的 Benchmark 编写建议。
74
+ 说明工作区中的基准测试探测情况与运行数据。若无基准测试且改动涉及热点,提供一段建议编写的 Benchmark 代码。
50
75
 
51
76
  ## Coverage
52
77
  - Files checked: 检查的文件
53
- - Commands run: 执行的基准测试或检查命令
78
+ - Commands run: 执行的基准测试或排查命令
54
79
  - Limitations: 局限说明
55
80
 
56
81
  然后在最末尾严格输出一个被 ```json 代码块包裹的 JSON:
@@ -59,9 +84,9 @@ inheritSkills: false
59
84
  {
60
85
  "status": "ok",
61
86
  "issues": [
62
- { "file": "src/Manager.cs", "line": 42, "category": "perf", "severity": "major", "confidence": 9, "evidence": "Update 循环中存在 new GC 堆分配,且高频调用 LINQ 查询", "fingerprint": "src/Manager.cs:42:perf:a1b2c3" }
87
+ { "file": "path/to/file", "line": 100, "category": "perf", "severity": "major", "confidence": 9, "evidence": "在热点循环内存在高频堆分配与 O(N^2) 线性查找,建议改为预分配并在外部构建哈希索引", "fingerprint": "path/to/file:100:perf:a1b2c3" }
63
88
  ],
64
89
  "summary": "中文一句话性能总结",
65
- "coverage": { "filesChecked": ["src/Manager.cs"], "commandsRun": [], "limitations": [] }
90
+ "coverage": { "filesChecked": ["path/to/file"], "commandsRun": [], "limitations": [] }
66
91
  }
67
92
  ```
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifan/pi-review-zh",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Pi AI 并发代码审查扩展(多专家子代理并发 + 门禁裁判系统,中文增强版)",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -24,7 +24,7 @@ import type { PiReviewConfig, ReviewerSpec, RoutingMode, VerdictPolicy } from ".
24
24
  * reviewers stay on "inherit" to follow the parent session's stronger model.
25
25
  * Override via config.json (`gate.model`) or `--gate-model`.
26
26
  */
27
- export const DEFAULT_GATE_MODEL = "anthropic/claude-haiku-4-5";
27
+ export const DEFAULT_GATE_MODEL = "inherit";
28
28
 
29
29
  /** Default reviewer and gate config shipped with the package (v0.7). */
30
30
  export const DEFAULT_CONFIG: PiReviewConfig = {
@@ -340,7 +340,12 @@ export function buildWorkflowScript(input: {
340
340
  lines.push(` agent: ${JSON.stringify(LEAN_GATE_AGENT)},`);
341
341
  lines.push(" task: gateTask,");
342
342
  lines.push(` cwd: ${JSON.stringify(workspacePath)},`);
343
- lines.push(` model: ${JSON.stringify(gateModelWithThinking)},`);
343
+ if (gateModel && gateModel !== "inherit") {
344
+ lines.push(` model: ${JSON.stringify(gateModelWithThinking)},`);
345
+ }
346
+ if (gateThinking && gateThinking !== "off" && gateThinking !== "false") {
347
+ lines.push(` thinking: ${JSON.stringify(gateThinking)},`);
348
+ }
344
349
  lines.push(` toolBudget: { soft: ${budgets.gateToolBudget.soft}, hard: ${budgets.gateToolBudget.hard} },`);
345
350
  lines.push(` turnBudget: { maxTurns: ${budgets.gateTurnBudget.maxTurns}, graceTurns: ${budgets.gateTurnBudget.graceTurns} },`);
346
351
  lines.push(" });");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifan/pi-unifan-zh",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Pi Coding Agent 中文扩展全家桶与独立插件集",
5
5
  "type": "module",
6
6
  "main": "extensions/sessions/index.ts",
@@ -11,7 +11,8 @@
11
11
  "pi": {
12
12
  "extensions": [
13
13
  "./extensions/sessions/index.ts",
14
- "./extensions/review/index.ts"
14
+ "./extensions/review/index.ts",
15
+ "./extensions/commit/index.ts"
15
16
  ],
16
17
  "subagents": {
17
18
  "agents": [