@kb-labs/commit-core 2.116.14 → 2.118.0
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/applier/index.js +96 -94
- package/dist/applier/index.js.map +1 -1
- package/dist/generator/index.js +1 -1
- package/dist/generator/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +95 -95
- package/dist/index.js.map +1 -1
- package/dist/validator/index.d.ts +43 -0
- package/dist/validator/index.js +131 -0
- package/dist/validator/index.js.map +1 -0
- package/package.json +8 -4
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export { A as ApplyOptions, G as GenerateOptions, a as GitStatusWithStaleness, L
|
|
|
2
2
|
export { F as FileDiff, d as detectCommitStyle, f as formatFileSummary, g as getAllChangedFiles, a as getCurrentBranch, b as getFileDiff, c as getFileSummaries, e as getGitStatus, h as getRecentCommits, i as hasChanges, j as isProtectedBranch } from './recent-commits-BnietMgO.js';
|
|
3
3
|
export { S as SYSTEM_PROMPT, b as buildPrompt, g as generateCommitPlan, a as generateHeuristicPlan, p as parseResponse } from './heuristics-AM06lXSo.js';
|
|
4
4
|
export { applyCommitPlan, formatCommitMessage, pushCommits } from './applier/index.js';
|
|
5
|
+
export { checkPlanStaleness, groupFilesByRepo, validatePlanIntegrity } from './validator/index.js';
|
|
5
6
|
export { clearPlan, getCommitStoragePath, getCurrentPlanPath, getCurrentStatusPath, hasPlan, initStorage, listHistory, loadPlan, loadStatus, savePlan, saveToHistory } from './storage/index.js';
|
|
6
7
|
export { ApplyResult, CommitGroup, CommitPlan, ConventionalType, FileSummary, GitStatus, GitStatusSnapshot, PushResult, ReleaseHint } from '@kb-labs/commit-contracts';
|
package/dist/index.js
CHANGED
|
@@ -2029,7 +2029,7 @@ async function generateCommitPlan(options) {
|
|
|
2029
2029
|
const { cwd, onProgress } = options;
|
|
2030
2030
|
const logger = useLogger();
|
|
2031
2031
|
const analytics = useAnalytics();
|
|
2032
|
-
const llm = useLLM();
|
|
2032
|
+
const llm = options.llmComplete ? useLLM() : void 0;
|
|
2033
2033
|
const startTime = Date.now();
|
|
2034
2034
|
const gitStatus = await getGitStatus(cwd);
|
|
2035
2035
|
const allFiles = getAllChangedFiles(gitStatus);
|
|
@@ -2766,6 +2766,98 @@ function getErrorType(error) {
|
|
|
2766
2766
|
const preview = error.message.substring(0, 50).replace(/\n/g, " ");
|
|
2767
2767
|
return `error: ${preview}${error.message.length > 50 ? "..." : ""}`;
|
|
2768
2768
|
}
|
|
2769
|
+
function groupFilesByRepo(cwd, files) {
|
|
2770
|
+
const filesByRepo = /* @__PURE__ */ new Map();
|
|
2771
|
+
for (const file of files) {
|
|
2772
|
+
const segments = file.split("/");
|
|
2773
|
+
const potentialRepoDir = segments[0];
|
|
2774
|
+
if (!potentialRepoDir) {
|
|
2775
|
+
const group = filesByRepo.get(cwd) ?? [];
|
|
2776
|
+
group.push({ relativePath: file, originalPath: file });
|
|
2777
|
+
filesByRepo.set(cwd, group);
|
|
2778
|
+
continue;
|
|
2779
|
+
}
|
|
2780
|
+
const potentialRepoPath = join(cwd, potentialRepoDir);
|
|
2781
|
+
const potentialGitDir = join(potentialRepoPath, ".git");
|
|
2782
|
+
const isNestedRepo = existsSync(potentialGitDir);
|
|
2783
|
+
if (isNestedRepo) {
|
|
2784
|
+
const relativePath = segments.slice(1).join("/");
|
|
2785
|
+
const group = filesByRepo.get(potentialRepoPath) ?? [];
|
|
2786
|
+
group.push({ relativePath, originalPath: file });
|
|
2787
|
+
filesByRepo.set(potentialRepoPath, group);
|
|
2788
|
+
} else {
|
|
2789
|
+
const group = filesByRepo.get(cwd) ?? [];
|
|
2790
|
+
group.push({ relativePath: file, originalPath: file });
|
|
2791
|
+
filesByRepo.set(cwd, group);
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
return filesByRepo;
|
|
2795
|
+
}
|
|
2796
|
+
function validatePlanIntegrity(plan) {
|
|
2797
|
+
const errors = [];
|
|
2798
|
+
const seenInCommit = /* @__PURE__ */ new Map();
|
|
2799
|
+
for (const commit of plan.commits) {
|
|
2800
|
+
if (commit.files.length === 0) {
|
|
2801
|
+
errors.push(`Commit ${commit.id} has no files`);
|
|
2802
|
+
continue;
|
|
2803
|
+
}
|
|
2804
|
+
if (!commit.message.trim()) {
|
|
2805
|
+
errors.push(`Commit ${commit.id} has empty message`);
|
|
2806
|
+
continue;
|
|
2807
|
+
}
|
|
2808
|
+
for (const file of commit.files) {
|
|
2809
|
+
const firstCommit = seenInCommit.get(file);
|
|
2810
|
+
if (firstCommit) {
|
|
2811
|
+
errors.push(
|
|
2812
|
+
`File appears in multiple commits: ${file} (first: ${firstCommit}, duplicate: ${commit.id})`
|
|
2813
|
+
);
|
|
2814
|
+
} else {
|
|
2815
|
+
seenInCommit.set(file, commit.id);
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
return errors;
|
|
2820
|
+
}
|
|
2821
|
+
async function checkPlanStaleness(cwd, plan, scope) {
|
|
2822
|
+
const logger = useLogger();
|
|
2823
|
+
const planFiles = new Set(plan.commits.flatMap((c) => c.files));
|
|
2824
|
+
await logger.debug("checkPlanStaleness: start", {
|
|
2825
|
+
scope,
|
|
2826
|
+
cwd,
|
|
2827
|
+
planFiles: [...planFiles]
|
|
2828
|
+
});
|
|
2829
|
+
if (planFiles.size === 0) {
|
|
2830
|
+
return { isStale: false, reason: "" };
|
|
2831
|
+
}
|
|
2832
|
+
const filesByRepo = groupFilesByRepo(cwd, [...planFiles]);
|
|
2833
|
+
for (const [repoPath, fileInfos] of filesByRepo) {
|
|
2834
|
+
const currentStatus = await getGitStatus(repoPath);
|
|
2835
|
+
const currentFiles = new Set(getAllChangedFiles(currentStatus));
|
|
2836
|
+
await logger.debug("checkPlanStaleness: repo status", {
|
|
2837
|
+
repoPath,
|
|
2838
|
+
staged: currentStatus.staged,
|
|
2839
|
+
unstaged: currentStatus.unstaged,
|
|
2840
|
+
untracked: currentStatus.untracked,
|
|
2841
|
+
expected: fileInfos.map((f) => f.relativePath)
|
|
2842
|
+
});
|
|
2843
|
+
for (const { relativePath, originalPath } of fileInfos) {
|
|
2844
|
+
if (!currentFiles.has(relativePath)) {
|
|
2845
|
+
await logger.warn("checkPlanStaleness: file not in current changes", {
|
|
2846
|
+
scope,
|
|
2847
|
+
repoPath,
|
|
2848
|
+
originalPath,
|
|
2849
|
+
relativePath,
|
|
2850
|
+
currentFiles: [...currentFiles]
|
|
2851
|
+
});
|
|
2852
|
+
return {
|
|
2853
|
+
isStale: true,
|
|
2854
|
+
reason: `File no longer has changes: ${originalPath}. Regenerate plan or use --force.`
|
|
2855
|
+
};
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
}
|
|
2859
|
+
return { isStale: false, reason: "" };
|
|
2860
|
+
}
|
|
2769
2861
|
var GIT_HOOK_NAMES = [
|
|
2770
2862
|
"pre-commit",
|
|
2771
2863
|
"commit-msg",
|
|
@@ -2811,7 +2903,7 @@ async function applyCommitPlan(cwd, plan, options) {
|
|
|
2811
2903
|
};
|
|
2812
2904
|
}
|
|
2813
2905
|
if (!options?.force) {
|
|
2814
|
-
const staleness = await
|
|
2906
|
+
const staleness = await checkPlanStaleness(cwd, plan, options?.scope);
|
|
2815
2907
|
if (staleness.isStale) {
|
|
2816
2908
|
return {
|
|
2817
2909
|
success: false,
|
|
@@ -2840,31 +2932,6 @@ async function applyCommitPlan(cwd, plan, options) {
|
|
|
2840
2932
|
errors
|
|
2841
2933
|
};
|
|
2842
2934
|
}
|
|
2843
|
-
function validatePlanIntegrity(plan) {
|
|
2844
|
-
const errors = [];
|
|
2845
|
-
const seenInCommit = /* @__PURE__ */ new Map();
|
|
2846
|
-
for (const commit of plan.commits) {
|
|
2847
|
-
if (commit.files.length === 0) {
|
|
2848
|
-
errors.push(`Commit ${commit.id} has no files`);
|
|
2849
|
-
continue;
|
|
2850
|
-
}
|
|
2851
|
-
if (!commit.message.trim()) {
|
|
2852
|
-
errors.push(`Commit ${commit.id} has empty message`);
|
|
2853
|
-
continue;
|
|
2854
|
-
}
|
|
2855
|
-
for (const file of commit.files) {
|
|
2856
|
-
const firstCommit = seenInCommit.get(file);
|
|
2857
|
-
if (firstCommit) {
|
|
2858
|
-
errors.push(
|
|
2859
|
-
`File appears in multiple commits: ${file} (first: ${firstCommit}, duplicate: ${commit.id})`
|
|
2860
|
-
);
|
|
2861
|
-
} else {
|
|
2862
|
-
seenInCommit.set(file, commit.id);
|
|
2863
|
-
}
|
|
2864
|
-
}
|
|
2865
|
-
}
|
|
2866
|
-
return errors;
|
|
2867
|
-
}
|
|
2868
2935
|
async function applyCommit(cwd, commit) {
|
|
2869
2936
|
const filesByRepo = groupFilesByRepo(cwd, commit.files);
|
|
2870
2937
|
const repos = Array.from(filesByRepo.keys());
|
|
@@ -2918,33 +2985,6 @@ async function applyCommit(cwd, commit) {
|
|
|
2918
2985
|
const result = await git.commit(message);
|
|
2919
2986
|
return result.commit;
|
|
2920
2987
|
}
|
|
2921
|
-
function groupFilesByRepo(cwd, files) {
|
|
2922
|
-
const filesByRepo = /* @__PURE__ */ new Map();
|
|
2923
|
-
for (const file of files) {
|
|
2924
|
-
const segments = file.split("/");
|
|
2925
|
-
const potentialRepoDir = segments[0];
|
|
2926
|
-
if (!potentialRepoDir) {
|
|
2927
|
-
const group = filesByRepo.get(cwd) ?? [];
|
|
2928
|
-
group.push({ relativePath: file, originalPath: file });
|
|
2929
|
-
filesByRepo.set(cwd, group);
|
|
2930
|
-
continue;
|
|
2931
|
-
}
|
|
2932
|
-
const potentialRepoPath = join(cwd, potentialRepoDir);
|
|
2933
|
-
const potentialGitDir = join(potentialRepoPath, ".git");
|
|
2934
|
-
const isNestedRepo = existsSync(potentialGitDir);
|
|
2935
|
-
if (isNestedRepo) {
|
|
2936
|
-
const relativePath = segments.slice(1).join("/");
|
|
2937
|
-
const group = filesByRepo.get(potentialRepoPath) ?? [];
|
|
2938
|
-
group.push({ relativePath, originalPath: file });
|
|
2939
|
-
filesByRepo.set(potentialRepoPath, group);
|
|
2940
|
-
} else {
|
|
2941
|
-
const group = filesByRepo.get(cwd) ?? [];
|
|
2942
|
-
group.push({ relativePath: file, originalPath: file });
|
|
2943
|
-
filesByRepo.set(cwd, group);
|
|
2944
|
-
}
|
|
2945
|
-
}
|
|
2946
|
-
return filesByRepo;
|
|
2947
|
-
}
|
|
2948
2988
|
var COMMIT_FOOTER = "\n\n\u{1F916} Generated by kb-labs-commit-plugin";
|
|
2949
2989
|
function formatCommitMessage(commit, options) {
|
|
2950
2990
|
const type = commit.type;
|
|
@@ -2962,46 +3002,6 @@ ${commit.body}`;
|
|
|
2962
3002
|
}
|
|
2963
3003
|
return message;
|
|
2964
3004
|
}
|
|
2965
|
-
async function checkStaleness(cwd, plan, scope) {
|
|
2966
|
-
const logger = useLogger();
|
|
2967
|
-
const planFiles = new Set(plan.commits.flatMap((c) => c.files));
|
|
2968
|
-
await logger.debug("checkStaleness: start", {
|
|
2969
|
-
scope,
|
|
2970
|
-
cwd,
|
|
2971
|
-
planFiles: [...planFiles]
|
|
2972
|
-
});
|
|
2973
|
-
if (planFiles.size === 0) {
|
|
2974
|
-
return { isStale: false, reason: "" };
|
|
2975
|
-
}
|
|
2976
|
-
const filesByRepo = groupFilesByRepo(cwd, [...planFiles]);
|
|
2977
|
-
for (const [repoPath, fileInfos] of filesByRepo) {
|
|
2978
|
-
const currentStatus = await getGitStatus(repoPath);
|
|
2979
|
-
const currentFiles = new Set(getAllChangedFiles(currentStatus));
|
|
2980
|
-
await logger.debug("checkStaleness: repo status", {
|
|
2981
|
-
repoPath,
|
|
2982
|
-
staged: currentStatus.staged,
|
|
2983
|
-
unstaged: currentStatus.unstaged,
|
|
2984
|
-
untracked: currentStatus.untracked,
|
|
2985
|
-
expected: fileInfos.map((f) => f.relativePath)
|
|
2986
|
-
});
|
|
2987
|
-
for (const { relativePath, originalPath } of fileInfos) {
|
|
2988
|
-
if (!currentFiles.has(relativePath)) {
|
|
2989
|
-
await logger.warn("checkStaleness: file not in current changes", {
|
|
2990
|
-
scope,
|
|
2991
|
-
repoPath,
|
|
2992
|
-
originalPath,
|
|
2993
|
-
relativePath,
|
|
2994
|
-
currentFiles: [...currentFiles]
|
|
2995
|
-
});
|
|
2996
|
-
return {
|
|
2997
|
-
isStale: true,
|
|
2998
|
-
reason: `File no longer has changes: ${originalPath}. Regenerate plan or use --force.`
|
|
2999
|
-
};
|
|
3000
|
-
}
|
|
3001
|
-
}
|
|
3002
|
-
}
|
|
3003
|
-
return { isStale: false, reason: "" };
|
|
3004
|
-
}
|
|
3005
3005
|
async function pushCommits(cwd, options) {
|
|
3006
3006
|
const git = simpleGit(cwd);
|
|
3007
3007
|
const remote = options?.remote || "origin";
|
|
@@ -3199,6 +3199,6 @@ async function initStorage(cwd, scope = "root") {
|
|
|
3199
3199
|
}
|
|
3200
3200
|
}
|
|
3201
3201
|
|
|
3202
|
-
export { SYSTEM_PROMPT, applyCommitPlan, buildPrompt, clearPlan, detectCommitStyle, formatCommitMessage, formatFileSummary, generateCommitPlan, generateHeuristicPlan, getAllChangedFiles, getCommitStoragePath, getCurrentBranch, getCurrentPlanPath, getCurrentStatusPath, getFileDiff, getFileSummaries, getGitStatus, getRecentCommits, hasChanges, hasPlan, initStorage, isProtectedBranch, listHistory, loadPlan, loadStatus, parseResponse, pushCommits, savePlan, saveToHistory };
|
|
3202
|
+
export { SYSTEM_PROMPT, applyCommitPlan, buildPrompt, checkPlanStaleness, clearPlan, detectCommitStyle, formatCommitMessage, formatFileSummary, generateCommitPlan, generateHeuristicPlan, getAllChangedFiles, getCommitStoragePath, getCurrentBranch, getCurrentPlanPath, getCurrentStatusPath, getFileDiff, getFileSummaries, getGitStatus, getRecentCommits, groupFilesByRepo, hasChanges, hasPlan, initStorage, isProtectedBranch, listHistory, loadPlan, loadStatus, parseResponse, pushCommits, savePlan, saveToHistory, validatePlanIntegrity };
|
|
3203
3203
|
//# sourceMappingURL=index.js.map
|
|
3204
3204
|
//# sourceMappingURL=index.js.map
|