@hifullmoon/aicommit 2.6.0 → 2.6.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/CHANGELOG.md +8 -1
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/docs/distribution.md +1 -1
- package/package.json +1 -1
- package/src/change-analysis.js +23 -4
- package/src/generation-ui.js +3 -0
- package/src/split.js +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ This file lists notable user-facing changes. Internal refactors, test-only chang
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [2.6.1] - 2026-09-14
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Split mode now streams thinking during each large-change planning batch, with batch progress in the spinner; interactive review still shows only the final plan's reasoning.
|
|
12
|
+
|
|
7
13
|
## [2.6.0] - 2026-09-14
|
|
8
14
|
|
|
9
15
|
### Added
|
|
@@ -233,7 +239,8 @@ This file lists notable user-facing changes. Internal refactors, test-only chang
|
|
|
233
239
|
- Added file-level split planning and execution with Git-state concurrency checks.
|
|
234
240
|
- Added provider presets and user/project configuration boundaries.
|
|
235
241
|
|
|
236
|
-
[Unreleased]: https://github.com/hi-fullmoon/AICommit/compare/v2.6.
|
|
242
|
+
[Unreleased]: https://github.com/hi-fullmoon/AICommit/compare/v2.6.1...HEAD
|
|
243
|
+
[2.6.1]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.6.1
|
|
237
244
|
[2.6.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.6.0
|
|
238
245
|
[2.5.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.5.0
|
|
239
246
|
[2.4.1]: https://github.com/hi-fullmoon/AICommit/releases/tag/v2.4.1
|
package/README.md
CHANGED
|
@@ -455,7 +455,7 @@ The staged index (or complete split-mode working tree, including untracked file
|
|
|
455
455
|
|
|
456
456
|
Reasoning defaults to `on` with `medium` effort. It is mapped natively for OpenAI reasoning models, DeepSeek, OpenRouter, and MiniMax; models that do not expose reasoning continue normally and show an unavailable notice instead of failing. Official OpenAI endpoints validate the selected effort against the model generation before sending the request, so unsupported combinations such as `o3 --no-reasoning` or `gpt-5.1 --reasoning=max` fail locally with a clear list of supported levels. DeepSeek's current `deepseek-v4-flash` and `deepseek-v4-pro` models receive `thinking: { "type": "enabled" }` plus `reasoning_effort`; `medium`/`xhigh` are normalized to DeepSeek's `high` level.
|
|
457
457
|
|
|
458
|
-
When reasoning mode is `on` (including via `--reasoning=<level>`), aicommit requests a streaming response and displays reasoning as it arrives. In `auto` mode it also displays thinking if the provider emits it, without forcing reasoning on. Split mode streams
|
|
458
|
+
When reasoning mode is `on` (including via `--reasoning=<level>`), aicommit requests a streaming response and displays reasoning as it arrives. In `auto` mode it also displays thinking if the provider emits it, without forcing reasoning on. Split mode streams thinking from each sequential planning batch with a batch label; the review prompt keeps only the final plan's reasoning. Earlier deep-analysis chunks show progress. The live panel requires an interactive terminal, and JSON output never includes reasoning. The live view follows the newest two terminal lines by default; press `Ctrl+O` to expand or collapse the accumulated text during generation or review. Long expanded output is kept inside the terminal viewport—use `PageUp`/`PageDown` to read every page. Holding `Ctrl+O` counts as one toggle, so key repeat cannot leave duplicate panels behind. Output is sanitized and capped by `reasoning.maxDisplayChars`; providers that do not expose reasoning show a short unavailable notice.
|
|
459
459
|
|
|
460
460
|
```json
|
|
461
461
|
{
|
package/README.zh-CN.md
CHANGED
|
@@ -457,7 +457,7 @@ exec zsh
|
|
|
457
457
|
|
|
458
458
|
推理默认为 `on`,强度为 `medium`。OpenAI 推理模型、DeepSeek、OpenRouter 和 MiniMax 使用各自原生映射;不暴露推理能力的模型会正常继续,并显示“不可用”提示,而不是失败。官方 OpenAI 端点会在发送请求前根据模型代际校验所选强度,因此 `o3 --no-reasoning` 或 `gpt-5.1 --reasoning=max` 等不支持的组合会在本地失败,并清楚列出支持的级别。DeepSeek 当前的 `deepseek-v4-flash` 和 `deepseek-v4-pro` 会收到 `thinking: { "type": "enabled" }` 与 `reasoning_effort`;`medium` / `xhigh` 会归一化为 DeepSeek 的 `high` 级别。
|
|
459
459
|
|
|
460
|
-
推理模式为 `on` 时(包括通过 `--reasoning=<level>` 启用),AICommit 会请求流式响应并实时显示推理;`auto` 模式下若 Provider 主动返回 think,也会显示,但不会强制开启推理。split
|
|
460
|
+
推理模式为 `on` 时(包括通过 `--reasoning=<level>` 启用),AICommit 会请求流式响应并实时显示推理;`auto` 模式下若 Provider 主动返回 think,也会显示,但不会强制开启推理。split 模式会按批次实时显示规划请求的 think,并标明当前批次;审阅界面只保留最终规划的推理。更早的深度分析分块仍只显示进度。实时面板需要交互式终端,JSON 输出始终不包含推理。默认实时视图跟随终端最新两行;生成或审阅期间按 `Ctrl+O` 可展开或收起累计文本。较长的展开输出会限制在终端视口内,可用 `PageUp` / `PageDown` 阅读所有页面。长按 `Ctrl+O` 只计为一次切换,避免按键重复留下多个面板。输出会经过清理,并受 `reasoning.maxDisplayChars` 限制;不暴露推理的 Provider 会显示简短的不可用提示。
|
|
461
461
|
|
|
462
462
|
```json
|
|
463
463
|
{
|
package/docs/distribution.md
CHANGED
|
@@ -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.
|
|
36
|
+
npm install --package-lock-only @hifullmoon/aicommit@2.6.1
|
|
37
37
|
npm audit signatures
|
|
38
38
|
```
|
|
39
39
|
|
package/package.json
CHANGED
package/src/change-analysis.js
CHANGED
|
@@ -736,8 +736,29 @@ export async function planAnalyzedChanges(config, facts, coverage = null, stream
|
|
|
736
736
|
coverage.metadataOnlyFiles = coverage.totalFiles - coverage.sampledFiles;
|
|
737
737
|
}
|
|
738
738
|
const next = [];
|
|
739
|
-
for (const batch of batches) {
|
|
739
|
+
for (const [batchIndex, batch] of batches.entries()) {
|
|
740
740
|
const ids = batch.map((x) => x.id);
|
|
741
|
+
const finalPlan = batches.length === 1;
|
|
742
|
+
stream?.onProgress?.(
|
|
743
|
+
finalPlan
|
|
744
|
+
? 'Planning final split merge ...'
|
|
745
|
+
: `Planning split batch ${batchIndex + 1}/${batches.length} ...`,
|
|
746
|
+
);
|
|
747
|
+
let startedThinking = false;
|
|
748
|
+
const batchStream = stream && {
|
|
749
|
+
onReasoningDelta(chunk) {
|
|
750
|
+
if (!startedThinking && chunk) {
|
|
751
|
+
startedThinking = true;
|
|
752
|
+
if (!finalPlan || level > 0) {
|
|
753
|
+
const stage = finalPlan ? 'final merge' : `batch ${batchIndex + 1}/${batches.length}`;
|
|
754
|
+
stream.onReasoningDelta?.(`\n\n[Planning ${stage}]\n`);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
stream.onReasoningDelta?.(chunk);
|
|
758
|
+
},
|
|
759
|
+
// Only the final merge belongs in the subsequent review prompt.
|
|
760
|
+
onReasoningComplete: finalPlan ? (text) => stream.onReasoningComplete?.(text) : undefined,
|
|
761
|
+
};
|
|
741
762
|
const groups = await jsonCall(
|
|
742
763
|
config,
|
|
743
764
|
`Each commit message must follow this policy: ${JSON.stringify(policy)}.\nGroup related changes into logical commits, including related implementation and tests across directories. Return [{"ids":[input IDs],"summary":"factual combined change summary","subject":"commit subject","body":"optional commit body"}]. Assign every input ID exactly once. Do not merge unrelated changes just to reduce group count.`,
|
|
@@ -750,9 +771,7 @@ export async function planAnalyzedChanges(config, facts, coverage = null, stream
|
|
|
750
771
|
'Analysis plan is missing a commit subject.',
|
|
751
772
|
);
|
|
752
773
|
},
|
|
753
|
-
|
|
754
|
-
// final plan, which is the reasoning relevant to the review screen.
|
|
755
|
-
batches.length === 1 ? stream : null,
|
|
774
|
+
batchStream,
|
|
756
775
|
);
|
|
757
776
|
for (const group of groups) {
|
|
758
777
|
next.push({
|
package/src/generation-ui.js
CHANGED
|
@@ -20,6 +20,9 @@ export async function runModelTask({
|
|
|
20
20
|
const stream =
|
|
21
21
|
reasoning && reasoning.mode !== 'off' && !machineOutput
|
|
22
22
|
? {
|
|
23
|
+
onProgress(status) {
|
|
24
|
+
if (spinner.isSpinning) spinner.text = chalk.dim(status);
|
|
25
|
+
},
|
|
23
26
|
onReasoningDelta(chunk) {
|
|
24
27
|
if (!liveReasoning) {
|
|
25
28
|
spinner.stop();
|
package/src/split.js
CHANGED
|
@@ -1797,12 +1797,14 @@ export async function splitFlow(
|
|
|
1797
1797
|
let planReasoning = null;
|
|
1798
1798
|
const planningStream = stream
|
|
1799
1799
|
? {
|
|
1800
|
+
onProgress(status) {
|
|
1801
|
+
stream.onProgress?.(status);
|
|
1802
|
+
},
|
|
1800
1803
|
onReasoningDelta(chunk) {
|
|
1801
|
-
planReasoning = (planReasoning || '') + chunk;
|
|
1802
1804
|
stream.onReasoningDelta(chunk);
|
|
1803
1805
|
},
|
|
1804
1806
|
onReasoningComplete(text) {
|
|
1805
|
-
|
|
1807
|
+
planReasoning = text || null;
|
|
1806
1808
|
},
|
|
1807
1809
|
}
|
|
1808
1810
|
: null;
|