@icode-js/icode 3.0.3 → 3.0.4
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/package.json
CHANGED
package/src/core/git-service.js
CHANGED
|
@@ -162,20 +162,52 @@ export class GitService {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
async statusPorcelain() {
|
|
165
|
+
// 返回标准 porcelain 状态,供上层统一判断“是否存在未提交改动”。
|
|
165
166
|
const result = await this.exec(['status', '--porcelain'])
|
|
166
167
|
return result.stdout
|
|
167
168
|
}
|
|
168
169
|
|
|
169
170
|
async hasChanges() {
|
|
171
|
+
// 只要 porcelain 有输出,就说明暂存区、工作区或未跟踪文件存在改动。
|
|
170
172
|
const output = await this.statusPorcelain()
|
|
171
173
|
return cleanOutput(output).length > 0
|
|
172
174
|
}
|
|
173
175
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
+
// 列出未被忽略的未跟踪文件,供 AI 工作流补全新文件 diff。
|
|
177
|
+
async listUntrackedFiles() {
|
|
178
|
+
const result = await this.exec(['ls-files', '--others', '--exclude-standard'])
|
|
179
|
+
return result.stdout
|
|
180
|
+
.split('\n')
|
|
181
|
+
.map((item) => item.trim())
|
|
182
|
+
.filter(Boolean)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// 通过 no-index diff 生成“/dev/null -> 新文件”的补丁,覆盖未跟踪文件内容。
|
|
186
|
+
async buildUntrackedFileDiff(filePath) {
|
|
187
|
+
const result = await this.exec(['diff', '--no-index', '--binary', '--', '/dev/null', filePath], {
|
|
188
|
+
allowFailure: true
|
|
189
|
+
})
|
|
176
190
|
return result.stdout
|
|
177
191
|
}
|
|
178
192
|
|
|
193
|
+
async diffWorkingTree() {
|
|
194
|
+
// git diff 默认不包含 untracked 文件,这里显式补齐,避免新仓库被误判成“无改动”。
|
|
195
|
+
const trackedResult = await this.exec(['diff'])
|
|
196
|
+
const untrackedFiles = await this.listUntrackedFiles()
|
|
197
|
+
const untrackedDiffs = []
|
|
198
|
+
|
|
199
|
+
for (const filePath of untrackedFiles) {
|
|
200
|
+
const diff = await this.buildUntrackedFileDiff(filePath)
|
|
201
|
+
if (cleanOutput(diff)) {
|
|
202
|
+
untrackedDiffs.push(diff.trimEnd())
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return [trackedResult.stdout.trimEnd(), ...untrackedDiffs]
|
|
207
|
+
.filter(Boolean)
|
|
208
|
+
.join('\n\n')
|
|
209
|
+
}
|
|
210
|
+
|
|
179
211
|
async diffStaged() {
|
|
180
212
|
const result = await this.exec(['diff', '--staged'])
|
|
181
213
|
return result.stdout
|
|
@@ -33,6 +33,15 @@ function buildCommitMessage(parsed) {
|
|
|
33
33
|
return `${header}\n\n${body}`
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
// 将多个 diff 片段稳定拼接,避免空块污染 prompt。
|
|
37
|
+
function joinDiffSections(sections) {
|
|
38
|
+
return sections
|
|
39
|
+
.map((item) => (item || '').trim())
|
|
40
|
+
.filter(Boolean)
|
|
41
|
+
.join('\n\n')
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 基于“全部未提交改动”生成 AI commit,确保未暂存新文件也能被识别并提交。
|
|
36
45
|
export async function runAiCommitWorkflow(options) {
|
|
37
46
|
const context = await resolveGitContext({
|
|
38
47
|
cwd: options.cwd,
|
|
@@ -44,13 +53,19 @@ export async function runAiCommitWorkflow(options) {
|
|
|
44
53
|
logger.info(`仓库根目录: ${context.topLevelPath}`)
|
|
45
54
|
}
|
|
46
55
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
const stagedDiff = await git.diffStaged()
|
|
57
|
+
const workingDiff = await git.diffWorkingTree()
|
|
58
|
+
const hasStagedDiff = Boolean(stagedDiff.trim())
|
|
59
|
+
const hasWorkingDiff = Boolean(workingDiff.trim())
|
|
60
|
+
const diff = joinDiffSections([
|
|
61
|
+
hasStagedDiff ? `--- STAGED DIFF ---\n${stagedDiff}` : '',
|
|
62
|
+
hasWorkingDiff ? `--- WORKING TREE DIFF ---\n${workingDiff}` : ''
|
|
63
|
+
])
|
|
64
|
+
const diffSource = hasStagedDiff && hasWorkingDiff
|
|
65
|
+
? 'staged+working-tree'
|
|
66
|
+
: hasStagedDiff
|
|
67
|
+
? 'staged'
|
|
68
|
+
: 'working-tree'
|
|
54
69
|
|
|
55
70
|
if (!diff.trim()) {
|
|
56
71
|
throw new IcodeError('没有可用于生成提交信息的代码改动。', {
|
|
@@ -105,8 +120,8 @@ export async function runAiCommitWorkflow(options) {
|
|
|
105
120
|
}
|
|
106
121
|
}
|
|
107
122
|
|
|
108
|
-
if (
|
|
109
|
-
//
|
|
123
|
+
if (hasWorkingDiff) {
|
|
124
|
+
// 统一暂存工作区改动,确保未暂存修改和新文件与 AI 看到的 diff 保持一致。
|
|
110
125
|
await git.stageAll()
|
|
111
126
|
}
|
|
112
127
|
|