@hifullmoon/aicommit 1.4.0 → 1.5.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 CHANGED
@@ -1,131 +1,116 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/).
3
+ This file lists notable user-facing changes. Internal refactors, test-only changes, release mechanics, and documentation-only edits are omitted.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [1.5.1] - 2026-08-27
8
+
9
+ ### Fixed
10
+
11
+ - Normalized Windows 8.3 path aliases before validating split plan destinations, so repository-local output is rejected before any provider request.
12
+
13
+ ## [1.5.0] - 2026-08-27
14
+
7
15
  ### Added
8
16
 
9
- - Bundled Kimi Code setup preset and a copy-ready environment-variable configuration example using the OpenAI-compatible endpoint.
17
+ - Added a built-in Kimi Code provider preset and an environment-variable configuration example.
10
18
 
11
19
  ### Changed
12
20
 
13
- - Publish the CLI as the public npm organization package `@hifullmoon/aicommit`, with guarded bootstrap and Trusted Publishing release paths.
14
- - Repository team policies now reject `-l`/`--lang` overrides, inherited policy languages are enforced during candidate validation, and split extension violations remain reviewable before commit.
15
- - Provider preset compatibility now accepts valid core prerelease/build versions and compares prereleases using SemVer precedence.
16
- - New committing split runs now detect unfinished checkpoints before provider access, report actionable resume/abort commands, and `aicommit split --abort` safely discards stale recovery metadata without changing commits, the index, or the worktree.
21
+ - `aicommit split` now starts the interactive split flow directly; `aicommit split run` remains available as an alias.
22
+ - Repository policies can enforce their configured language without CLI overrides.
23
+ - Provider preset compatibility now follows SemVer rules for prerelease and build versions.
24
+ - Split commands detect unfinished checkpoints early and provide safe resume or abort actions.
17
25
 
18
26
  ### Security
19
27
 
20
- - Provider endpoint userinfo, credential-like query parameters, and fragments are redacted from config inspection, diagnostics, debug output, extension inputs, and credential-helper failures.
21
- - Extension provider adapters reject a broader set of credential-like request/configuration fields and fail closed when nested input exceeds the inspection depth.
28
+ - Sensitive URL components are redacted from configuration, diagnostics, debug output, extension input, and credential-helper errors.
29
+ - Provider extensions reject credential-like configuration fields and excessively deep nested input.
22
30
 
23
- ## [1.4.0] - 2026-08-24
31
+ ## 1.4.0 - 2026-08-24
24
32
 
25
33
  ### Added
26
34
 
27
- - Credential-free `aicommit config show|validate|path` inspection and generated Bash, Zsh, and Fish completion.
28
- - Strict repository-owned team policy template plus deterministic local/CI `policy check` commands and bilingual migration examples.
29
- - Independently updateable, versioned provider preset manifests with core/adapter compatibility declarations, atomic install, repair, and rollback.
30
- - Credential-denied extension API v1 with isolated context-provider, message-validator, and provider-adapter interfaces, a strict manifest schema, and bilingual executable documentation.
31
- - Signed GitHub release assets with SHA-256 checksums, SPDX SBOM, GitHub OIDC/Sigstore attestations, npm Trusted Publishing provenance, and a generated Homebrew formula.
32
- - Automated npm/Homebrew installation smoke paths plus bilingual distribution, troubleshooting, privacy, and provider-compatibility guides.
35
+ - Added credential-free `config show`, `config validate`, and `config path` commands.
36
+ - Added generated shell completion for Bash, Zsh, and Fish.
37
+ - Added repository-owned team policies with deterministic local and CI checks.
38
+ - Added independently updateable provider presets with install, repair, and rollback support.
39
+ - Added an isolated extension API for context providers, message validators, and provider adapters.
33
40
 
34
41
  ### Changed
35
42
 
36
- - Interactive setup now consumes the active provider preset manifest instead of a hard-coded provider list.
37
- - Provider request orchestration accepts asynchronous built-in or extension adapters without changing the Git and interaction flows.
43
+ - Interactive setup now reads providers from the active preset manifest.
38
44
 
39
45
  ### Security
40
46
 
41
- - Third-party extension code runs in a permissioned child process with a sanitized environment and no credential value; project config cannot enable extensions, v1 rejects credential permission requests, and Node.js 18 never falls back to unsandboxed execution.
42
- - Team policy, config inspection, and preset management never resolve provider credentials; preset and extension manifests reject credential-bearing fields, unsafe paths, and incompatible contracts.
47
+ - Extension processes run with explicit permissions, a sanitized environment, and no provider credentials.
48
+ - Project configuration cannot enable extensions or weaken credential boundaries.
43
49
 
44
- ## [1.3.0] - 2026-08-24
50
+ ## 1.3.0 - 2026-08-24
45
51
 
46
52
  ### Added
47
53
 
48
- - Explicit `--split=staged|all` scope selection plus versioned `aicommit split plan/apply` JSON artifacts with base-HEAD, change-set, and content-fingerprint validation.
49
- - Code-free, owner-only split checkpoints and `aicommit split --resume`, including reconciliation of the post-commit/pre-checkpoint crash window.
50
- - Strict split preflight checks for empty or duplicate groups, path coverage, rename/copy sides, conflicts, changed submodules, active hooks, and unborn branches.
51
- - Opt-in `--split-hunks` support for tracked multi-hunk text modifications, with hunk IDs/ranges/hashes in plans and machine output.
52
- - A shared end-to-end split fault matrix for SIGINT, process crashes, concurrent edits, hook failures, renames, deletions, binary files, and submodules.
54
+ - Added explicit staged/all split scopes and reusable `split plan` / `split apply` artifacts.
55
+ - Added resumable split checkpoints for interrupted or failed multi-commit operations.
56
+ - Added optional same-file hunk splitting for tracked text files.
53
57
 
54
58
  ### Changed
55
59
 
56
- - Every split group is now created from an immutable captured object snapshot through a temporary index; later worktree edits cannot silently enter pending commits.
57
- - Hook and Git failures report checkpointed, in-flight, pending, and current worktree/index state without reordering or duplicating groups.
58
- - Split apply and resume run without loading provider configuration or credentials.
60
+ - Split commits are built from captured snapshots so later worktree edits cannot enter pending commits.
61
+ - Split apply and resume no longer require provider configuration or credentials.
59
62
 
60
63
  ### Security
61
64
 
62
- - Split plan and checkpoint readers reject unsafe paths, unknown fields, oversized artifacts, and symbolic links; artifacts never contain diffs, patch text, or file content.
63
- - Experimental hunk execution validates selected patches entirely in temporary indexes and requires the final tree to reproduce every captured target blob exactly; otherwise planning falls back to file-level groups before the first commit.
65
+ - Split plans, checkpoints, paths, and hunk operations are validated before Git state is changed.
64
66
 
65
- ## [1.2.0] - 2026-08-24
67
+ ## 1.2.0 - 2026-08-24
66
68
 
67
69
  ### Added
68
70
 
69
- - Versioned `commitPolicy` rules for types, scopes, subject length, body, breaking changes, and language.
70
- - Strictly bounded repository context from recent commit subjects, package boundaries, user-trusted convention files, and statically recognized commitlint rules.
71
- - `aicommit stats` for local first-pass acceptance, edit/rewrite/failure rates, latency, token trends, and the 20% quality-improvement baseline; stats can be disabled or permanently cleared.
72
- - Anonymous local eval coverage for single/mixed changes, renames, generated files, long diffs, Chinese/English output, and malformed weak-model candidates, enforced in CI at 99% or better.
71
+ - Added versioned commit policies for type, scope, subject, body, breaking changes, and language.
72
+ - Added bounded repository context from recent commits, package boundaries, trusted convention files, and recognized commitlint rules.
73
+ - Added local-only quality statistics with enable, disable, and clear controls.
73
74
 
74
75
  ### Changed
75
76
 
76
- - Replaced the default free-form prompt contract with an authoritative structured policy; user guidance is additive, and project-owned prompts now require the user-owned `allowProjectPrompt` opt-in.
77
- - Commit generation now shows a bounded context summary before the provider request and allows every repository-context category to be disabled independently.
78
- - Candidate responses are validated locally for policy compliance and diff/path alignment; hard policy failures receive at most one low-cost correction without re-sending the diff.
79
- - Automatic policy corrections now contribute to the anonymous local rewrite metric.
77
+ - Commit generation now uses an authoritative structured policy and locally validates candidate messages.
78
+ - Repository context categories and budgets can be configured without allowing project settings to expand user-owned limits.
80
79
 
81
80
  ### Security
82
81
 
83
- - Diff, file, path, history, and convention inputs now use explicit JSON envelopes marked as untrusted data, backed by a prompt-injection regression corpus.
84
- - Project config can only disable repository context or lower user-owned ceilings; it cannot add trusted convention files, re-enable sources, expand budgets, or alter endpoints and credentials.
85
- - Trusted convention reads reject paths outside the repository, symbolic links, and non-regular files; commitlint configuration is parsed as data and never executed.
82
+ - Repository and diff inputs are isolated as untrusted structured data.
83
+ - Trusted convention files cannot escape the repository or execute commitlint configuration code.
86
84
 
87
- ## [1.1.0] - 2026-08-24
85
+ ## 1.1.0 - 2026-08-24
88
86
 
89
87
  ### Added
90
88
 
91
- - Linux, macOS, and Windows CI across Node.js 18, 20, 22, and 24.
92
- - ESLint, Prettier, c8 reporting, and a 70% minimum line-coverage gate.
93
- - Setup and terminal UI smoke coverage plus installed-tarball dry-run tests.
94
- - Release, security, contribution, privacy, and recovery documentation.
95
- - Unified provider generation adapters and contract fixtures for OpenAI, OpenRouter, DeepSeek, MiniMax, Ollama, and custom endpoints.
96
- - Bounded retries for rate limits, recoverable server failures, and interrupted network responses, including `Retry-After` support.
97
- - Stable error categories and process exit codes for config, Git state, network, provider, response-format, sensitive-data, and concurrent-modification failures.
98
- - `--output=text|json` with a published JSON schema and decoration-free stdout for automation.
99
- - `aicommit doctor` diagnostics for runtime, configuration, endpoint security, provider capabilities, credentials, and connectivity.
100
- - Optional Git credential-helper integration for OS-backed credential storage.
101
- - Minimal local-only metrics with status, clear, enable, and disable commands.
89
+ - Added unified support for OpenAI, OpenRouter, DeepSeek, MiniMax, Ollama, and custom compatible endpoints.
90
+ - Added bounded retries for rate limits, recoverable server failures, and interrupted responses.
91
+ - Added stable error categories, process exit codes, and JSON output for automation.
92
+ - Added `aicommit doctor` diagnostics.
93
+ - Added optional Git credential-helper integration.
102
94
 
103
95
  ### Changed
104
96
 
105
- - Constrained interactive prompt dependencies to releases that support Node.js 18.
106
- - Normalized provider usage as input, output, and total tokens and exposed finish reasons through one internal response contract.
107
97
  - Environment credentials now take priority over credential helpers and legacy plaintext configuration.
108
- - Installed-package smoke tests now verify the machine interface and published schema.
98
+ - Provider usage is normalized as input, output, and total tokens.
109
99
 
110
- ### Fixed
100
+ ### Security
111
101
 
112
- - Split planning scans complete untracked regular files for common sensitive content while keeping model previews bounded.
113
- - Split planning no longer follows untracked symbolic links for previews or fingerprints.
114
- - Non-interactive split mode fails closed before auto-staging detected sensitive files.
115
- - Split-plan messages are sanitized before terminal display and commit execution.
102
+ - Sensitive untracked files are detected before non-interactive staging.
103
+ - Split previews avoid symbolic links and sanitize generated messages before display or commit.
116
104
 
117
- ## [1.0.0] - 2026-08-24
105
+ ## 1.0.0 - 2026-08-24
118
106
 
119
107
  ### Added
120
108
 
121
- - Conventional commit generation in Chinese or English through OpenAI-compatible providers.
122
- - Interactive staging, editing, regeneration, dry-run, reasoning display, and connection checks.
123
- - File-level split planning and execution with Git-state concurrency checks.
124
- - Provider presets and user/project configuration trust boundaries.
125
-
126
- [Unreleased]: https://github.com/hi-fullmoon/AICommit/compare/v1.4.0...HEAD
127
- [1.4.0]: https://github.com/hi-fullmoon/AICommit/compare/v1.3.0...v1.4.0
128
- [1.3.0]: https://github.com/hi-fullmoon/AICommit/compare/v1.2.0...v1.3.0
129
- [1.2.0]: https://github.com/hi-fullmoon/AICommit/compare/v1.1.0...v1.2.0
130
- [1.1.0]: https://github.com/hi-fullmoon/AICommit/compare/v1.0.0...v1.1.0
131
- [1.0.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v1.0.0
109
+ - Added Conventional Commit generation in Chinese or English through OpenAI-compatible providers.
110
+ - Added interactive staging, editing, regeneration, dry-run, reasoning display, and connection checks.
111
+ - Added file-level split planning and execution with Git-state concurrency checks.
112
+ - Added provider presets and user/project configuration boundaries.
113
+
114
+ [Unreleased]: https://github.com/hi-fullmoon/AICommit/compare/v1.5.1...HEAD
115
+ [1.5.1]: https://github.com/hi-fullmoon/AICommit/releases/tag/v1.5.1
116
+ [1.5.0]: https://github.com/hi-fullmoon/AICommit/releases/tag/v1.5.0
package/README.md CHANGED
@@ -4,6 +4,26 @@
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
+ ## Usage preview
8
+
9
+ These screenshots were captured from real interactive terminal sessions in this repository. Provider, model, paths, and timings reflect the environment at capture time.
10
+
11
+ ### Configure a provider interactively
12
+
13
+ ![AICommit setup prompting for an AI provider](https://raw.githubusercontent.com/hi-fullmoon/AICommit/main/docs/assets/readme/setup-provider.png)
14
+
15
+ ### Diagnose configuration and connectivity
16
+
17
+ ![AICommit doctor checking runtime, configuration, credentials, and provider connectivity](https://raw.githubusercontent.com/hi-fullmoon/AICommit/main/docs/assets/readme/doctor-diagnostics.png)
18
+
19
+ ### Generate a commit message
20
+
21
+ ![AICommit generating a commit message from staged changes](https://raw.githubusercontent.com/hi-fullmoon/AICommit/main/docs/assets/readme/generating-commit.png)
22
+
23
+ ### Review the generated commit message
24
+
25
+ ![AICommit presenting a generated conventional commit message for confirmation](https://raw.githubusercontent.com/hi-fullmoon/AICommit/main/docs/assets/readme/generate-commit.png)
26
+
7
27
  ## Install
8
28
 
9
29
  ```bash
@@ -259,15 +279,15 @@ aicommit stats # show local quality, latency, and token trends
259
279
  aicommit stats clear # permanently clear local metric history
260
280
  aicommit # generate & commit in current directory
261
281
  aicommit /path/to/repo # or a target directory
262
- aicommit split run # choose staged/all scope, then split logical commits
263
- aicommit split run --scope=staged # split only the reviewed index snapshot
264
- aicommit split run --scope=all # split the complete working-tree snapshot
265
- aicommit split run --scope=staged --split-hunks # experimental same-file hunk splitting
282
+ aicommit split # choose staged/all scope, then split logical commits
283
+ aicommit split --scope=staged # split only the reviewed index snapshot
284
+ aicommit split --scope=all # split the complete working-tree snapshot
285
+ aicommit split --scope=staged --split-hunks # experimental same-file hunk splitting
266
286
  aicommit --dry-run # generate and review without creating a commit
267
- aicommit split run --dry-run # review a split plan without creating commits
287
+ aicommit split --dry-run # review a split plan without creating commits
268
288
  aicommit --yes # non-interactively commit already staged changes
269
289
  aicommit --yes --dry-run # non-interactively preview all changes; restores staging
270
- aicommit split run --scope=all --yes # non-interactively plan and commit all working-tree changes
290
+ aicommit split --scope=all --yes # non-interactively plan and commit all working-tree changes
271
291
  aicommit split plan --scope=staged --file=/tmp/split-plan.json --yes
272
292
  aicommit split apply --file=/tmp/split-plan.json --yes
273
293
  aicommit split resume --yes # resume an interrupted split transaction
@@ -285,7 +305,7 @@ aicommit -h # help
285
305
  | `-l`, `--lang` | Commit message language (`zh` or `en`) |
286
306
  | `-p`, `--provider` | Use the named provider from `providers` |
287
307
  | `--split-hunks` | Opt in to experimental same-file text-hunk planning; disabled by default |
288
- | `--scope` | `staged` or `all` scope for `aicommit split run` and `aicommit split plan` |
308
+ | `--scope` | `staged` or `all` scope for `aicommit split` and `aicommit split plan` |
289
309
  | `--file` | JSON plan path for `aicommit split plan` and `aicommit split apply` |
290
310
  | `--dry-run` | Generate and review a message or split plan without creating commits |
291
311
  | `-y`, `--yes` | Accept without prompts; normal mode requires explicitly staged changes |
@@ -389,7 +409,7 @@ When reasoning mode is `on` (including via `--reasoning=<level>`), aicommit requ
389
409
 
390
410
  ### Split mode
391
411
 
392
- `aicommit split run` asks whether to group the staged index snapshot or all staged, unstaged, and untracked changes into logical commits. Use `--scope=staged` or `--scope=all` when the boundary must be explicit, including every non-interactive run. You can review the plan, regenerate messages for selected groups, or edit the plan as JSON before committing. Extension validation errors are shown with the plan and must be corrected by editing or regenerating before commit. Sensitive-content detection fails closed before a non-interactive provider request or automatic staging.
412
+ `aicommit split` (also available as the explicit `aicommit split run`) asks whether to group the staged index snapshot or all staged, unstaged, and untracked changes into logical commits. Use `--scope=staged` or `--scope=all` when the boundary must be explicit, including every non-interactive run. You can review the plan, regenerate messages for selected groups, or edit the plan as JSON before committing. Extension validation errors are shown with the plan and must be corrected by editing or regenerating before commit. Sensitive-content detection fails closed before a non-interactive provider request or automatic staging.
393
413
 
394
414
  For an auditable two-step flow, `aicommit split plan --scope=staged|all --file=<path>` exports a versioned JSON artifact, and `aicommit split apply --file=<path>` rechecks its base commit, change set, and content fingerprint before touching the index. Keep plan files outside the worktree or under `.git` so they cannot become part of their own plan.
395
415
 
@@ -399,7 +419,7 @@ Split remains file-level by default. `--split-hunks` opts in to experimental sam
399
419
 
400
420
  ## Development and releases
401
421
 
402
- See [CONTRIBUTING.md](CONTRIBUTING.md) for local development and pull-request checks, [SECURITY.md](SECURITY.md) for private vulnerability reporting, [RELEASING.md](RELEASING.md) for the executable maintainer process, and the bilingual [distribution guide](docs/distribution.md) for npm/Homebrew install, verification, and user rollback. Releases require a GitHub-verified signed tag, Sigstore/GitHub attestations for the exact npm tarball and SPDX SBOM, npm Trusted Publishing provenance, SHA-256-pinned Homebrew formula, and post-publish smoke tests. `npm run eval` runs the anonymous local quality corpus covering single and mixed changes, renames, generated files, long diffs, Chinese/English output, and malformed weak-model candidates; it is also part of `npm run ci`.
422
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for local development and pull-request checks, [SECURITY.md](SECURITY.md) for private vulnerability reporting, [RELEASING.md](RELEASING.md) for the maintainer process, and the bilingual [distribution guide](docs/distribution.md) for npm/Homebrew installation and rollback. Releases use npm Trusted Publishing with provenance, verify the exact package tarball, and run a post-publish Homebrew smoke test. `npm run eval` runs the anonymous local quality corpus covering single and mixed changes, renames, generated files, long diffs, Chinese/English output, and malformed weak-model candidates; it is also part of `npm run ci`.
403
423
 
404
424
  ## License
405
425
 
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
+ ![AICommit setup 提示选择 AI Provider](https://raw.githubusercontent.com/hi-fullmoon/AICommit/main/docs/assets/readme/setup-provider.png)
14
+
15
+ ### 检查配置与连接
16
+
17
+ ![AICommit doctor 检查运行环境、配置、凭据和 Provider 连接](https://raw.githubusercontent.com/hi-fullmoon/AICommit/main/docs/assets/readme/doctor-diagnostics.png)
18
+
19
+ ### 生成提交信息
20
+
21
+ ![AICommit 根据已暂存的变更生成提交信息](https://raw.githubusercontent.com/hi-fullmoon/AICommit/main/docs/assets/readme/generating-commit.png)
22
+
23
+ ### 检查生成的提交信息
24
+
25
+ ![AICommit 展示生成的 Conventional Commit 并等待确认](https://raw.githubusercontent.com/hi-fullmoon/AICommit/main/docs/assets/readme/generate-commit.png)
26
+
7
27
  ## 安装
8
28
 
9
29
  使用 npm:
@@ -261,15 +281,15 @@ aicommit stats # 显示本地质量、延迟和 token 趋势
261
281
  aicommit stats clear # 永久清除本地指标历史
262
282
  aicommit # 在当前目录生成提交信息并提交
263
283
  aicommit /path/to/repo # 或指定目标目录
264
- aicommit split run # 选择 staged / all 范围并拆分逻辑提交
265
- aicommit split run --scope=staged # 只拆分已审阅的 index 快照
266
- aicommit split run --scope=all # 拆分完整工作区快照
267
- aicommit split run --scope=staged --split-hunks # 实验性同文件 hunk 拆分
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 run --dry-run # 审阅拆分计划,但不创建提交
289
+ aicommit split --dry-run # 审阅拆分计划,但不创建提交
270
290
  aicommit --yes # 非交互提交已明确暂存的变更
271
291
  aicommit --yes --dry-run # 非交互预览所有变更;退出时恢复暂存状态
272
- aicommit split run --scope=all --yes # 非交互规划并提交所有工作区变更
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 # 恢复中断的拆分事务
@@ -282,20 +302,20 @@ aicommit --yes --output=json # 向 stdout 输出一个通过 schema 校验的 JS
282
302
  aicommit -h # 帮助
283
303
  ```
284
304
 
285
- | 选项 | 说明 |
286
- | ------------------ | ----------------------------------------------------------------------- |
287
- | `-l`, `--lang` | 提交信息语言:`zh` 或 `en` |
288
- | `-p`, `--provider` | 使用 `providers` 中的命名 Provider |
289
- | `--split-hunks` | 启用实验性同文件文本 hunk 规划;默认关闭 |
290
- | `--scope` | `aicommit split run` 和 `aicommit split plan` 的范围:`staged` 或 `all` |
291
- | `--file` | `aicommit split plan` 和 `aicommit split apply` 的 JSON 计划路径 |
292
- | `--dry-run` | 生成并审阅消息或拆分计划,但不创建提交 |
293
- | `-y`, `--yes` | 不提示直接接受;普通模式要求变更已明确暂存 |
294
- | `--reasoning` | 启用推理,可选强度:`low`、`medium`、`high`、`xhigh` 或 `max` |
295
- | `--no-reasoning` | 所选 Provider / 模型支持时显式关闭推理 |
296
- | `--output` | `text`(默认)或单个 JSON 对象;提交 / 拆分的 JSON 流程要求 `--yes` |
297
- | `-v`, `--version` | 显示版本 |
298
- | `-h`, `--help` | 显示帮助 |
305
+ | 选项 | 说明 |
306
+ | ------------------ | ------------------------------------------------------------------- |
307
+ | `-l`, `--lang` | 提交信息语言:`zh` 或 `en` |
308
+ | `-p`, `--provider` | 使用 `providers` 中的命名 Provider |
309
+ | `--split-hunks` | 启用实验性同文件文本 hunk 规划;默认关闭 |
310
+ | `--scope` | `aicommit split` 和 `aicommit split plan` 的范围:`staged` 或 `all` |
311
+ | `--file` | `aicommit split plan` 和 `aicommit split apply` 的 JSON 计划路径 |
312
+ | `--dry-run` | 生成并审阅消息或拆分计划,但不创建提交 |
313
+ | `-y`, `--yes` | 不提示直接接受;普通模式要求变更已明确暂存 |
314
+ | `--reasoning` | 启用推理,可选强度:`low`、`medium`、`high`、`xhigh` 或 `max` |
315
+ | `--no-reasoning` | 所选 Provider / 模型支持时显式关闭推理 |
316
+ | `--output` | `text`(默认)或单个 JSON 对象;提交 / 拆分的 JSON 流程要求 `--yes` |
317
+ | `-v`, `--version` | 显示版本 |
318
+ | `-h`, `--help` | 显示帮助 |
299
319
 
300
320
  ### 配置检查
301
321
 
@@ -391,7 +411,7 @@ aicommit completion fish > ~/.config/fish/completions/aicommit.fish
391
411
 
392
412
  ### 拆分提交模式
393
413
 
394
- `aicommit split run` 会询问是对暂存 index 快照分组,还是对全部已暂存、未暂存和未跟踪变更分组。边界必须明确时请使用 `--scope=staged` 或 `--scope=all`,所有非交互运行都应显式指定范围。提交前可以审阅计划、为选中的组重新生成消息,或直接编辑 JSON 计划。扩展校验错误会随计划显示,必须通过编辑或重新生成修复后才能提交。敏感内容检测会在非交互 Provider 请求或自动暂存前 fail closed。
414
+ `aicommit split`(也可以显式写成 `aicommit split run`)会询问是对暂存 index 快照分组,还是对全部已暂存、未暂存和未跟踪变更分组。边界必须明确时请使用 `--scope=staged` 或 `--scope=all`,所有非交互运行都应显式指定范围。提交前可以审阅计划、为选中的组重新生成消息,或直接编辑 JSON 计划。扩展校验错误会随计划显示,必须通过编辑或重新生成修复后才能提交。敏感内容检测会在非交互 Provider 请求或自动暂存前 fail closed。
395
415
 
396
416
  如需可审计的两步流程,使用 `aicommit split plan --scope=staged|all --file=<path>` 导出版本化 JSON 工件,再用 `aicommit split apply --file=<path>` 在接触 index 前重新校验 base commit、变更集和内容指纹。计划文件应保存在工作区之外或 `.git` 下,避免被纳入自身计划。
397
417
 
@@ -401,7 +421,7 @@ split 默认仍按文件拆分。`--split-hunks` 可选择性启用实验性的
401
421
 
402
422
  ## 开发与发布
403
423
 
404
- 本地开发和 Pull Request 检查请参阅 [CONTRIBUTING.md](CONTRIBUTING.md),私密漏洞报告请参阅 [SECURITY.md](SECURITY.md),可执行的维护者发布流程请参阅 [RELEASING.md](RELEASING.md),npm / Homebrew 安装、验证和用户回滚请参阅双语[分发指南](docs/distribution.md)。发布要求包含 GitHub 验证的签名 tag、精确 npm tarball 和 SPDX SBOM 的 Sigstore / GitHub attestations、npm Trusted Publishing provenance、SHA-256 固定的 Homebrew formula,以及发布后的冒烟测试。`npm run eval` 会运行匿名本地质量语料,覆盖单一与混合变更、rename、生成文件、长 diff、中英文输出和格式错误的弱模型候选;该命令也是 `npm run ci` 的一部分。
424
+ 本地开发和 Pull Request 检查请参阅 [CONTRIBUTING.md](CONTRIBUTING.md),私密漏洞报告请参阅 [SECURITY.md](SECURITY.md),维护者发布流程请参阅 [RELEASING.md](RELEASING.md),npm / Homebrew 安装和用户回滚请参阅双语[分发指南](docs/distribution.md)。发布通过 npm Trusted Publishing 生成 provenance,校验精确的 package tarball,并在发布后执行 Homebrew 冒烟测试。`npm run eval` 会运行匿名本地质量语料,覆盖单一与混合变更、rename、生成文件、长 diff、中英文输出和格式错误的弱模型候选;该命令也是 `npm run ci` 的一部分。
405
425
 
406
426
  ## 许可证
407
427
 
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
- - distributed tarballs must be bound to a GitHub-verified signed tag, GitHub/Sigstore build attestation, npm provenance, and the Homebrew formula SHA-256.
27
+ - npm releases must use Trusted Publishing provenance, and the Homebrew formula must pin the published npm tarball by SHA-256.
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
 
@@ -1,43 +1,41 @@
1
- # Distribution and verification / 分发与校验
1
+ # Distribution / 分发
2
2
 
3
- AICommit publishes the same version through npm, an in-repository Homebrew tap, and a signed GitHub Release asset set. Runtime behavior is identical; Homebrew installs the npm tarball whose SHA-256 is pinned in the formula.
3
+ AICommit 通过 npm 与 Homebrew 发布。Homebrew formula 安装同一个 npm tarball,并用 SHA-256 固定其内容。
4
4
 
5
- AICommit 通过 npm、仓库内 Homebrew tap 和带签名证明的 GitHub Release 资产发布同一版本。运行行为一致;Homebrew 安装的是 formula 中固定 SHA-256 的 npm tarball。
5
+ AICommit is distributed through npm and Homebrew. The Homebrew formula installs the same npm tarball and pins it by SHA-256.
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
- The release workflow uses npm Trusted Publishing on a GitHub-hosted runner with OIDC and `--provenance`; it has no long-lived npm token. To verify registry signatures and provenance with a current npm CLI:
22
+ 发布工作流使用 npm Trusted Publishing,不保存长期 `NPM_TOKEN`。来自公开 GitHub 仓库的 OIDC 发布会自动携带 npm provenance。可使用当前 npm CLI 检查 registry signature 与 provenance:
21
23
 
22
- 发布工作流在 GitHub 托管 runner 上通过 OIDC 使用 npm Trusted Publishing,并显式启用 `--provenance`;流程不需要长期 npm token。使用较新的 npm CLI 校验 registry 签名与 provenance:
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@1.4.0
29
+ npm install --package-lock-only @hifullmoon/aicommit@1.5.1
28
30
  npm audit signatures
29
31
  ```
30
32
 
31
33
  ## Homebrew
32
34
 
33
- The main repository is a tap, so no separate tap repository or install script is trusted:
34
-
35
- 主仓库本身就是 tap,无需信任额外 tap 仓库或安装脚本:
36
-
37
35
  ```bash
36
+ # install / 安装
38
37
  brew tap hi-fullmoon/aicommit https://github.com/hi-fullmoon/AICommit.git
39
38
  brew install hi-fullmoon/aicommit/aicommit
40
- aicommit --version
41
39
 
42
40
  # upgrade / 升级
43
41
  brew update
@@ -48,57 +46,31 @@ brew uninstall aicommit
48
46
  brew untap hi-fullmoon/aicommit
49
47
  ```
50
48
 
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。
49
+ Formula 依赖 Homebrew 的 Node package,使用 Homebrew 标准 npm 安装参数,并测试 `--version`、`--help` 与无凭据配置校验。每次 npm 发布完成后,release workflow 会从公开 registry 再执行一次真实安装测试。
54
50
 
55
- ## Signed GitHub assets / GitHub 签名资产
51
+ The formula depends on Homebrew's Node package, uses Homebrew's standard npm installation arguments, and tests `--version`, `--help`, and credential-free configuration validation. After every npm publish, the release workflow performs a real install from the public registry.
56
52
 
57
- Each release requires a GitHub-verified signed annotated tag. The release workflow builds and uploads:
53
+ ## Integrity / 完整性
58
54
 
59
- 每个 release 都要求 GitHub 已验证签名的 annotated tag。发布工作流生成并上传:
55
+ `Formula/aicommit.rb` 中的 `sha256` 必须与对应 npm tarball 一致。维护者发布前通过 `scripts/release-assets.mjs` 生成 formula,工作流发布前会再次比较生成结果与已提交文件。
60
56
 
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.
57
+ The `sha256` in `Formula/aicommit.rb` must match the corresponding npm tarball. Maintainers generate the formula with `scripts/release-assets.mjs`, and the release workflow compares it again before publishing.
66
58
 
67
- Verify checksums and the cryptographically signed provenance against the exact release workflow:
59
+ ## Rollback / 回滚
68
60
 
69
- 校验 checksum,并把加密签名的 provenance 限定到本仓库的 release workflow:
61
+ npm 用户可以立即固定上一可用版本:
70
62
 
71
63
  ```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
64
+ npm install --global @hifullmoon/aicommit@<last-good-version>
80
65
  ```
81
66
 
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.
89
-
90
- 维护者按 [`RELEASING.md`](../RELEASING.md) 执行完整清单。公开 tag 与 attestation 不可变:不得移动已发布 tag,也不得覆盖已发布版本。
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`,卸载当前版本后从本地文件安装:
67
+ Homebrew 用户可从旧 tag 取出 formula 并本地安装:
95
68
 
96
69
  ```bash
97
- gh release download v1.4.0 -R hi-fullmoon/AICommit -p aicommit.rb -D /tmp/aicommit-rollback
70
+ git clone https://github.com/hi-fullmoon/AICommit.git /tmp/aicommit-rollback
71
+ git -C /tmp/aicommit-rollback show v1.4.0:Formula/aicommit.rb > /tmp/aicommit.rb
98
72
  brew uninstall aicommit
99
- brew install --formula /tmp/aicommit-rollback/aicommit.rb
73
+ brew install --formula /tmp/aicommit.rb
100
74
  ```
101
75
 
102
- Provider preset rollback is independent of the core package: use `aicommit preset rollback`, then `aicommit preset show` and `aicommit doctor`. See [`provider-presets.md`](provider-presets.md).
103
-
104
- Provider preset 回滚不依赖核心包版本:执行 `aicommit preset rollback`,再运行 `aicommit preset show` 和 `aicommit doctor`。详见 [`provider-presets.md`](provider-presets.md)。
76
+ 已发布的 npm version 不应覆盖或复用。维护者应 deprecate 有问题的版本、恢复正确的 dist-tag,并发布修复 patch。完整流程见 [`RELEASING.md`](../RELEASING.md)。
@@ -29,7 +29,7 @@ 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 |
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 `Formula/aicommit.rb` with the npm tarball; do not use `--force` to bypass integrity |
33
33
  | 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
34
 
35
35
  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": "1.4.0",
3
+ "version": "1.5.1",
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/",
@@ -29,9 +30,9 @@
29
30
  "eval": "node eval/run.mjs",
30
31
  "test:package": "node scripts/package-smoke.mjs",
31
32
  "test:homebrew": "node scripts/homebrew-smoke.mjs",
33
+ "docs:terminal-demo": "node scripts/readme-terminal-demo.mjs",
32
34
  "release:assets": "node scripts/release-assets.mjs",
33
- "release:npm:check": "node scripts/publish-npm-org.mjs",
34
- "release:npm:publish": "node scripts/publish-npm-org.mjs --publish",
35
+ "release:npm:check": "node scripts/verify-release.mjs && npm run ci && npm run test:package && npm pack --dry-run",
35
36
  "ci": "npm run lint && npm run format:check && npm run eval && npm run coverage"
36
37
  },
37
38
  "c8": {
package/src/cli.js CHANGED
@@ -18,7 +18,7 @@ function showHelp() {
18
18
  ${chalk.dim('$')} aicommit policy <template|check> [options]
19
19
  ${chalk.dim('$')} aicommit preset <show|validate|path|install|rollback> [options]
20
20
  ${chalk.dim('$')} aicommit completion <bash|zsh|fish>
21
- ${chalk.dim('$')} aicommit split <run|plan|apply|resume|abort> [options]
21
+ ${chalk.dim('$')} aicommit split [run|plan|apply|resume|abort] [options]
22
22
 
23
23
  ${chalk.bold('Commands:')}
24
24
  setup Interactive configuration wizard
@@ -30,7 +30,7 @@ function showHelp() {
30
30
  policy check Validate a message file or Git range with the effective team policy
31
31
  preset Inspect, validate, install, or roll back provider preset manifests
32
32
  completion Generate Bash, Zsh, or Fish completion on stdout
33
- split run Plan and create logical commits
33
+ split, split run Plan and create logical commits
34
34
  split plan Generate and export a fingerprinted JSON plan
35
35
  split apply Validate and apply an exported JSON plan
36
36
  split resume Resume the repository's unfinished transaction
@@ -46,7 +46,7 @@ function showHelp() {
46
46
  -l, --lang=<zh|en> Commit message language (default: zh)
47
47
  -p, --provider=<name> Use the named provider from config "providers"
48
48
  --split-hunks Experimental same-file hunk planning (default: off)
49
- --scope=<scope> Scope for "split run|plan": staged, all
49
+ --scope=<scope> Scope for "split|split plan": staged, all
50
50
  --file=<path> Split-plan artifact or commit-message file
51
51
  --range=<revision> Git revision/range for "policy check" (default: HEAD)
52
52
  --reasoning=<level> Set reasoning effort (enabled by default: medium)
@@ -73,10 +73,10 @@ function showHelp() {
73
73
  aicommit Commit changes in current directory (Chinese)
74
74
  aicommit --lang=en Generate English commit message
75
75
  aicommit -p deepseek Switch to the "deepseek" provider from config
76
- aicommit split run Choose staged/all scope, then plan logical commits
77
- aicommit split run --scope=staged Split only the reviewed index snapshot
78
- aicommit split run --scope=all --yes Split the complete working tree non-interactively
79
- aicommit split run --scope=staged --split-hunks Split eligible text hunks
76
+ aicommit split Choose staged/all scope, then plan logical commits
77
+ aicommit split --scope=staged Split only the reviewed index snapshot
78
+ aicommit split --scope=all --yes Split the complete working tree non-interactively
79
+ aicommit split --scope=staged --split-hunks Split eligible text hunks
80
80
  aicommit split plan --scope=staged --file=.aicommit-plan.json --yes
81
81
  aicommit split apply --file=.aicommit-plan.json --yes
82
82
  aicommit split resume --yes Resume pending groups from the checkpoint
@@ -203,14 +203,23 @@ export function parseArgs(args = process.argv.slice(2)) {
203
203
 
204
204
  let splitCommand = null;
205
205
  if (args[0] === 'split') {
206
- splitCommand = args[1];
207
- if (!['run', 'plan', 'apply', 'resume', 'abort'].includes(splitCommand)) {
206
+ const requestedAction = args[1];
207
+ const actions = ['run', 'plan', 'apply', 'resume', 'abort'];
208
+ if (!requestedAction || requestedAction.startsWith('-')) {
209
+ // Keep the common path short: `aicommit split` is the interactive
210
+ // split flow, while explicit actions remain available for automation
211
+ // and recovery.
212
+ splitCommand = 'run';
213
+ args = args.slice(1);
214
+ } else if (actions.includes(requestedAction)) {
215
+ splitCommand = requestedAction;
216
+ args = args.slice(2);
217
+ } else {
208
218
  throw fail(
209
219
  ERROR_CATEGORIES.CONFIG,
210
220
  'split requires one action: run, plan, apply, resume, or abort.',
211
221
  );
212
222
  }
213
- args = args.slice(2);
214
223
  }
215
224
 
216
225
  const doctor = args[0] === 'doctor';
package/src/split.js CHANGED
@@ -101,12 +101,19 @@ function pathIsWithin(parent, candidate) {
101
101
  return rel === '' || (rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel));
102
102
  }
103
103
 
104
+ function canonicalExistingPath(path) {
105
+ // On Windows the native implementation expands 8.3 aliases such as
106
+ // RUNNER~1 consistently. The JS fallback can preserve whichever spelling
107
+ // it received, causing two paths to the same directory to compare unequal.
108
+ return realpathSync.native(path);
109
+ }
110
+
104
111
  function canonicalDestination(path) {
105
112
  let cursor = resolve(path);
106
113
  const suffix = [];
107
114
  while (true) {
108
115
  try {
109
- return join(realpathSync(cursor), ...suffix);
116
+ return join(canonicalExistingPath(cursor), ...suffix);
110
117
  } catch {
111
118
  const parent = dirname(cursor);
112
119
  if (parent === cursor) return resolve(path);
@@ -120,7 +127,7 @@ function safeExportPlanPath(projectRoot, path) {
120
127
  const absolute = resolve(path);
121
128
  const rawGitDir = readGit(['rev-parse', '--git-dir'], projectRoot).trim();
122
129
  const gitDir = isAbsolute(rawGitDir) ? rawGitDir : resolve(projectRoot, rawGitDir);
123
- const canonicalRoot = realpathSync(projectRoot);
130
+ const canonicalRoot = canonicalExistingPath(projectRoot);
124
131
  const canonicalGitDir = canonicalDestination(gitDir);
125
132
  const canonicalPlan = canonicalDestination(absolute);
126
133
  if (pathIsWithin(canonicalRoot, canonicalPlan) && !pathIsWithin(canonicalGitDir, canonicalPlan)) {