@hifullmoon/aicommit 2.6.7 → 2.6.9

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/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@ This file lists notable user-facing changes. Internal refactors, test-only chang
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [2.6.9] - 2026-10-08
8
+
9
+ ### Fixed
10
+
11
+ - Split planning no longer creates generic "update remaining files" commits for omitted changes. Incomplete plans are rejected, and exhausted analysis budgets stop without committing.
12
+ - Single-commit fallback after planning capacity exhaustion now generates its message from change summaries within the remaining analysis budget.
13
+
14
+ ## [2.6.8] - 2026-10-07
15
+
16
+ ### Fixed
17
+
18
+ - Provider requests now ignore SDK environment headers and logging settings, preventing unrelated credentials from reaching configured endpoints and keeping JSON output free of SDK logs.
19
+
7
20
  ## [2.6.7] - 2026-10-05
8
21
 
9
22
  ### Changed
@@ -283,25 +296,27 @@ This file lists notable user-facing changes. Internal refactors, test-only chang
283
296
  - Added file-level split planning and execution with Git-state concurrency checks.
284
297
  - Added provider presets and user/project configuration boundaries.
285
298
 
286
- [Unreleased]: https://github.com/hi-fullmoon/AICommit/compare/v2.6.7...HEAD
287
- [2.6.7]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.6.7
288
- [2.6.6]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.6.6
289
- [2.6.5]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.6.5
290
- [2.6.4]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.6.4
291
- [2.6.3]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.6.3
292
- [2.6.2]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.6.2
293
- [2.6.1]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.6.1
294
- [2.6.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.6.0
295
- [2.5.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.5.0
296
- [2.4.1]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.4.1
297
- [2.4.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.4.0
298
- [2.3.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.3.0
299
- [2.2.3]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.2.3
300
- [2.2.2]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.2.2
301
- [2.2.1]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.2.1
302
- [2.2.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.2.0
303
- [2.1.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.1.0
304
- [2.0.1]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.0.1
305
- [2.0.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.0.0
306
- [1.5.1]: https://github.com/hi-fullmoon/AICommit/releases/tag/v1.5.1
307
- [1.5.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v1.5.0
299
+ [Unreleased]: https://github.com/hi-fullmoon/AICommit/compare/v2.6.9...HEAD
300
+ [2.6.9]: https://github.com/hi-fullmoon/AICommit/tree/v2.6.9
301
+ [2.6.8]: https://github.com/hi-fullmoon/AICommit/tree/v2.6.8
302
+ [2.6.7]: https://github.com/hi-fullmoon/AICommit/tree/v2.6.7
303
+ [2.6.6]: https://github.com/hi-fullmoon/AICommit/tree/v2.6.6
304
+ [2.6.5]: https://github.com/hi-fullmoon/AICommit/tree/v2.6.5
305
+ [2.6.4]: https://github.com/hi-fullmoon/AICommit/tree/v2.6.4
306
+ [2.6.3]: https://github.com/hi-fullmoon/AICommit/tree/v2.6.3
307
+ [2.6.2]: https://github.com/hi-fullmoon/AICommit/tree/v2.6.2
308
+ [2.6.1]: https://github.com/hi-fullmoon/AICommit/tree/v2.6.1
309
+ [2.6.0]: https://github.com/hi-fullmoon/AICommit/tree/v2.6.0
310
+ [2.5.0]: https://github.com/hi-fullmoon/AICommit/tree/v2.5.0
311
+ [2.4.1]: https://github.com/hi-fullmoon/AICommit/tree/v2.4.1
312
+ [2.4.0]: https://github.com/hi-fullmoon/AICommit/tree/v2.4.0
313
+ [2.3.0]: https://github.com/hi-fullmoon/AICommit/tree/v2.3.0
314
+ [2.2.3]: https://github.com/hi-fullmoon/AICommit/tree/v2.2.3
315
+ [2.2.2]: https://github.com/hi-fullmoon/AICommit/tree/v2.2.2
316
+ [2.2.1]: https://github.com/hi-fullmoon/AICommit/tree/v2.2.1
317
+ [2.2.0]: https://github.com/hi-fullmoon/AICommit/tree/v2.2.0
318
+ [2.1.0]: https://github.com/hi-fullmoon/AICommit/tree/v2.1.0
319
+ [2.0.1]: https://github.com/hi-fullmoon/AICommit/tree/v2.0.1
320
+ [2.0.0]: https://github.com/hi-fullmoon/AICommit/tree/v2.0.0
321
+ [1.5.1]: https://github.com/hi-fullmoon/AICommit/tree/v1.5.1
322
+ [1.5.0]: https://github.com/hi-fullmoon/AICommit/tree/v1.5.0
package/README.md CHANGED
@@ -4,6 +4,27 @@
4
4
 
5
5
  AI-powered git commit message generator: reads your diff, asks an AI model for a conventional commit message, and commits after your confirmation.
6
6
 
7
+ [npm package](https://www.npmjs.com/package/@hifullmoon/aicommit) · [Releases](https://github.com/hi-fullmoon/AICommit/releases) · [Privacy model](docs/privacy.md)
8
+
9
+ - Use OpenAI, DeepSeek, OpenRouter, MiniMax, Kimi Code, Ollama, or a custom OpenAI-compatible endpoint.
10
+ - Review, edit, or cancel before committing; preview with `--dry-run`.
11
+ - Generate English or Chinese messages and apply shared [team commit policies](docs/team-policy.md).
12
+
13
+ AICommit runs locally without usage telemetry. Cloud providers receive the selected diff and context; choose a local Ollama endpoint to use a local model. See the [privacy model](docs/privacy.md) for details.
14
+
15
+ ## Quick start
16
+
17
+ Requires Node.js >= 22.19.0 and Git. Run the last two commands inside your Git repository after configuring a provider:
18
+
19
+ ```bash
20
+ npm install --global @hifullmoon/aicommit
21
+ aicommit setup
22
+ aicommit --dry-run
23
+ aicommit
24
+ ```
25
+
26
+ Cloud providers require your own API credentials. For Ollama, start your local server and install a model before setup.
27
+
7
28
  ## Usage preview
8
29
 
9
30
  These screenshots were captured from real interactive terminal sessions in this repository. Provider, model, paths, and timings reflect the environment at capture time.
@@ -492,7 +513,7 @@ The default `largeChange.strategy: "auto"` inventories every file locally, group
492
513
 
493
514
  A normal commit typically needs one model request, with no per-file AI calls or recursive model reduction. The inventory contains at most 16 representative groups under a UTF-8 byte budget, prioritizing coverage across code, configuration, tests, and other categories. It explicitly describes sampling limits. Both terminal and JSON output distinguish fully analyzed files, representative excerpts, and metadata-only files. Provider retries, response recovery, policy correction, and user-requested regeneration can still add requests.
494
515
 
495
- Split mode builds local candidates and sends them in bounded batches of at most `splitMaxPlanFiles`, then merges the batch plans hierarchically. When an `auto` inventory exceeds four times that candidate limit, adjacent candidates are first bundled locally by top-level module, file kind, and Git status; the model receives compact counts, examples, and selected excerpts while the complete file mapping stays local. Every file remains represented even when the complete candidate inventory cannot fit one request. If `deep` analysis exhausts its aggregate budget or the hierarchy cannot converge, interactive and dry-run flows produce one conservative all-files plan with an explicit warning instead of using incomplete model output. Non-interactive committing stops unless `--allow-single-fallback` explicitly authorizes that degradation. Small changes keep the existing request path.
516
+ Split mode builds local candidates and sends them in bounded batches of at most `splitMaxPlanFiles`, then merges the batch plans hierarchically. When an `auto` inventory exceeds four times that candidate limit, adjacent candidates are first bundled locally by top-level module, file kind, and Git status; the model receives compact counts, examples, and selected excerpts while the complete file mapping stays local. Every file remains represented even when the complete candidate inventory cannot fit one request. Exhausted analysis budgets stop without committing; increase the budget or use smaller batches. If the hierarchy cannot converge while budget remains, an all-files commit message can be generated from local change summaries; non-interactive committing requires `--allow-single-fallback`. Plans omitting files or hunks are rejected instead of creating an automatic "update remaining files" commit. Small changes keep the existing request path.
496
517
 
497
518
  For exhaustive chunk-by-chunk model analysis, opt in through personal configuration:
498
519
 
@@ -514,7 +535,7 @@ For exhaustive chunk-by-chunk model analysis, opt in through personal configurat
514
535
  }
515
536
  ```
516
537
 
517
- `deep` spends more requests and tokens, with a maximum of 256 requests. Before dispatch, a preflight estimate covers initial chunks, required reductions, and the minimum hierarchical planning tree; an impossible deep run switches to the local inventory path, and validated cache hits are excluded from that estimate. Validated initial fact chunks are stored briefly under Git metadata, reused when the same snapshot is retried after failure or interruption, and removed after complete generation succeeds. The cache does not directly store captured diffs, reasoning, credentials, or complete provider responses; it stores model summaries that may contain code-derived details. Unprotected original input is not persisted unless personal configuration explicitly enables `allowUnprotected`. Repository configuration cannot change this personal strategy, enable unprotected caching, or raise spending/cache ceilings. Both strategies use conservative token estimates; cache hits consume no request or token budget. Incomplete model output is never committed: budget/capacity fallback is a new complete plan containing every reviewed file; interactive runs show it for review, while non-interactive committing requires `--allow-single-fallback`.
538
+ `deep` spends more requests and tokens, with a maximum of 256 requests. Before dispatch, a preflight estimate covers initial chunks, required reductions, and the minimum hierarchical planning tree; an impossible deep run switches to the local inventory path, and validated cache hits are excluded from that estimate. Validated initial fact chunks are stored briefly under Git metadata, reused when the same snapshot is retried after failure or interruption, and removed after complete generation succeeds. The cache does not directly store captured diffs, reasoning, credentials, or complete provider responses; it stores model summaries that may contain code-derived details. Unprotected original input is not persisted unless personal configuration explicitly enables `allowUnprotected`. Repository configuration cannot change this personal strategy, enable unprotected caching, or raise spending/cache ceilings. Both strategies use conservative token estimates; cache hits consume no request or token budget. Incomplete model output is never committed. Budget exhaustion stops generation; capacity fallback requires enough budget to generate a message from change summaries. Interactive runs show it for review, while non-interactive committing requires `--allow-single-fallback`.
518
539
 
519
540
  Large-change split planning completes file grouping before repairing commit messages. If a message violates the policy (for example, its description exceeds 72 characters), up to three message-only correction rounds preserve file assignments and valid messages without resending diffs. These rounds share the existing request, time, and token budgets; JSON recovery may require an additional request within a round. If automatic repair fails, interactive runs offer an editor for the invalid messages and then return to normal plan review. Non-interactive runs stop without committing or collapsing the groups into a single commit. For protected input, a private temporary diagnostic JSON file preserves the complete grouping and messages; it is not an artifact accepted by `split apply`.
520
541
 
package/README.zh-CN.md CHANGED
@@ -4,6 +4,27 @@
4
4
 
5
5
  AI 驱动的 Git 提交信息生成器:读取 diff,请 AI 模型生成符合 Conventional Commits 规范的提交信息,并在你确认后执行提交。
6
6
 
7
+ [npm 包](https://www.npmjs.com/package/@hifullmoon/aicommit) · [版本发布](https://github.com/hi-fullmoon/AICommit/releases) · [隐私模型](docs/privacy.md)
8
+
9
+ - 支持 OpenAI、DeepSeek、OpenRouter、MiniMax、Kimi Code、Ollama 和自定义 OpenAI 兼容端点。
10
+ - 提交前可以检查、编辑或取消;通过 `--dry-run` 预览。
11
+ - 支持中文或英文提交信息,以及共享的[团队提交策略](docs/team-policy.md)。
12
+
13
+ AICommit 在本地运行,不记录使用指标。使用云端 Provider 时,选定的 diff 和上下文会发送给该 Provider;选择本地 Ollama 端点可以使用本地模型。详见[隐私模型](docs/privacy.md)。
14
+
15
+ ## 快速开始
16
+
17
+ 需要 Node.js >= 22.19.0 和 Git。配置 Provider 后,在你的 Git 仓库内执行最后两条命令:
18
+
19
+ ```bash
20
+ npm install --global @hifullmoon/aicommit
21
+ aicommit setup
22
+ aicommit --dry-run
23
+ aicommit
24
+ ```
25
+
26
+ 云端 Provider 需要你自己的 API 凭据。使用 Ollama 时,请先启动本地服务并安装模型,再运行配置向导。
27
+
7
28
  ## 使用预览
8
29
 
9
30
  以下截图来自本仓库中的真实交互式终端会话。Provider、模型、路径和耗时均为截图时的实际环境。
@@ -317,7 +338,7 @@ aicommit --yes --dry-run --scope=staged --output=json # 只预览暂存区
317
338
  aicommit generate --scope=staged --file=/tmp/commit-plan.json --yes --output=json
318
339
  aicommit apply --file=/tmp/commit-plan.json --yes --output=json
319
340
  aicommit split --scope=all --yes # 非交互规划并提交所有工作区变更
320
- aicommit split --scope=all --yes --allow-single-fallback # 明确允许规划预算耗尽后的保守提交
341
+ aicommit split --scope=all --yes --allow-single-fallback # 明确允许预算内生成的保守单次提交
321
342
  aicommit split plan --scope=staged --file=/tmp/split-plan.json --yes
322
343
  aicommit split apply --file=/tmp/split-plan.json --yes
323
344
  aicommit split resume --yes # 恢复中断的拆分事务
@@ -494,7 +515,7 @@ exec zsh
494
515
 
495
516
  普通提交通常只需要一次模型请求,不会为每个文件调用 AI,也不会递归调用模型汇总。摘要最多包含 16 个代表组,并受 UTF-8 字节预算约束;优先覆盖代码、配置和测试等不同类别。摘要明确说明抽样范围,界面和 JSON 分别报告全文分析、代表片段和仅元数据的文件数,不把抽样视为完整理解。提供方重试、响应恢复、格式修正和用户重新生成仍可能增加请求。
496
517
 
497
- 批次提交先在本地建立候选组,再按每批最多 `splitMaxPlanFiles` 个候选发送,并分层合并各批计划。当 `auto` 清单规模超过该候选上限的四倍时,会先按顶层模块、文件类型和 Git 状态在本地归并相邻候选;模型只接收紧凑计数、少量路径示例和代表片段,完整文件映射始终留在本地。完整候选清单放不进一次请求时,仍会保留每个文件。如果 `deep` 分析耗尽总预算,或分层规划无法收敛,交互和 dry-run 流程会明确警告并生成一个覆盖全部文件的保守计划,而不会采用不完整的模型结果;非交互提交默认停止,只有显式传入 `--allow-single-fallback` 才允许该降级。小变更保持原有请求路径。
518
+ 批次提交先在本地建立候选组,再按每批最多 `splitMaxPlanFiles` 个候选发送,并分层合并各批计划。当 `auto` 清单规模超过该候选上限的四倍时,会先按顶层模块、文件类型和 Git 状态在本地归并相邻候选;模型只接收紧凑计数、少量路径示例和代表片段,完整文件映射始终留在本地。完整候选清单放不进一次请求时,仍会保留每个文件。分析预算耗尽时停止提交,保留变更并提示提高预算或减少单批文件。如果分层规划无法收敛且预算仍充足,可根据本地变更摘要生成覆盖全部文件的单次提交;非交互提交需要 `--allow-single-fallback`。遗漏文件或 hunk 的计划会被拒绝,不再自动生成“更新其余文件”。小变更保持原有请求路径。
498
519
 
499
520
  确实需要逐块 AI 分析时,在个人配置中设置:
500
521
 
@@ -516,7 +537,7 @@ exec zsh
516
537
  }
517
538
  ```
518
539
 
519
- `deep` 会增加请求和 token 消耗,最多 256 次请求。请求前会预估初始分块、必要归并和最小分层规划树的成本;确定无法装入总预算时直接切换到本地清单路径,已验证的缓存命中不计入这次预估。通过完整校验的初始事实分块会短期写入 Git 元数据目录;同一快照失败或中断后重试时直接复用,完整生成成功后清理。缓存不直接保存捕获的 diff、推理、凭据或完整 Provider 响应,只保存可能包含代码派生细节的模型摘要;选择发送未保护的原始内容时默认不落盘,只有个人配置显式设置 `allowUnprotected: true` 才允许。仓库配置不能切换策略、启用未保护缓存或提高费用与缓存上限。两种策略均使用保守 token 估算,未知 usage 按预留额度计入;缓存命中不计请求或 token。模型的不完整输出永远不会被提交:预算或容量降级会重新生成一个包含全部已审核文件的完整计划;交互模式先展示确认,非交互提交则要求 `--allow-single-fallback`。
540
+ `deep` 会增加请求和 token 消耗,最多 256 次请求。请求前会预估初始分块、必要归并和最小分层规划树的成本;确定无法装入总预算时直接切换到本地清单路径,已验证的缓存命中不计入这次预估。通过完整校验的初始事实分块会短期写入 Git 元数据目录;同一快照失败或中断后重试时直接复用,完整生成成功后清理。缓存不直接保存捕获的 diff、推理、凭据或完整 Provider 响应,只保存可能包含代码派生细节的模型摘要;选择发送未保护的原始内容时默认不落盘,只有个人配置显式设置 `allowUnprotected: true` 才允许。仓库配置不能切换策略、启用未保护缓存或提高费用与缓存上限。两种策略均使用保守 token 估算,未知 usage 按预留额度计入;缓存命中不计请求或 token。模型的不完整输出永远不会被提交。预算耗尽会停止生成;容量降级只有在剩余预算足够根据变更摘要生成提交信息时才可继续,交互模式先展示确认,非交互提交则要求 `--allow-single-fallback`。
520
541
 
521
542
  大变更拆分先完成全部文件分组,再修正不合规的提交信息。自动修正最多三轮,只发送出错的消息、实际长度和校验原因,不重发 diff,也不改动文件归属或已合规的消息。修正与原规划共用请求、时间和 token 预算;每轮 JSON 恢复可能额外请求一次。自动修正失败后,交互模式允许编辑出错的提交信息,校验通过后返回正常计划确认流程。非交互模式停止提交,不会将已有分组合并成单次提交;对于已保护的输入,会将完整分组和消息保存到私有临时诊断文件,该文件不能直接用于 `split apply`。
522
543
 
@@ -33,7 +33,7 @@ The release workflow uses npm Trusted Publishing without a long-lived `NPM_TOKEN
33
33
  ```bash
34
34
  workdir=$(mktemp -d)
35
35
  cd "$workdir"
36
- npm install --package-lock-only @hifullmoon/aicommit@2.6.7
36
+ npm install --package-lock-only @hifullmoon/aicommit@2.6.9
37
37
  npm audit signatures
38
38
  ```
39
39
 
@@ -0,0 +1,32 @@
1
+ # Model capability metadata
2
+
3
+ `src/model-capabilities.json` contains the reasoning capabilities and context/output limits of 403 OpenAI,
4
+ DeepSeek, and OpenRouter model IDs from `@earendil-works/pi-ai` version 0.85.0.
5
+ Models sharing the same capabilities share one profile. This is a static metadata
6
+ snapshot, not a runtime dependency or a model availability guarantee. When updating
7
+ it, verify supported efforts and disabled reasoning behavior against provider
8
+ documentation; unknown model IDs continue to use the existing fallback.
9
+
10
+ Source: https://github.com/earendil-works/pi/tree/main/packages/ai
11
+
12
+ MIT License
13
+
14
+ Copyright (c) 2025 Mario Zechner
15
+
16
+ Permission is hereby granted, free of charge, to any person obtaining a copy
17
+ of this software and associated documentation files (the "Software"), to deal
18
+ in the Software without restriction, including without limitation the rights
19
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20
+ copies of the Software, and to permit persons to whom the Software is
21
+ furnished to do so, subject to the following conditions:
22
+
23
+ The above copyright notice and this permission notice shall be included in all
24
+ copies or substantial portions of the Software.
25
+
26
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
+ SOFTWARE.
@@ -1,53 +1,53 @@
1
1
  # Provider compatibility / Provider 兼容表
2
2
 
3
- AICommit uses **Pi AI** (`@earendil-works/pi-ai`, pinned to 0.85.0) for model request construction, message conversion, SSE decoding, thinking events, and normalized results. Node.js **>=22.19.0** is required. See the [Pi AI documentation](https://github.com/earendil-works/pi/tree/main/packages/ai).
3
+ AICommit uses the official **OpenAI JavaScript SDK** (`openai`, pinned to 6.40.0) for Chat Completions and SSE decoding. Node.js **>=22.19.0** is required. See the [OpenAI SDK documentation](https://developers.openai.com/api/reference/typescript).
4
4
 
5
- AICommit 使用 **Pi AI**(`@earendil-works/pi-ai`,固定为 0.85.0)构造模型请求、转换消息、解析 SSE,并读取统一的推理事件和结果。要求 Node.js **>=22.19.0**。
5
+ AICommit 使用官方 **OpenAI JavaScript SDK**(`openai`,固定为 6.40.0)发送 Chat Completions 请求并解码 SSE。要求 Node.js **>=22.19.0**。
6
6
 
7
- The runtime keeps the existing Provider/Model config format. `providers.js` selects Pi model metadata and applies configuration overrides; `model-client.js` calls Pi's `openai-completions` implementation. `provider-response.js` normalizes legacy response fields before Pi; its SSE framing uses the lightweight [eventsource-parser](https://github.com/rexxars/eventsource-parser) dependency. `api.js` retains commit prompts, policy validation, and recovery. Presets remain setup data, not executable adapters.
7
+ The existing Provider/Model configuration format is preserved. `providers.js` applies model capability checks and vendor parameter mappings; `model-client.js` calls the SDK through the application's restricted transport. `provider-response.js` normalizes vendor fields using [eventsource-parser](https://github.com/rexxars/eventsource-parser) for SSE framing. `api.js` retains commit prompts, policy validation, and recovery.
8
8
 
9
- 现有 Provider/Model 配置格式保持不变。`providers.js` 选择 Pi 模型元数据并应用配置覆盖;`model-client.js` 调用 Pi 的 `openai-completions` 实现;`provider-response.js` 在进入 Pi 前统一旧版响应字段,SSE 分帧使用轻量依赖 `eventsource-parser`;`api.js` 保留提交提示词、规则校验与恢复。预设仍是 setup 数据,不是可执行适配器。
9
+ 现有 Provider/Model 配置格式保持不变。`providers.js` 负责模型能力校验与厂商参数映射;`model-client.js` 通过应用已有的受限请求层调用 SDK;`provider-response.js` 使用 `eventsource-parser` 解析 SSE 并统一厂商响应字段;`api.js` 保留提交提示词、规则校验与恢复。
10
10
 
11
- | Provider / adapter | Pi integration / Pi 接入 | Reasoning / 推理 | Token budget / 输出预算 |
12
- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
13
- | OpenAI / `openai` | Chat Completions; bundled model metadata / Chat Completions 与内置模型元数据 | Pi thinking-level map; unsupported known efforts rejected locally / 使用 Pi 强度映射,已知不支持的强度本地拒绝 | Reasoning: `max_completion_tokens`; otherwise `max_tokens` |
14
- | OpenRouter / `openrouter` | Chat Completions; `X-Title: aicommit` | Pi `reasoning.effort` and catalog capability checks / Pi 参数映射与模型能力检查 | `max_tokens` |
15
- | DeepSeek / `deepseek` | Chat Completions; bundled model metadata / 内置模型元数据 | Pi `thinking.type` and effort mapping; enabled thinking omits temperature / Pi 映射推理参数,开启时省略 temperature | `max_tokens` |
16
- | MiniMax / `minimax` | Chat Completions / 兼容接口 | Small compatibility override for `reasoning_split` and thinking switches / 保留少量开关兼容逻辑 | `max_tokens` |
17
- | Kimi Code / `custom` | Existing OpenAI-compatible endpoint and `kimi-for-coding` preset / 保留现有兼容端点与预设 | Server defaults; configurable body switches / 服务端默认值或自定义请求体 | `max_tokens` |
18
- | Ollama / `ollama` | Native JSON bridge for `/api/chat` and `/api/generate`; compatible `/v1/chat/completions` uses Pi directly / 原生端点使用 JSON 桥接,兼容端点直接使用 Pi | Native `think` switch / 原生开关 | Native: `options.num_predict`; compatible: `max_tokens` |
19
- | Custom / `custom` | Arbitrary OpenAI-compatible model IDs and full endpoint URLs / 任意兼容模型 ID 与完整端点 URL | `enabledBody` / `disabledBody`; no inferred vendor fields / 不自动注入厂商开关 | `max_tokens` |
11
+ | Provider / adapter | Protocol / 协议 | Reasoning / 推理 | Token budget / 输出预算 |
12
+ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
13
+ | OpenAI / `openai` | Chat Completions | Local effort mapping and capability checks / 本地强度映射与能力校验 | Reasoning: `max_completion_tokens`; otherwise `max_tokens` |
14
+ | OpenRouter / `openrouter` | Chat Completions; `X-Title: aicommit` | `reasoning.effort` and model capability checks / 强度映射与模型能力校验 | `max_tokens` |
15
+ | DeepSeek / `deepseek` | Chat Completions | `thinking.type` and effort mapping; thinking omits temperature / 开关与强度映射,开启推理时省略 temperature | `max_tokens` |
16
+ | MiniMax / `minimax` | Chat Completions | `reasoning_split` and thinking switches / 推理分离与开关 | `max_tokens` |
17
+ | Kimi Code / `custom` | OpenAI-compatible endpoint and `kimi-for-coding` preset / 兼容端点与现有预设 | Server defaults or configured body switches / 服务端默认值或配置的请求体开关 | `max_tokens` |
18
+ | Ollama / `ollama` | Native JSON bridge for `/api/chat` and `/api/generate`; SDK for compatible endpoints / 原生端点使用 JSON 桥接,兼容端点使用 SDK | Native `think` switch / 原生开关 | Native: `options.num_predict`; compatible: `max_tokens` |
19
+ | Custom / `custom` | Full OpenAI-compatible endpoint URLs / 完整兼容端点 URL | `enabledBody` / `disabledBody` | `max_tokens` |
20
20
 
21
21
  ## Configuration and model metadata / 配置与模型元数据
22
22
 
23
- - `apiUrl` is still the **complete endpoint**, not a base URL. Proxy paths and query parameters are preserved. Requests use only the resolved AICommit credential. Pi environment-key discovery and OAuth are not invoked, and redirects are rejected.
24
- - `modelId` need not exist in Pi's catalog. Known OpenAI, DeepSeek, and OpenRouter models use the bundled metadata; unknown IDs retain a compatible fallback. No online model discovery runs during setup or generation.
25
- - `reasoning.mode: auto` preserves server defaults and explicit `extraBody`. `on` / `off` applies the selected mode after extras. Setup filters known supported effort levels. DeepSeek's legacy unsupported effort values are normalized by Pi: for the pinned V4 Flash catalog, `medium` becomes `high`, and `xhigh` becomes `max`.
26
- - Pi requests SSE by default, even when the CLI does not display reasoning. Complete JSON responses are bridged into Pi events. Set `extraBody: { "stream": false }` for endpoints that reject streaming requests; streaming-only options are removed automatically.
27
- - Native Ollama remains non-streaming. `/api/generate` receives `system` and `prompt`, while `/api/chat` receives `messages`; existing `options` are retained.
23
+ - `apiUrl` is the **complete endpoint**. Proxy paths and query parameters are preserved. Only the resolved AICommit credential is sent; SDK environment credential discovery is bypassed and redirects are rejected.
24
+ - `src/model-capabilities.json` preserves the reasoning capabilities, assistant message compatibility requirements, and context/output limits of 403 model IDs from the previous pinned Pi AI 0.85.0 catalog, sharing 176 capability profiles. It is a static metadata snapshot with [source and license information](model-capabilities-license.md), not a runtime Pi dependency. Unknown IDs retain the existing fallback. No online model discovery runs during setup or generation.
25
+ - `reasoning.mode: auto` preserves server defaults and explicit `extraBody`. Explicit `on` / `off` takes precedence over extras. Setup filters supported efforts. DeepSeek V4 Flash maps legacy `medium` to `high` and `xhigh` to `max`.
26
+ - SSE is requested by default, including when reasoning is not displayed. Complete JSON responses are normalized into SDK-readable events. `extraBody: { "stream": false }` disables streaming for incompatible endpoints and removes streaming-only options.
27
+ - Native Ollama remains non-streaming. `/api/generate` receives `system` and `prompt`; `/api/chat` receives `messages`. Existing `options` are retained.
28
28
 
29
29
  对应行为:
30
30
 
31
- - `apiUrl` 仍填写**完整接口地址**,代理路径与查询参数会保留。鉴权只使用 AICommit 已解析的凭据,不调用 Pi 的环境变量凭据发现或 OAuth,也不跟随重定向。
32
- - Pi 目录中没有的 `modelId` 也可以配置;已知 OpenAI、DeepSeek、OpenRouter 模型使用随依赖发布的元数据,未知模型走兼容路径。setup 与生成过程不在线拉取模型目录。
33
- - `reasoning.mode: auto` 保留服务端默认值及显式 `extraBody`;`on` / `off` 在 extras 之后应用。setup 根据已知能力过滤强度。DeepSeek 的旧配置由 Pi 归一:当前 V4 Flash 目录中 `medium` 映射为 `high`,`xhigh` 映射为 `max`。
34
- - Pi 默认请求 SSE,包括终端不展示推理的场景;完整 JSON 响应通过桥接交给 Pi。若服务拒绝流式请求,可配置 `extraBody: { "stream": false }`,流式专用参数会自动移除。
35
- - Ollama 原生端点继续使用非流式响应,保留 `options`;`/api/generate` 使用 `system` / `prompt`,`/api/chat` 使用 `messages`。
31
+ - `apiUrl` 仍填写**完整接口地址**,代理路径与查询参数会保留。仅发送 AICommit 已解析的凭据,不使用 SDK 自动读取的环境变量凭据,也不跟随重定向。
32
+ - `src/model-capabilities.json` 保存原 Pi AI 0.85.0 目录中 403 个模型 ID 的推理能力、assistant 消息兼容要求、上下文与输出上限,共享 176 组能力配置。这是带来源及许可说明的静态元数据,运行时不再依赖 Pi。未知模型继续走兼容路径,setup 与生成过程不在线拉取目录。
33
+ - `auto` 保留服务端默认值及显式 `extraBody`;`on` / `off` 在 extras 之后应用。setup 根据能力过滤强度。DeepSeek V4 Flash 的旧配置 `medium` 映射为 `high`,`xhigh` 映射为 `max`。
34
+ - 默认请求 SSE;完整 JSON 响应会统一为 SDK 可读取的事件。服务拒绝流式请求时,可配置 `extraBody: { "stream": false }`,流式专用参数会自动移除。
35
+ - Ollama 原生端点保留非流式响应和 `options`;`/api/generate` 使用 `system` / `prompt`,`/api/chat` 使用 `messages`。
36
36
 
37
37
  ## Result and retry contract / 结果与重试契约
38
38
 
39
- Callers receive `content`, optional `reasoning`, normalized usage, finish reason, capabilities, attempts, and latency. Cached input tokens are included once in `inputTokens`; reasoning tokens are already part of output usage. `piMessage` exposes Pi's normalized assistant result. `raw` retains the actual complete JSON response, or a reconstructed Chat Completions result for SSE, preserving `callAPI` compatibility.
39
+ Callers receive `content`, optional `reasoning`, normalized usage, finish reason, capabilities, attempts, and latency. Cached input tokens are included once in `inputTokens`; reasoning tokens are already part of output usage. The legacy `piMessage` field retains assistant content blocks and token usage for compatibility; it is assembled locally and no longer supplies catalog price estimates or Pi replay metadata. `raw` retains complete JSON responses or reconstructed Chat Completions results for SSE.
40
40
 
41
- Retries remain owned by AICommit; Pi and the underlying SDK's automatic retries are disabled. Only 429, selected 5xx, and network failures **before an accepted response** can retry. Accepted-body interruptions, malformed responses, authentication, invalid parameters, and safety failures are never automatically replayed. Oversized `Retry-After` fails instead of retrying early.
41
+ Retries are owned by AICommit; SDK automatic retries are disabled. Only 429, selected 5xx, and network failures **before an accepted response** may retry. Accepted-body interruptions, malformed responses, authentication, invalid parameters, and safety failures are never automatically replayed. Oversized `Retry-After` fails instead of retrying early.
42
42
 
43
- SSE must contain a `finish_reason`. A clean EOF or `[DONE]` alone is rejected, and partial content is not returned as a successful generation. Token-limit aliases (`max_tokens`, `max_output_tokens`, `token_limit`) are normalized to `length` before Pi so recovery can run. Textual `reasoning_details`, including legacy shapes, are combined with ordinary reasoning deltas in arrival order. Duplicate representations within one event are emitted once; repeated text in later events is retained. Encrypted metadata remains opaque.
43
+ SSE must contain a `finish_reason`. A clean EOF or `[DONE]` alone is rejected. Token-limit aliases (`max_tokens`, `max_output_tokens`, `token_limit`) normalize to `length` so recovery can run. Textual `reasoning_details`, including legacy shapes, are combined with ordinary reasoning deltas in arrival order. Duplicate representations within one event are emitted once; repeated text in later events is retained. Encrypted metadata is not displayed.
44
44
 
45
- 业务仍获得 `content`、可选 `reasoning`、归一 usage、结束原因、能力、尝试次数与耗时。缓存输入 token 只计入一次,推理 token 已包含在输出中。`piMessage` 提供 Pi 的统一 assistant 结果;完整 JSON 的 `raw` 保留原响应,SSE 的 `raw` 则重建兼容 Chat Completions 结构。
45
+ 业务仍获得 `content`、可选 `reasoning`、归一 usage、结束原因、能力、尝试次数与耗时。缓存输入 token 只计入一次,推理 token 已包含在输出中。旧字段 `piMessage` 保留 assistant 内容块和 token 用量兼容结构,由本地组装,不再提供目录价格估算或 Pi 重放元数据。`raw` 保留完整 JSON 原响应,或重建 SSE 的 Chat Completions 结果。
46
46
 
47
- 重试由 AICommit 负责,Pi 与底层 SDK 的自动重试均已关闭。只有 429、部分 5xx,以及**收到成功响应前**的网络失败可重试;已接受请求后的响应中断、格式错误、鉴权、参数及安全错误不会自动重放。超过上限的 `Retry-After` 会直接报错,不提前重试。
47
+ 重试由 AICommit 负责,SDK 自动重试已关闭。仅 429、部分 5xx,以及**收到成功响应前**的网络失败可重试;已接受请求后的响应中断、格式错误、鉴权、参数及安全错误不会自动重放。超过上限的 `Retry-After` 会直接报错。
48
48
 
49
- SSE 必须带 `finish_reason`。只有 EOF 或 `[DONE]` 时会拒绝结果,不将半截内容当作成功生成。输出上限别名(`max_tokens`、`max_output_tokens`、`token_limit`)在进入 Pi 前归一为 `length`,保留补全恢复流程。`reasoning_details`(含旧格式)中的文本与普通推理分片按到达顺序合并;同一事件中的重复表示只展示一次,后续事件中重复出现的文本则保留。加密元数据不会作为推理文本输出。
49
+ SSE 必须带 `finish_reason`,仅有 EOF 或 `[DONE]` 时会拒绝结果。输出上限别名归一为 `length`,保留补全恢复流程。推理文本按到达顺序合并;同一事件中的重复表示只展示一次,后续事件中重复出现的文本保留。加密元数据不会作为推理文本输出。
50
50
 
51
- Use `aicommit doctor -p provider-name -m model-name` to verify a configured connection. This integration covers the existing six adapter types; installing Pi does **not** automatically expose every Pi provider, OAuth flow, or native Anthropic/Gemini/Responses endpoint. Those protocols require explicit routing and configuration support.
51
+ Use `aicommit doctor -p provider-name -m model-name` to verify a configured connection. The six existing adapter types are supported; native Anthropic/Gemini/Responses endpoints and OAuth require explicit routing and configuration support.
52
52
 
53
- 使用 `aicommit doctor -p provider-name -m model-name` 检查配置的连接。本次接入覆盖现有六种适配类型;安装 Pi **不会自动开放**其全部供应商、OAuth 或 Anthropic/Gemini/Responses 原生端点,这些协议需要显式扩展路由与配置。
53
+ 使用 `aicommit doctor -p provider-name -m model-name` 检查配置的连接。现有六种适配类型保持支持;Anthropic、Gemini、Responses 原生端点及 OAuth 需要额外的路由与配置支持。
@@ -36,9 +36,9 @@ If a failure remains, capture `aicommit doctor --output=json`, Node/Git versions
36
36
 
37
37
  ## Large-change limits / 大变更限制
38
38
 
39
- Default `auto` analysis builds a local inventory and selects bounded excerpts, then batches oversized split inventories and merges their plans hierarchically. Deep analysis still has fixed request (256) and depth (8) limits. If its aggregate token/time budget is exhausted or hierarchical planning cannot converge, split mode emits an explicit warning and can fall back to one complete all-files plan; it never uses a partial model plan. Interactive and dry-run flows show that plan, while non-interactive committing requires the explicit `--allow-single-fallback` option. Token/time limits remain configurable in personal settings. Unknown model token counts use conservative estimates; an oversized request is not dispatched, and provider-context errors are not blindly replayed.
39
+ Default `auto` analysis builds a local inventory and selects bounded excerpts, then batches oversized split inventories and merges their plans hierarchically. Deep analysis still has fixed request (256) and depth (8) limits. Exhausted token/time budgets stop without committing, even with `--allow-single-fallback`; increase the budget or use smaller batches. If hierarchical planning cannot converge while budget remains, a complete all-files message can be generated from local summaries. Non-interactive committing requires `--allow-single-fallback`. Missing file or hunk coverage is rejected instead of receiving a generic catch-all message. Unknown model token counts use conservative estimates; an oversized request is not dispatched, and provider-context errors are not blindly replayed.
40
40
 
41
- 默认 `auto` 在本地建立清单并选择受限片段;拆分候选过多时会分批请求,再分层合并计划。深度分析仍有固定的请求数(256)和汇总层级(8)上限。如果总 token/时间预算耗尽,或分层规划无法收敛,拆分模式会明确警告,并可降级为一个覆盖全部文件的计划,绝不会采用模型返回的半份计划。交互和 dry-run 流程会展示该计划;非交互提交必须显式传入 `--allow-single-fallback`。token 和时间预算仍可在个人配置中调整。未知模型采用保守 token 估算,单次输入超限时不会发送该请求;Provider 上下文超限不会盲目重试。
41
+ 默认 `auto` 在本地建立清单并选择受限片段;拆分候选过多时会分批请求,再分层合并计划。深度分析仍有固定的请求数(256)和汇总层级(8)上限。总 token/时间预算耗尽时停止提交,即使传入 `--allow-single-fallback` 也不会生成固定文案;请提高预算或减少单批文件。如果分层规划无法收敛且预算仍充足,可根据本地摘要生成覆盖全部文件的提交信息;非交互提交必须显式传入 `--allow-single-fallback`。遗漏文件或 hunk 的计划直接拒绝。未知模型采用保守 token 估算,单次输入超限时不会发送该请求;Provider 上下文超限不会盲目重试。
42
42
 
43
43
  Validated initial `deep` chunks are cached under private Git metadata after a failed or interrupted run. A retry of the identical snapshot and model settings reports cached chunks and requests only the remainder. Any input/model/protection change causes a miss. Successful generation clears the active cache; stale entries expire after 24 hours. Unprotected input is not cached unless personal `largeChange.cache.allowUnprotected` is explicitly enabled.
44
44
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hifullmoon/aicommit",
3
- "version": "2.6.7",
4
- "description": "Safe, local-first AI commit message generator for Git workflows",
3
+ "version": "2.6.9",
4
+ "description": "AI Git commit message CLI for Conventional Commits with OpenAI, DeepSeek, OpenRouter and local Ollama models",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "aicommit": "./bin/aicommit.js"
@@ -11,6 +11,7 @@
11
11
  "CHANGELOG.md",
12
12
  "LICENSE",
13
13
  "README.md",
14
+ "README.zh-CN.md",
14
15
  "SECURITY.md",
15
16
  "bin/",
16
17
  "docs/*.md",
@@ -48,7 +49,6 @@
48
49
  "lines": 70
49
50
  },
50
51
  "dependencies": {
51
- "@earendil-works/pi-ai": "0.85.0",
52
52
  "@inquirer/checkbox": "^4.3.2",
53
53
  "@inquirer/confirm": "^5.1.0",
54
54
  "@inquirer/core": "^10.3.2",
@@ -60,6 +60,7 @@
60
60
  "chalk": "^5.4.0",
61
61
  "eventsource-parser": "4.1.0",
62
62
  "ora": "^8.2.0",
63
+ "openai": "6.40.0",
63
64
  "wrap-ansi": "^9.0.2"
64
65
  },
65
66
  "keywords": [
@@ -67,11 +68,20 @@
67
68
  "commit",
68
69
  "ai",
69
70
  "cli",
71
+ "aicommit",
72
+ "ai-commit",
73
+ "git-commit",
74
+ "commit-message",
75
+ "commit-message-generator",
70
76
  "conventional-commits",
77
+ "developer-tools",
71
78
  "openai",
72
79
  "deepseek",
73
80
  "openrouter",
74
- "ollama"
81
+ "ollama",
82
+ "minimax",
83
+ "kimi",
84
+ "local-llm"
75
85
  ],
76
86
  "repository": {
77
87
  "type": "git",