@webywz/vibe-commit 0.1.6 → 0.1.8
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/dist/heuristic.d.ts +5 -1
- package/dist/heuristic.js +42 -15
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/propose.js +4 -1
- package/package.json +1 -1
package/dist/heuristic.d.ts
CHANGED
|
@@ -21,9 +21,13 @@ export declare function detectBreakingKind(diff: StagedDiff, forced?: boolean):
|
|
|
21
21
|
export declare function formatBreakingReason(kind: BreakingKind): string;
|
|
22
22
|
/** Detail text for the BREAKING CHANGE footer, or undefined when not inferred. */
|
|
23
23
|
export declare function breakingFooterDetail(diff: StagedDiff): string | undefined;
|
|
24
|
+
/** Generic bilingual footer when no better reason (or empty subject) exists. */
|
|
25
|
+
export declare const DEFAULT_BREAKING_FOOTER_DETAIL = "incompatible API change \u00B7 \u4E0D\u517C\u5BB9\u7684 API \u53D8\u66F4";
|
|
24
26
|
/**
|
|
25
27
|
* Ensure body carries a conventional BREAKING CHANGE footer when breaking.
|
|
26
|
-
* Skips if the body already mentions one.
|
|
28
|
+
* Skips if the body already mentions one.
|
|
29
|
+
* Prefers subject when reason is empty or the generic bilingual default.
|
|
30
|
+
* Heuristic major/export/footer-specific bilingual details are kept as-is.
|
|
27
31
|
*/
|
|
28
32
|
export declare function ensureBreakingFooter(message: ProposedMessage, reason?: string): ProposedMessage;
|
|
29
33
|
export declare function collectAddedIdentifiers(hunks: DiffHunk[]): string[];
|
package/dist/heuristic.js
CHANGED
|
@@ -37,7 +37,9 @@ export function proposeHeuristic(input) {
|
|
|
37
37
|
engine: "heuristic",
|
|
38
38
|
breakingReason: kind ? formatBreakingReason(kind) : undefined,
|
|
39
39
|
};
|
|
40
|
-
|
|
40
|
+
// Forced --breaking: prefer subject in the footer (not bilingual default).
|
|
41
|
+
const footerReason = kind === "forced" ? message.subject : breakingFooterDetail(diff);
|
|
42
|
+
return ensureBreakingFooter(message, footerReason);
|
|
41
43
|
}
|
|
42
44
|
export function inferType(diff) {
|
|
43
45
|
const files = diff.files;
|
|
@@ -260,17 +262,22 @@ export function breakingFooterDetail(diff) {
|
|
|
260
262
|
if (removed.length > 0) {
|
|
261
263
|
const names = removed.slice(0, 3).join(", ");
|
|
262
264
|
return removed.length === 1
|
|
263
|
-
? `remove public export ${names}`
|
|
264
|
-
: `remove public exports ${names}`;
|
|
265
|
+
? `remove public export ${names} · 删除公开 export ${names}`
|
|
266
|
+
: `remove public exports ${names} · 删除公开 exports ${names}`;
|
|
265
267
|
}
|
|
266
268
|
const bump = detectMajorVersionBump(diff);
|
|
267
|
-
if (bump)
|
|
268
|
-
return `bump major version to ${bump.to}`;
|
|
269
|
+
if (bump) {
|
|
270
|
+
return `bump major version to ${bump.to} · 主版本升至 ${bump.to}`;
|
|
271
|
+
}
|
|
269
272
|
return undefined;
|
|
270
273
|
}
|
|
274
|
+
/** Generic bilingual footer when no better reason (or empty subject) exists. */
|
|
275
|
+
export const DEFAULT_BREAKING_FOOTER_DETAIL = "incompatible API change · 不兼容的 API 变更";
|
|
271
276
|
/**
|
|
272
277
|
* Ensure body carries a conventional BREAKING CHANGE footer when breaking.
|
|
273
|
-
* Skips if the body already mentions one.
|
|
278
|
+
* Skips if the body already mentions one.
|
|
279
|
+
* Prefers subject when reason is empty or the generic bilingual default.
|
|
280
|
+
* Heuristic major/export/footer-specific bilingual details are kept as-is.
|
|
274
281
|
*/
|
|
275
282
|
export function ensureBreakingFooter(message, reason) {
|
|
276
283
|
if (!message.breaking)
|
|
@@ -279,8 +286,13 @@ export function ensureBreakingFooter(message, reason) {
|
|
|
279
286
|
if (/BREAKING CHANGE:/i.test(body)) {
|
|
280
287
|
return body === (message.body ?? "") ? message : { ...message, body };
|
|
281
288
|
}
|
|
282
|
-
const
|
|
283
|
-
|
|
289
|
+
const subject = message.subject.replace(/\s+/g, " ").trim();
|
|
290
|
+
const normalized = (reason ?? "").replace(/\s+/g, " ").trim();
|
|
291
|
+
const useSubject = Boolean(subject) &&
|
|
292
|
+
(!normalized || normalized === DEFAULT_BREAKING_FOOTER_DETAIL);
|
|
293
|
+
const detail = (useSubject ? subject : normalized) ||
|
|
294
|
+
subject ||
|
|
295
|
+
DEFAULT_BREAKING_FOOTER_DETAIL;
|
|
284
296
|
const footer = `BREAKING CHANGE: ${detail}`;
|
|
285
297
|
return {
|
|
286
298
|
...message,
|
|
@@ -297,7 +309,7 @@ function detectBreakingFooter(diff) {
|
|
|
297
309
|
}
|
|
298
310
|
// Presence of the token alone still counts as breaking.
|
|
299
311
|
if (diff.hunks.some((hunk) => hunk.lines.some((line) => /^\+\s*BREAKING CHANGE:/i.test(line)))) {
|
|
300
|
-
return
|
|
312
|
+
return DEFAULT_BREAKING_FOOTER_DETAIL;
|
|
301
313
|
}
|
|
302
314
|
return undefined;
|
|
303
315
|
}
|
|
@@ -340,6 +352,20 @@ function exportNameFromDeletedLine(line) {
|
|
|
340
352
|
return def[1];
|
|
341
353
|
return undefined;
|
|
342
354
|
}
|
|
355
|
+
/** Collect every `"version": "..."` value on a +/- diff line (incl. minified JSON). */
|
|
356
|
+
function versionsOnDiffLine(line) {
|
|
357
|
+
if (!(line.startsWith("-") || line.startsWith("+")))
|
|
358
|
+
return [];
|
|
359
|
+
if (line.startsWith("---") || line.startsWith("+++"))
|
|
360
|
+
return [];
|
|
361
|
+
const versions = [];
|
|
362
|
+
const re = /"version"\s*:\s*"([^"]+)"/g;
|
|
363
|
+
for (const match of line.slice(1).matchAll(re)) {
|
|
364
|
+
if (match[1])
|
|
365
|
+
versions.push(match[1]);
|
|
366
|
+
}
|
|
367
|
+
return versions;
|
|
368
|
+
}
|
|
343
369
|
function detectMajorVersionBump(diff) {
|
|
344
370
|
for (const hunk of diff.hunks) {
|
|
345
371
|
if (!/(^|\/)package\.json$/i.test(hunk.path))
|
|
@@ -347,12 +373,13 @@ function detectMajorVersionBump(diff) {
|
|
|
347
373
|
const removed = [];
|
|
348
374
|
const added = [];
|
|
349
375
|
for (const line of hunk.lines) {
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
376
|
+
const versions = versionsOnDiffLine(line);
|
|
377
|
+
if (versions.length === 0)
|
|
378
|
+
continue;
|
|
379
|
+
if (line.startsWith("-"))
|
|
380
|
+
removed.push(...versions);
|
|
381
|
+
else if (line.startsWith("+"))
|
|
382
|
+
added.push(...versions);
|
|
356
383
|
}
|
|
357
384
|
for (const from of removed) {
|
|
358
385
|
for (const to of added) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { proposeWithAi } from "./ai.ts";
|
|
2
2
|
export { formatCommit, parseCommit, normalizeSubject } from "./format.ts";
|
|
3
3
|
export { inspectStaged, commitWithMessage, GitError } from "./git.ts";
|
|
4
|
-
export { proposeHeuristic, inferType, inferScope, inferSubject, inferBreaking, detectBreakingKind, formatBreakingReason, breakingFooterDetail, ensureBreakingFooter, classifyPath, } from "./heuristic.ts";
|
|
4
|
+
export { proposeHeuristic, inferType, inferScope, inferSubject, inferBreaking, detectBreakingKind, formatBreakingReason, breakingFooterDetail, DEFAULT_BREAKING_FOOTER_DETAIL, ensureBreakingFooter, classifyPath, } from "./heuristic.ts";
|
|
5
5
|
export type { BreakingKind } from "./heuristic.ts";
|
|
6
6
|
export { parseArgs, helpText, UsageError } from "./parse-args.ts";
|
|
7
7
|
export { assembleDiff, parseUnifiedDiff } from "./parse-diff.ts";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { proposeWithAi } from "./ai.js";
|
|
2
2
|
export { formatCommit, parseCommit, normalizeSubject } from "./format.js";
|
|
3
3
|
export { inspectStaged, commitWithMessage, GitError } from "./git.js";
|
|
4
|
-
export { proposeHeuristic, inferType, inferScope, inferSubject, inferBreaking, detectBreakingKind, formatBreakingReason, breakingFooterDetail, ensureBreakingFooter, classifyPath, } from "./heuristic.js";
|
|
4
|
+
export { proposeHeuristic, inferType, inferScope, inferSubject, inferBreaking, detectBreakingKind, formatBreakingReason, breakingFooterDetail, DEFAULT_BREAKING_FOOTER_DETAIL, ensureBreakingFooter, classifyPath, } from "./heuristic.js";
|
|
5
5
|
export { parseArgs, helpText, UsageError } from "./parse-args.js";
|
|
6
6
|
export { assembleDiff, parseUnifiedDiff } from "./parse-diff.js";
|
|
7
7
|
export { installHook, uninstallHook, runPrepareCommitMsg, shouldSkipPrepareCommitMsg, hasNonCommentContent, HOOK_BEGIN, HOOK_END, } from "./hook.js";
|
package/dist/propose.js
CHANGED
|
@@ -30,6 +30,9 @@ export async function proposeMessage(diff, options, env = process.env) {
|
|
|
30
30
|
: breaking
|
|
31
31
|
? heuristic.breakingReason ?? message.breakingReason
|
|
32
32
|
: undefined;
|
|
33
|
-
|
|
33
|
+
const withMeta = { ...message, breaking, breakingReason };
|
|
34
|
+
// Forced --breaking: footer uses subject, not bilingual default.
|
|
35
|
+
const footerReason = kind === "forced" ? withMeta.subject : breakingFooterDetail(diff);
|
|
36
|
+
return ensureBreakingFooter(withMeta, footerReason);
|
|
34
37
|
}
|
|
35
38
|
//# sourceMappingURL=propose.js.map
|