@hifullmoon/aicommit 1.4.0 → 2.0.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.
- package/.aicommit.config.example.json +30 -10
- package/CHANGELOG.md +75 -74
- package/README.md +71 -49
- package/README.zh-CN.md +109 -87
- package/SECURITY.md +1 -1
- package/docs/distribution.md +13 -76
- package/docs/privacy.md +8 -8
- package/docs/provider-presets.md +22 -9
- package/docs/troubleshooting.md +0 -1
- package/package.json +6 -6
- package/presets/provider-presets.json +48 -15
- package/schemas/aicommit-provider-presets.schema.json +24 -4
- package/src/cli.js +57 -17
- package/src/completion.js +4 -1
- package/src/config-command.js +7 -5
- package/src/config.js +198 -26
- package/src/doctor.js +5 -3
- package/src/main.js +29 -6
- package/src/provider-presets.js +43 -15
- package/src/setup.js +66 -37
- package/src/split.js +9 -2
- package/src/ui.js +66 -13
package/README.zh-CN.md
CHANGED
|
@@ -4,6 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
AI 驱动的 Git 提交信息生成器:读取 diff,请 AI 模型生成符合 Conventional Commits 规范的提交信息,并在你确认后执行提交。
|
|
6
6
|
|
|
7
|
+
## 使用预览
|
|
8
|
+
|
|
9
|
+
以下截图来自本仓库中的真实交互式终端会话。Provider、模型、路径和耗时均为截图时的实际环境。
|
|
10
|
+
|
|
11
|
+
### 交互式配置 Provider
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
### 检查配置与连接
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
### 生成提交信息
|
|
20
|
+
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
### 检查生成的提交信息
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+
|
|
7
27
|
## 安装
|
|
8
28
|
|
|
9
29
|
使用 npm:
|
|
@@ -12,16 +32,9 @@ AI 驱动的 Git 提交信息生成器:读取 diff,请 AI 模型生成符合
|
|
|
12
32
|
npm install --global @hifullmoon/aicommit
|
|
13
33
|
```
|
|
14
34
|
|
|
15
|
-
或使用 Homebrew:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
brew tap hi-fullmoon/aicommit https://github.com/hi-fullmoon/AICommit.git
|
|
19
|
-
brew install hi-fullmoon/aicommit/aicommit
|
|
20
|
-
```
|
|
21
|
-
|
|
22
35
|
需要 Node.js >= 18。
|
|
23
36
|
|
|
24
|
-
安装、升级、签名校验与回滚请参阅双语[分发指南](docs/distribution.md)。npm
|
|
37
|
+
安装、升级、签名校验与回滚请参阅双语[分发指南](docs/distribution.md)。npm package 带有自动化安装冒烟测试。
|
|
25
38
|
|
|
26
39
|
如需直接安装源码检出版本,请在仓库根目录运行 `npm install --global .`。
|
|
27
40
|
|
|
@@ -33,7 +46,7 @@ brew install hi-fullmoon/aicommit/aicommit
|
|
|
33
46
|
aicommit setup
|
|
34
47
|
```
|
|
35
48
|
|
|
36
|
-
向导会引导你从当前生效的版本化预设清单中选择 Provider(内置预设包括 OpenAI、DeepSeek、OpenRouter、MiniMax、Kimi Code 和 Ollama),或填写自定义 OpenAI 兼容端点;随后输入 API Key
|
|
49
|
+
向导会引导你从当前生效的版本化预设清单中选择 Provider(内置预设包括 OpenAI、DeepSeek、OpenRouter、MiniMax、Kimi Code 和 Ollama),或填写自定义 OpenAI 兼容端点;随后输入 API Key 和一个或多个模型、选择默认模型和提交信息语言,并可选测试连接。配置会原子写入用户配置文件 `~/.aicommit.config.json`;如果已有文件格式错误或属于旧格式,替换前会先备份。
|
|
37
50
|
|
|
38
51
|
如需手动配置,请从 [.aicommit.config.example.json](.aicommit.config.example.json) 开始。AICommit 先加载用户配置,再将 `./.aicommit.config.json` 中白名单内的生成偏好深度合并到用户配置之上。项目配置可以设置 `language`、`commitPolicy`、`stripFiles`、`temperature`,也可以降低 diff、token、timeout 或仓库上下文上限。项目拥有的 `prompt` 默认会被忽略,除非用户配置明确设置 `allowProjectPrompt: true`。连接或 Provider 字段(包括 `apiKeyEnv`)、推理请求控制、未知字段,以及任何试图提高上限的配置,都会被忽略并给出警告。这样可以防止克隆的仓库重定向已鉴权请求,或在不知情的情况下扩大成本和数据范围。
|
|
39
52
|
|
|
@@ -41,77 +54,80 @@ aicommit setup
|
|
|
41
54
|
|
|
42
55
|
AICommit 也可以读取操作系统上已经配置的 Git credential helper。启用 `credentialHelper.enabled`,通过常规 Git/系统凭据流程保存 Provider 凭据,AICommit 就会在不弹出输入提示的情况下调用 `git credential fill`。查询用户名默认为 `aicommit`,可通过 `credentialHelper.username` 修改。凭据解析顺序为:环境变量 → Git credential helper → 用户配置中的明文凭据 → 无密钥 localhost。项目配置不能启用 credential helper,也不能选择凭据来源。
|
|
43
56
|
|
|
44
|
-
|
|
57
|
+
每个 Provider 可以拥有多个命名模型配置。通过 `-p` / `--provider` 切换 Provider,通过 `-m` / `--model` 选择该 Provider 下的模型:
|
|
45
58
|
|
|
46
59
|
```json
|
|
47
60
|
{
|
|
61
|
+
"schemaVersion": 1,
|
|
48
62
|
"defaultProvider": "minimax",
|
|
49
|
-
|
|
50
63
|
"providers": {
|
|
51
64
|
"minimax": {
|
|
52
65
|
"providerType": "minimax",
|
|
53
66
|
"apiUrl": "https://api.minimaxi.com/v1/chat/completions",
|
|
54
67
|
"apiKeyEnv": "MINIMAX_API_KEY",
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
|
|
68
|
+
"defaultModel": "default",
|
|
69
|
+
"models": {
|
|
70
|
+
"default": {
|
|
71
|
+
"label": "MiniMax M3",
|
|
72
|
+
"modelId": "MiniMax-M3",
|
|
73
|
+
"extraBody": {
|
|
74
|
+
"thinking": { "type": "disabled" },
|
|
75
|
+
"reasoning_split": true
|
|
76
|
+
}
|
|
77
|
+
}
|
|
59
78
|
}
|
|
60
79
|
},
|
|
61
80
|
"deepseek": {
|
|
62
81
|
"providerType": "deepseek",
|
|
63
82
|
"apiUrl": "https://api.deepseek.com/v1/chat/completions",
|
|
64
83
|
"apiKeyEnv": "DEEPSEEK_API_KEY",
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"apiKeyEnv": "OPENROUTER_API_KEY",
|
|
71
|
-
"modelId": "openai/gpt-4o-mini"
|
|
72
|
-
},
|
|
73
|
-
"kimi-code": {
|
|
74
|
-
"providerType": "custom",
|
|
75
|
-
"apiUrl": "https://api.kimi.com/coding/v1/chat/completions",
|
|
76
|
-
"apiKeyEnv": "KIMI_API_KEY",
|
|
77
|
-
"modelId": "kimi-for-coding"
|
|
84
|
+
"defaultModel": "chat",
|
|
85
|
+
"models": {
|
|
86
|
+
"chat": { "modelId": "deepseek-v4-flash" },
|
|
87
|
+
"reasoner": { "modelId": "deepseek-v4-pro" }
|
|
88
|
+
}
|
|
78
89
|
}
|
|
79
90
|
}
|
|
80
91
|
}
|
|
81
92
|
```
|
|
82
93
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
94
|
+
`schemaVersion`、`defaultProvider`、`providers`,以及每个 Provider 的 `providerType`、`apiUrl`、`defaultModel` 和非空 `models` 都是必填项。未指定 `-p` 时选择 `defaultProvider`;未指定 `-m` 时选择该 Provider 的 `defaultModel`。模型配置会继承全局生成设置和 Provider 连接设置,并可覆盖 `temperature`、`maxTokens`、`timeoutMs`、`reasoning` 与 `extraBody`。Provider 名和模型名是稳定的本地别名,`modelId` 才是发送给 API 的模型标识。
|
|
95
|
+
|
|
96
|
+
这是唯一支持的用户配置格式。旧版扁平配置或 Provider 级 `modelId` 会被直接拒绝;请运行 `aicommit setup` 或显式迁移。
|
|
97
|
+
|
|
98
|
+
| 配置项 | 说明 |
|
|
99
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
100
|
+
| `schemaVersion` | 必填的用户配置 schema 版本,当前为 `1` |
|
|
101
|
+
| `providers` | 命名 Provider 配置;每项包含连接设置、`defaultModel` 和非空 `models` |
|
|
102
|
+
| `defaultProvider` | 必填;未指定 `-p` 时使用的 Provider 别名 |
|
|
103
|
+
| `apiUrl` | OpenAI 兼容的 Chat Completions 端点 |
|
|
104
|
+
| `apiKey` | API Key;本地模型允许使用空字符串 |
|
|
105
|
+
| `apiKeyEnv` | 保存 API Key 的环境变量名,优先于 `apiKey`(默认:空) |
|
|
106
|
+
| `providerType` | 必填适配器:`openai`、`openrouter`、`deepseek`、`minimax`、`ollama`、`custom` 或用户安装的 `extension:<id>` |
|
|
107
|
+
| `defaultModel` | 必填;未指定 `-m` 时使用的模型别名 |
|
|
108
|
+
| `models` | 一个 Provider 下的命名模型配置 |
|
|
109
|
+
| `modelId` | 每个模型配置中必填的 API 模型标识 |
|
|
110
|
+
| `commitPolicy` | 版本化提交规则:type、scope、主题长度、正文、破坏性变更和语言 |
|
|
111
|
+
| `prompt` | 用户批准的可选指导,追加到权威结构化策略之后(默认:空) |
|
|
112
|
+
| `allowProjectPrompt` | 是否接受项目配置中的 `prompt`,只能由用户配置启用(默认:`false`) |
|
|
113
|
+
| `repositoryContext` | 近期提交、包边界、可信约定和 commitlint 检测的总预算与分类预算 |
|
|
114
|
+
| `language` | 提交信息语言:`zh` 或 `en`(默认:`zh`) |
|
|
115
|
+
| `temperature` | 采样温度(默认:`0.3`) |
|
|
116
|
+
| `maxTokens` | 最大响应 token 数(默认:`1024`) |
|
|
117
|
+
| `timeoutMs` | 单次请求超时,单位为毫秒(默认:`120000`) |
|
|
118
|
+
| `retry` | 瞬时错误重试限制:`maxAttempts`、`baseDelayMs`、`maxDelayMs`(默认:`3`、`500`、`5000`) |
|
|
119
|
+
| `credentialHelper` | 通过 `enabled` 和 `username` 选择性启用 `git credential fill`(默认:`false`、`aicommit`) |
|
|
120
|
+
| `metrics` | 仅本地指标控制:`enabled`、绝对路径 `path`(空表示默认路径)、`maxEntries`(默认:`true`、空、`500`) |
|
|
121
|
+
| `extensions` | 用户拥有的绝对扩展清单路径,以及执行超时和上下文上限;项目配置不能启用或重定向扩展 |
|
|
122
|
+
| `maxDiffChars` | 单次发送给模型的 diff 字符数;超限后改为 `--stat` 摘要和截断的 hunk(默认:`30000`) |
|
|
123
|
+
| `maxFileDiffChars` | 单文件 diff 上限;超限文件只保留前部 hunk,避免一个大文件挤占全部上下文(默认:`3000`) |
|
|
124
|
+
| `splitMaxDiffChars` | 拆分规划请求的 diff 字符数;规划阶段需要的 hunk 细节少于最终信息生成(默认:`16000`) |
|
|
125
|
+
| `splitMaxPlanFiles` | 交给拆分规划器的最大变更文件数;超出部分归入兜底提交(默认:`100`) |
|
|
126
|
+
| `diffContextLines` | 每个 diff hunk 周围的上下文行数(`git diff --unified=<n>`);越小越节省 token(默认:`1`) |
|
|
127
|
+
| `stripFiles` | 额外替换为占位的文件,按 basename 使用 `*` / `?` 通配,如 `["*.min.js", "*.map", "*.snap"]`(默认:`[]`;项目项与用户项合并而非覆盖) |
|
|
128
|
+
| `regenerateWithDiff` | `true` 表示每次重写都重发完整 diff,以获得更多变化;`false`(默认)只要求模型改写上一条消息,成本更低 |
|
|
129
|
+
| `extraBody` | 模型配置中合并到请求体的 JSON 字段,但不允许覆盖 `model` / `messages`(默认:`{}`) |
|
|
130
|
+
| `reasoning` | 全局或模型级推理控制:`mode`、`effort`、`maxTokens` 和 `maxDisplayChars`;默认为 `mode: "on"`,并自动流式展示推理 |
|
|
115
131
|
|
|
116
132
|
AICommit 支持 OpenAI、DeepSeek、[OpenRouter](https://openrouter.ai)、MiniMax、[Kimi Code](https://www.kimi.com/code/docs/)、Ollama(原生 `/api/chat` 或 OpenAI 兼容 `/v1/chat/completions`)、LiteLLM,以及其他兼容端点。远程端点必须使用 HTTPS;明文 HTTP 只允许 localhost / loopback。
|
|
117
133
|
|
|
@@ -125,13 +141,17 @@ export KIMI_API_KEY='your-kimi-code-api-key'
|
|
|
125
141
|
|
|
126
142
|
```json
|
|
127
143
|
{
|
|
144
|
+
"schemaVersion": 1,
|
|
128
145
|
"defaultProvider": "kimi-code",
|
|
129
146
|
"providers": {
|
|
130
147
|
"kimi-code": {
|
|
131
148
|
"providerType": "custom",
|
|
132
149
|
"apiUrl": "https://api.kimi.com/coding/v1/chat/completions",
|
|
133
150
|
"apiKeyEnv": "KIMI_API_KEY",
|
|
134
|
-
"
|
|
151
|
+
"defaultModel": "default",
|
|
152
|
+
"models": {
|
|
153
|
+
"default": { "modelId": "kimi-for-coding" }
|
|
154
|
+
}
|
|
135
155
|
}
|
|
136
156
|
}
|
|
137
157
|
}
|
|
@@ -261,15 +281,15 @@ aicommit stats # 显示本地质量、延迟和 token 趋势
|
|
|
261
281
|
aicommit stats clear # 永久清除本地指标历史
|
|
262
282
|
aicommit # 在当前目录生成提交信息并提交
|
|
263
283
|
aicommit /path/to/repo # 或指定目标目录
|
|
264
|
-
aicommit split
|
|
265
|
-
aicommit split
|
|
266
|
-
aicommit split
|
|
267
|
-
aicommit split
|
|
284
|
+
aicommit split # 选择 staged / all 范围并拆分逻辑提交
|
|
285
|
+
aicommit split --scope=staged # 只拆分已审阅的 index 快照
|
|
286
|
+
aicommit split --scope=all # 拆分完整工作区快照
|
|
287
|
+
aicommit split --scope=staged --split-hunks # 实验性同文件 hunk 拆分
|
|
268
288
|
aicommit --dry-run # 生成并审阅,但不创建提交
|
|
269
|
-
aicommit split
|
|
289
|
+
aicommit split --dry-run # 审阅拆分计划,但不创建提交
|
|
270
290
|
aicommit --yes # 非交互提交已明确暂存的变更
|
|
271
291
|
aicommit --yes --dry-run # 非交互预览所有变更;退出时恢复暂存状态
|
|
272
|
-
aicommit split
|
|
292
|
+
aicommit split --scope=all --yes # 非交互规划并提交所有工作区变更
|
|
273
293
|
aicommit split plan --scope=staged --file=/tmp/split-plan.json --yes
|
|
274
294
|
aicommit split apply --file=/tmp/split-plan.json --yes
|
|
275
295
|
aicommit split resume --yes # 恢复中断的拆分事务
|
|
@@ -278,28 +298,30 @@ aicommit --reasoning=low # 流式显示低强度推理;Ctrl+O 展开或收起
|
|
|
278
298
|
aicommit --no-reasoning # Provider / 模型支持时显式关闭推理
|
|
279
299
|
aicommit -l zh # 提交信息语言
|
|
280
300
|
aicommit -p deepseek # 切换到名为 "deepseek" 的 Provider
|
|
301
|
+
aicommit -p deepseek -m reasoner # 使用其中名为 "reasoner" 的模型配置
|
|
281
302
|
aicommit --yes --output=json # 向 stdout 输出一个通过 schema 校验的 JSON 结果
|
|
282
303
|
aicommit -h # 帮助
|
|
283
304
|
```
|
|
284
305
|
|
|
285
|
-
| 选项 | 说明
|
|
286
|
-
| ------------------ |
|
|
287
|
-
| `-l`, `--lang` | 提交信息语言:`zh` 或 `en`
|
|
288
|
-
| `-p`, `--provider` | 使用 `providers` 中的命名 Provider
|
|
289
|
-
| `--
|
|
290
|
-
| `--
|
|
291
|
-
| `--
|
|
292
|
-
| `--
|
|
293
|
-
|
|
|
294
|
-
| `--
|
|
295
|
-
| `--
|
|
296
|
-
| `--
|
|
297
|
-
|
|
|
298
|
-
| `-
|
|
306
|
+
| 选项 | 说明 |
|
|
307
|
+
| ------------------ | ------------------------------------------------------------------- |
|
|
308
|
+
| `-l`, `--lang` | 提交信息语言:`zh` 或 `en` |
|
|
309
|
+
| `-p`, `--provider` | 使用 `providers` 中的命名 Provider |
|
|
310
|
+
| `-m`, `--model` | 使用所选 Provider 下的命名模型配置 |
|
|
311
|
+
| `--split-hunks` | 启用实验性同文件文本 hunk 规划;默认关闭 |
|
|
312
|
+
| `--scope` | `aicommit split` 和 `aicommit split plan` 的范围:`staged` 或 `all` |
|
|
313
|
+
| `--file` | `aicommit split plan` 和 `aicommit split apply` 的 JSON 计划路径 |
|
|
314
|
+
| `--dry-run` | 生成并审阅消息或拆分计划,但不创建提交 |
|
|
315
|
+
| `-y`, `--yes` | 不提示直接接受;普通模式要求变更已明确暂存 |
|
|
316
|
+
| `--reasoning` | 启用推理,可选强度:`low`、`medium`、`high`、`xhigh` 或 `max` |
|
|
317
|
+
| `--no-reasoning` | 所选 Provider / 模型支持时显式关闭推理 |
|
|
318
|
+
| `--output` | `text`(默认)或单个 JSON 对象;提交 / 拆分的 JSON 流程要求 `--yes` |
|
|
319
|
+
| `-v`, `--version` | 显示版本 |
|
|
320
|
+
| `-h`, `--help` | 显示帮助 |
|
|
299
321
|
|
|
300
322
|
### 配置检查
|
|
301
323
|
|
|
302
|
-
`aicommit config show|validate|path` 可以在仓库外运行,并接受可选目标目录。`show` 使用与提交生成相同的用户 / 项目 / 团队策略信任过滤和 Provider
|
|
324
|
+
`aicommit config show|validate|path` 可以在仓库外运行,并接受可选目标目录。`show` 使用与提交生成相同的用户 / 项目 / 团队策略信任过滤和 Provider / 模型选择,但会递归遮蔽秘密。`validate` 在不读取环境凭据、不调用 Git credential helper 的情况下解析、合并并校验配置,因此 `aicommit config validate --output=json` 可安全用于 CI。即使配置文件格式错误,`path` 仍会报告用户配置、项目配置和团队策略路径。`show` 与 `validate` 都接受 `--provider=<name>` 和 `--model=<name>`。
|
|
303
325
|
|
|
304
326
|
### Shell 补全
|
|
305
327
|
|
|
@@ -360,11 +382,11 @@ aicommit completion fish > ~/.config/fish/completions/aicommit.fish
|
|
|
360
382
|
|
|
361
383
|
### 诊断
|
|
362
384
|
|
|
363
|
-
`aicommit doctor` 会检查当前 Node.js 与 Git 版本、已加载的配置来源、端点安全、所选适配器能力、脱敏后的凭据来源,以及实时 Provider 连接。它会显示 `env:OPENAI_API_KEY`、`git credential helper`、`keyless localhost` 等来源标签,但绝不会显示凭据值。端点 userinfo、疑似凭据的查询参数和 URL fragment 也会从正常输出及凭据解析错误中脱敏。使用 `aicommit doctor -p <
|
|
385
|
+
`aicommit doctor` 会检查当前 Node.js 与 Git 版本、已加载的配置来源、端点安全、所选适配器能力、脱敏后的凭据来源,以及实时 Provider 连接。它会显示 `env:OPENAI_API_KEY`、`git credential helper`、`keyless localhost` 等来源标签,但绝不会显示凭据值。端点 userinfo、疑似凭据的查询参数和 URL fragment 也会从正常输出及凭据解析错误中脱敏。使用 `aicommit doctor -p <provider> -m <model>` 选择已配置的 Provider / 模型组合,或在自动化中使用 `aicommit doctor --output=json`。
|
|
364
386
|
|
|
365
|
-
稳定错误分类、
|
|
387
|
+
稳定错误分类、npm 校验失败、split 恢复、预设兼容和扩展隔离错误,请参阅双语[故障排查矩阵](docs/troubleshooting.md)。
|
|
366
388
|
|
|
367
|
-
基本流程:读取暂存 diff,发送给 AI,然后让你选择**接受**(Enter)、**编辑**(`e`)或**取消**(`n
|
|
389
|
+
基本流程:读取暂存 diff,发送给 AI,然后让你选择**接受**(Enter)、**编辑**(`e`)或**取消**(`n`)。在交互式选择提示中,按 `q` 会立即退出。如果没有暂存内容,但工作区存在未暂存或未跟踪变更,AICommit 会先询问是否为你暂存——可以一次性执行 `git add -A`,也可以逐文件选择——然后继续。一旦存在暂存内容,就以该 index 快照为准,其余工作区变更保持不动。
|
|
368
390
|
|
|
369
391
|
`--dry-run` 使用相同审阅流程,但会在 `git commit` 前停止。AICommit 在执行期间做出的任何暂存操作都会在退出前恢复。取消和失败也使用同一 index 事务;如果另一个进程并发修改了 index,AICommit 会保持其现状,不会覆盖对方的工作。
|
|
370
392
|
|
|
@@ -391,7 +413,7 @@ aicommit completion fish > ~/.config/fish/completions/aicommit.fish
|
|
|
391
413
|
|
|
392
414
|
### 拆分提交模式
|
|
393
415
|
|
|
394
|
-
`aicommit split
|
|
416
|
+
`aicommit split`(也可以显式写成 `aicommit split run`)会询问是对暂存 index 快照分组,还是对全部已暂存、未暂存和未跟踪变更分组。边界必须明确时请使用 `--scope=staged` 或 `--scope=all`,所有非交互运行都应显式指定范围。提交前可以审阅计划、为选中的组重新生成消息,或直接编辑 JSON 计划。扩展校验错误会随计划显示,必须通过编辑或重新生成修复后才能提交。敏感内容检测会在非交互 Provider 请求或自动暂存前 fail closed。
|
|
395
417
|
|
|
396
418
|
如需可审计的两步流程,使用 `aicommit split plan --scope=staged|all --file=<path>` 导出版本化 JSON 工件,再用 `aicommit split apply --file=<path>` 在接触 index 前重新校验 base commit、变更集和内容指纹。计划文件应保存在工作区之外或 `.git` 下,避免被纳入自身计划。
|
|
397
419
|
|
|
@@ -401,7 +423,7 @@ split 默认仍按文件拆分。`--split-hunks` 可选择性启用实验性的
|
|
|
401
423
|
|
|
402
424
|
## 开发与发布
|
|
403
425
|
|
|
404
|
-
本地开发和 Pull Request 检查请参阅 [CONTRIBUTING.md](CONTRIBUTING.md),私密漏洞报告请参阅 [SECURITY.md](SECURITY.md)
|
|
426
|
+
本地开发和 Pull Request 检查请参阅 [CONTRIBUTING.md](CONTRIBUTING.md),私密漏洞报告请参阅 [SECURITY.md](SECURITY.md),维护者发布流程请参阅 [RELEASING.md](RELEASING.md),npm 安装和用户回滚请参阅双语[分发指南](docs/distribution.md)。发布通过 npm Trusted Publishing 生成 provenance,并发布经过校验的精确 package tarball。`npm run eval` 会运行匿名本地质量语料,覆盖单一与混合变更、rename、生成文件、长 diff、中英文输出和格式错误的弱模型候选;该命令也是 `npm run ci` 的一部分。
|
|
405
427
|
|
|
406
428
|
## 许可证
|
|
407
429
|
|
package/SECURITY.md
CHANGED
|
@@ -24,7 +24,7 @@ AICommit is a local CLI that sends selected repository context directly to the c
|
|
|
24
24
|
- common sensitive content should be detected and protected before the default model request;
|
|
25
25
|
- remote endpoints must use HTTPS, while plaintext HTTP is limited to loopback development services.
|
|
26
26
|
- third-party extension API v1 must deny resolved credential access, run out of process with a sanitized environment, and fail instead of falling back to unsandboxed execution;
|
|
27
|
-
-
|
|
27
|
+
- npm releases must use Trusted Publishing provenance.
|
|
28
28
|
|
|
29
29
|
Sensitive-content detection is intentionally a defense in depth and cannot replace a dedicated secret scanner. Interactive users can explicitly choose to send original content after a warning. Review the selected endpoint and diff before doing so.
|
|
30
30
|
|
package/docs/distribution.md
CHANGED
|
@@ -1,104 +1,41 @@
|
|
|
1
|
-
# Distribution
|
|
1
|
+
# Distribution / 分发
|
|
2
2
|
|
|
3
|
-
AICommit
|
|
3
|
+
AICommit 仅通过 npm 发布。
|
|
4
4
|
|
|
5
|
-
AICommit
|
|
5
|
+
AICommit is distributed exclusively through npm.
|
|
6
6
|
|
|
7
7
|
## npm
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
+
# install / 安装
|
|
10
11
|
npm install --global @hifullmoon/aicommit
|
|
11
|
-
aicommit --version
|
|
12
12
|
|
|
13
13
|
# upgrade / 升级
|
|
14
14
|
npm install --global @hifullmoon/aicommit@latest
|
|
15
15
|
|
|
16
16
|
# pin or roll back / 固定或回滚
|
|
17
17
|
npm install --global @hifullmoon/aicommit@1.4.0
|
|
18
|
+
|
|
19
|
+
aicommit --version
|
|
18
20
|
```
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
发布工作流使用 npm Trusted Publishing,不保存长期 `NPM_TOKEN`。来自公开 GitHub 仓库的 OIDC 发布会自动携带 npm provenance。可使用当前 npm CLI 检查 registry signature 与 provenance:
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
The release workflow uses npm Trusted Publishing without a long-lived `NPM_TOKEN`. OIDC publishing from the public GitHub repository automatically includes npm provenance. Verify registry signatures and provenance with a current npm CLI:
|
|
23
25
|
|
|
24
26
|
```bash
|
|
25
27
|
workdir=$(mktemp -d)
|
|
26
28
|
cd "$workdir"
|
|
27
|
-
npm install --package-lock-only @hifullmoon/aicommit@
|
|
29
|
+
npm install --package-lock-only @hifullmoon/aicommit@2.0.0
|
|
28
30
|
npm audit signatures
|
|
29
31
|
```
|
|
30
32
|
|
|
31
|
-
##
|
|
32
|
-
|
|
33
|
-
The main repository is a tap, so no separate tap repository or install script is trusted:
|
|
34
|
-
|
|
35
|
-
主仓库本身就是 tap,无需信任额外 tap 仓库或安装脚本:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
brew tap hi-fullmoon/aicommit https://github.com/hi-fullmoon/AICommit.git
|
|
39
|
-
brew install hi-fullmoon/aicommit/aicommit
|
|
40
|
-
aicommit --version
|
|
41
|
-
|
|
42
|
-
# upgrade / 升级
|
|
43
|
-
brew update
|
|
44
|
-
brew upgrade hi-fullmoon/aicommit/aicommit
|
|
45
|
-
|
|
46
|
-
# uninstall / 卸载
|
|
47
|
-
brew uninstall aicommit
|
|
48
|
-
brew untap hi-fullmoon/aicommit
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
The formula depends on Homebrew's Node package, installs with Homebrew's standard npm arguments, and tests `--version`, `--help`, credential-free config validation, and Fish completion. Pull requests run an actual `brew install` against a locally packed tarball; the release workflow repeats the smoke test against the published registry tarball.
|
|
52
|
-
|
|
53
|
-
Formula 依赖 Homebrew 的 Node 包,使用 Homebrew 标准 npm 参数安装,并测试 `--version`、`--help`、无凭据配置校验和 Fish completion。Pull request 会针对本地打包 tarball 执行真实 `brew install`;发布工作流还会针对 registry 已发布 tarball 再跑一次 smoke。
|
|
54
|
-
|
|
55
|
-
## Signed GitHub assets / GitHub 签名资产
|
|
56
|
-
|
|
57
|
-
Each release requires a GitHub-verified signed annotated tag. The release workflow builds and uploads:
|
|
58
|
-
|
|
59
|
-
每个 release 都要求 GitHub 已验证签名的 annotated tag。发布工作流生成并上传:
|
|
60
|
-
|
|
61
|
-
- `aicommit-X.Y.Z.tgz` — the exact tarball published to npm / 与 npm 完全相同的 tarball;
|
|
62
|
-
- `aicommit.rb` — the versioned Homebrew formula / 固定版本的 Homebrew formula;
|
|
63
|
-
- `aicommit-X.Y.Z.spdx.json` — SPDX SBOM;
|
|
64
|
-
- `SHA256SUMS` — hashes for the tarball, formula, and SBOM;
|
|
65
|
-
- `*.sigstore.json` — GitHub OIDC/Sigstore provenance and SBOM bundles.
|
|
66
|
-
|
|
67
|
-
Verify checksums and the cryptographically signed provenance against the exact release workflow:
|
|
68
|
-
|
|
69
|
-
校验 checksum,并把加密签名的 provenance 限定到本仓库的 release workflow:
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
version=v1.4.0
|
|
73
|
-
asset_dir=$(mktemp -d)
|
|
74
|
-
gh release download "$version" -R hi-fullmoon/AICommit -D "$asset_dir"
|
|
75
|
-
cd "$asset_dir"
|
|
76
|
-
shasum -a 256 -c SHA256SUMS
|
|
77
|
-
gh attestation verify "aicommit-${version#v}.tgz" \
|
|
78
|
-
-R hi-fullmoon/AICommit \
|
|
79
|
-
--signer-workflow hi-fullmoon/AICommit/.github/workflows/release.yml
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
An attestation proves origin and integrity, not that the code is vulnerability-free. Review the referenced commit/workflow and the security notes before installation.
|
|
83
|
-
|
|
84
|
-
Attestation 证明来源与完整性,不代表代码不存在漏洞。安装前仍应审查其关联 commit、workflow 与安全说明。
|
|
85
|
-
|
|
86
|
-
## Release and rollback / 发布与回滚
|
|
87
|
-
|
|
88
|
-
Maintainers execute the complete checklist in [`RELEASING.md`](../RELEASING.md). Public tags and attestations are immutable: never move a published tag or replace a published version.
|
|
33
|
+
## Rollback / 回滚
|
|
89
34
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
For an affected npm version, deprecate it and publish a fixed patch. Users can immediately pin the preceding version. For Homebrew, revert the formula in a new commit or download the older release's attested `aicommit.rb`, uninstall the current formula, and install that local file:
|
|
93
|
-
|
|
94
|
-
若 npm 版本有问题,应 deprecate 并发布修复 patch;用户可立即固定上一版本。Homebrew 应通过新 commit 回退 formula,或下载旧 release 中已证明的 `aicommit.rb`,卸载当前版本后从本地文件安装:
|
|
35
|
+
npm 用户可以立即固定上一可用版本:
|
|
95
36
|
|
|
96
37
|
```bash
|
|
97
|
-
|
|
98
|
-
brew uninstall aicommit
|
|
99
|
-
brew install --formula /tmp/aicommit-rollback/aicommit.rb
|
|
38
|
+
npm install --global @hifullmoon/aicommit@<last-good-version>
|
|
100
39
|
```
|
|
101
40
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
Provider preset 回滚不依赖核心包版本:执行 `aicommit preset rollback`,再运行 `aicommit preset show` 和 `aicommit doctor`。详见 [`provider-presets.md`](provider-presets.md)。
|
|
41
|
+
已发布的 npm version 不应覆盖或复用。维护者应 deprecate 有问题的版本、恢复正确的 dist-tag,并发布修复 patch。完整流程见 [`RELEASING.md`](../RELEASING.md)。
|
package/docs/privacy.md
CHANGED
|
@@ -6,14 +6,14 @@ AICommit 是本地 CLI,不是托管中转服务。仓库数据从本地进程
|
|
|
6
6
|
|
|
7
7
|
## Trust boundaries / 信任边界
|
|
8
8
|
|
|
9
|
-
| Boundary / 边界
|
|
10
|
-
|
|
|
11
|
-
| Main CLI process / CLI 主进程
|
|
12
|
-
| Git subprocess / Git 子进程
|
|
13
|
-
| Provider endpoint / Provider 端点
|
|
14
|
-
| Extension child / 扩展子进程
|
|
15
|
-
| Local metrics file / 本地指标文件
|
|
16
|
-
| GitHub/npm
|
|
9
|
+
| Boundary / 边界 | Data visible there / 可见数据 | Default control / 默认控制 |
|
|
10
|
+
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
11
|
+
| Main CLI process / CLI 主进程 | Selected Git metadata/diff, effective config, resolved provider credential / 选定 Git 元数据与 diff、有效配置、provider 凭据 | User config owns connection fields; project config is filtered / 连接字段归用户配置,项目配置受过滤 |
|
|
12
|
+
| Git subprocess / Git 子进程 | Requested status, diff, index/tree operations / 请求的 status、diff、index/tree 操作 | Explicit arguments, temporary indexes, fingerprints and recovery checkpoints / 显式参数、临时 index、指纹与恢复 checkpoint |
|
|
13
|
+
| Provider endpoint / Provider 端点 | Prompt, protected selected diff/context, model options, Bearer credential / prompt、保护后的选定 diff/context、模型选项、Bearer 凭据 | Remote HTTPS except loopback; preview/protection before send; bounded context / 远端仅 HTTPS;发送前预览/保护;上下文有预算 |
|
|
14
|
+
| Extension child / 扩展子进程 | Only the input for its declared interface / 仅声明接口所需输入 | Sanitized environment, no resolved credential, Node permission model, timeout/output bounds / 清理环境、不传凭据、Node 权限模型、超时/输出限制 |
|
|
15
|
+
| Local metrics file / 本地指标文件 | Duration, token totals, bounded result, edited/rewrite flags / 延迟、token 总量、结果类别、编辑/重写标记 | Local-only, owner permissions, retention cap, disable/clear controls / 仅本地、owner 权限、保留上限、可关闭/清除 |
|
|
16
|
+
| GitHub/npm during installation / 安装期 GitHub/npm | Package download metadata / package 下载元数据 | Version tag and npm Trusted Publishing provenance / 版本 tag 与 npm Trusted Publishing provenance |
|
|
17
17
|
|
|
18
18
|
## Provider request contents / Provider 请求内容
|
|
19
19
|
|
package/docs/provider-presets.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Provider presets / Provider 预设
|
|
2
2
|
|
|
3
|
-
Provider presets are versioned setup data, not request code. The stable adapters in `src/providers.js` own request/response behavior; `presets/provider-presets.json`
|
|
3
|
+
Provider presets are versioned setup data, not request code. The stable adapters in `src/providers.js` own request/response behavior; `presets/provider-presets.json` supplies a provider ID, display label, adapter ID, secure endpoint, a named model map, and the default model name. Each model supplies its API `modelId` and may include a label or bounded `extraBody` defaults. Adding another OpenAI-compatible service with the `custom` adapter does not change Git, interaction, or request orchestration code.
|
|
4
4
|
|
|
5
|
-
Provider preset 是带版本的 setup 数据,不是请求代码。`src/providers.js` 中的稳定 adapter 负责请求/响应行为;`presets/provider-presets.json`
|
|
5
|
+
Provider preset 是带版本的 setup 数据,不是请求代码。`src/providers.js` 中的稳定 adapter 负责请求/响应行为;`presets/provider-presets.json` 提供 provider ID、显示名称、adapter ID、安全 endpoint、命名模型表和默认模型名。每个模型提供 API `modelId`,也可提供显示名称或有界的 `extraBody` 默认值。使用 `custom` adapter 新增另一个 OpenAI-compatible 服务时,不需要修改 Git、交互或请求编排代码。
|
|
6
6
|
|
|
7
7
|
## Compatibility contract / 兼容契约
|
|
8
8
|
|
|
@@ -13,11 +13,11 @@ Every manifest declares:
|
|
|
13
13
|
```json
|
|
14
14
|
{
|
|
15
15
|
"kind": "aicommit-provider-presets",
|
|
16
|
-
"schemaVersion":
|
|
17
|
-
"version": "
|
|
16
|
+
"schemaVersion": 2,
|
|
17
|
+
"version": "2.0.0",
|
|
18
18
|
"compatibility": {
|
|
19
|
-
"coreMinimum": "1.
|
|
20
|
-
"coreMaximumExclusive": "
|
|
19
|
+
"coreMinimum": "1.5.1",
|
|
20
|
+
"coreMaximumExclusive": "3.0.0",
|
|
21
21
|
"adapterContract": 1
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -27,13 +27,15 @@ Every manifest declares:
|
|
|
27
27
|
- The core range is inclusive at `coreMinimum` and exclusive at `coreMaximumExclusive`.
|
|
28
28
|
- Core prerelease versions and build metadata follow SemVer; build metadata is ignored for precedence.
|
|
29
29
|
- `adapterContract` declares the request-adapter interface expected by every entry.
|
|
30
|
-
-
|
|
30
|
+
- Every provider declares a non-empty `models` map and a `defaultModel` that references one entry. Model names are setup aliases; `modelId` is sent to the API.
|
|
31
|
+
- The runtime rejects unknown fields, duplicate/reserved IDs, unsupported adapters, remote HTTP, credentials, model-level `model`/`messages` overrides, oversized data, incompatible versions, and symlinked files.
|
|
31
32
|
|
|
32
33
|
- `version` 标识可独立替换的 preset 数据版本。
|
|
33
34
|
- core 范围包含 `coreMinimum`,不包含 `coreMaximumExclusive`。
|
|
34
35
|
- Core 的预发布版本与构建元数据遵循 SemVer;构建元数据不参与优先级比较。
|
|
35
36
|
- `adapterContract` 声明每个条目所依赖的请求 adapter 接口。
|
|
36
|
-
-
|
|
37
|
+
- 每个 Provider 都声明非空 `models`,并通过 `defaultModel` 引用其中一项。模型名是 setup 使用的别名,`modelId` 才会发送给 API。
|
|
38
|
+
- 运行时拒绝未知字段、重复/保留 ID、不支持的 adapter、远程 HTTP、凭据、模型级 `model`/`messages` 覆盖、超限数据、不兼容版本和符号链接文件。
|
|
37
39
|
|
|
38
40
|
The published JSON Schema is [`schemas/aicommit-provider-presets.schema.json`](../schemas/aicommit-provider-presets.schema.json). Runtime validation is authoritative and adds semantic/security checks that JSON Schema alone cannot express.
|
|
39
41
|
|
|
@@ -91,7 +93,18 @@ Add one entry to a copied manifest, bump `version`, validate, and install it:
|
|
|
91
93
|
"label": "Acme Compatible",
|
|
92
94
|
"adapter": "custom",
|
|
93
95
|
"apiUrl": "https://api.acme.example/v1/chat/completions",
|
|
94
|
-
"
|
|
96
|
+
"defaultModel": "fast",
|
|
97
|
+
"models": {
|
|
98
|
+
"fast": {
|
|
99
|
+
"label": "Acme Chat",
|
|
100
|
+
"modelId": "acme-chat"
|
|
101
|
+
},
|
|
102
|
+
"quality": {
|
|
103
|
+
"label": "Acme Reasoner",
|
|
104
|
+
"modelId": "acme-reasoner",
|
|
105
|
+
"extraBody": { "reasoning": true }
|
|
106
|
+
}
|
|
107
|
+
}
|
|
95
108
|
}
|
|
96
109
|
```
|
|
97
110
|
|
package/docs/troubleshooting.md
CHANGED
|
@@ -29,7 +29,6 @@ JSON 模式保证 stdout 只有一个机器对象,诊断进入 stderr。`error
|
|
|
29
29
|
| Preset install/rollback fails / preset 安装或回滚失败 | `config` / `2` | Schema/core range/adapter contract mismatch or no valid backup / schema、核心范围、adapter contract 不匹配或无备份 | `aicommit preset validate --file=...`; `aicommit preset show`; follow the compatibility guide |
|
|
30
30
|
| Extension requires Node 20+ / 扩展要求 Node 20+ | `config` / `2` | Node 18 intentionally has no executable-extension fallback / Node 18 有意不降级运行扩展 | Upgrade Node for extensions or remove user manifest entries; core CLI still supports Node 18 |
|
|
31
31
|
| Extension timeout or permission error / 扩展超时或权限错误 | warning or `response_format` | Extension exceeded its limit or tried denied filesystem/process access / 扩展超时或访问被拒资源 | Review the extension, keep it single-file, raise `extensions.timeoutMs` cautiously; validator failures are fail-closed |
|
|
32
|
-
| `brew install` checksum mismatch / Homebrew checksum 不一致 | Homebrew failure | Formula and registry tarball differ, stale tap, or tampered download / formula 与 tarball 不同、tap 过旧或下载被篡改 | `brew update`; compare release `SHA256SUMS`; do not use `--force` to bypass integrity |
|
|
33
32
|
| npm provenance is absent or invalid / npm provenance 缺失或失败 | npm audit failure | Old npm CLI, non-trusted release, or wrong version / npm 过旧、非可信发布或版本错误 | Upgrade npm; run `npm audit signatures`; install only a version linked to the official workflow |
|
|
34
33
|
|
|
35
34
|
If a failure remains, capture `aicommit doctor --output=json`, Node/Git versions, the error category, and redacted config sources. Never attach a diff, commit message, config file, API key, reasoning trace, extension source containing secrets, or credential-helper output to a public issue.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hifullmoon/aicommit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Safe, local-first AI commit message generator for Git workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"README.md",
|
|
14
14
|
"SECURITY.md",
|
|
15
15
|
"bin/",
|
|
16
|
-
"docs
|
|
16
|
+
"docs/*.md",
|
|
17
|
+
"docs/examples/",
|
|
17
18
|
"presets/",
|
|
18
19
|
"schemas/",
|
|
19
20
|
"templates/",
|
|
@@ -28,10 +29,9 @@
|
|
|
28
29
|
"coverage": "c8 node --test --test-concurrency=1",
|
|
29
30
|
"eval": "node eval/run.mjs",
|
|
30
31
|
"test:package": "node scripts/package-smoke.mjs",
|
|
31
|
-
"
|
|
32
|
-
"release:
|
|
33
|
-
"release:npm:check": "node scripts/
|
|
34
|
-
"release:npm:publish": "node scripts/publish-npm-org.mjs --publish",
|
|
32
|
+
"docs:terminal-demo": "node scripts/readme-terminal-demo.mjs",
|
|
33
|
+
"release:version": "node scripts/update-version.mjs",
|
|
34
|
+
"release:npm:check": "node scripts/verify-release.mjs && npm run ci && npm run test:package && npm pack --dry-run",
|
|
35
35
|
"ci": "npm run lint && npm run format:check && npm run eval && npm run coverage"
|
|
36
36
|
},
|
|
37
37
|
"c8": {
|