@quikcommit/cli 11.0.0 → 12.0.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.
Files changed (2) hide show
  1. package/dist/index.js +214 -89
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -89,9 +89,14 @@ function slugifyFilename(path) {
89
89
  const noExt = basename.replace(/\.[^.]+$/, "");
90
90
  return noExt.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
91
91
  }
92
+ function pickBestFile(files) {
93
+ const codeFiles = files.filter((f) => !NON_CODE_PATTERNS.some((rx) => rx.test(f)));
94
+ return codeFiles[0] ?? files[0] ?? "";
95
+ }
92
96
  function deterministicBranchName(opts) {
93
97
  const files = opts.files ?? [];
94
- const haystack = `${opts.description ?? ""} ${files.join(" ")}`;
98
+ const codeFiles = files.filter((f) => !NON_CODE_PATTERNS.some((rx) => rx.test(f)));
99
+ const haystack = `${opts.description ?? ""} ${(codeFiles.length > 0 ? codeFiles : files).join(" ")}`;
95
100
  let type = "chore";
96
101
  for (const [rx, t] of TYPE_HINTS) {
97
102
  if (rx.test(haystack)) {
@@ -103,7 +108,7 @@ function deterministicBranchName(opts) {
103
108
  if (opts.description) {
104
109
  slug = opts.description.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").split("-").slice(0, 5).join("-").slice(0, 40);
105
110
  } else if (files.length > 0) {
106
- slug = slugifyFilename(files[0] ?? "");
111
+ slug = slugifyFilename(pickBestFile(files));
107
112
  } else {
108
113
  slug = "changes";
109
114
  }
@@ -117,7 +122,7 @@ function deterministicBranchName(opts) {
117
122
  }
118
123
  return { name, type, slug };
119
124
  }
120
- var BRANCH_NAME_RX, PROTECTED_BRANCH_RX, MAX_BRANCH_NAME_LENGTH, TYPE_HINTS;
125
+ var BRANCH_NAME_RX, PROTECTED_BRANCH_RX, MAX_BRANCH_NAME_LENGTH, TYPE_HINTS, NON_CODE_PATTERNS;
121
126
  var init_branch = __esm({
122
127
  "../shared/dist/branch.js"() {
123
128
  "use strict";
@@ -133,6 +138,21 @@ var init_branch = __esm({
133
138
  [/\bfix|bug|issue/i, "fix"],
134
139
  [/\bfeat|add|new\b/i, "feat"]
135
140
  ];
141
+ NON_CODE_PATTERNS = [
142
+ /^docs?\//i,
143
+ /^\.env/,
144
+ /\.md$/i,
145
+ /^readme/i,
146
+ /^changelog/i,
147
+ /^license/i,
148
+ /\.lock$/,
149
+ /\.ya?ml$/,
150
+ /\.json$/,
151
+ /\.toml$/,
152
+ /\/\.?config\b/i,
153
+ /^\.github\//,
154
+ /^\.vscode\//
155
+ ];
136
156
  }
137
157
  });
138
158
 
@@ -439,6 +459,13 @@ var init_api = __esm({
439
459
  async generateBranchName(req) {
440
460
  return this.request("/v1/branch", req);
441
461
  }
462
+ async summarizeChunk(diff, changes, model) {
463
+ const data = await this.request(
464
+ "/v1/summarize",
465
+ { diff, changes, ...model ? { model } : {} }
466
+ );
467
+ return data.summary ?? "";
468
+ }
442
469
  async fetchJson(endpoint, options) {
443
470
  if (!this.apiKey) {
444
471
  throw new Error("Not authenticated. Run `qc login` first.");
@@ -7913,7 +7940,7 @@ function getStagedDiff(excludes = []) {
7913
7940
  }
7914
7941
  return (0, import_child_process2.execFileSync)("git", args, {
7915
7942
  encoding: "utf-8",
7916
- maxBuffer: 10 * 1024 * 1024
7943
+ maxBuffer: 50 * 1024 * 1024
7917
7944
  });
7918
7945
  }
7919
7946
  function getStagedFiles() {
@@ -7975,8 +8002,18 @@ function gitCommit(message) {
7975
8002
  }
7976
8003
  }
7977
8004
  function gitPush() {
8005
+ const branch = (0, import_child_process2.execFileSync)("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
8006
+ encoding: "utf-8"
8007
+ }).trim();
8008
+ let hasUpstream = false;
8009
+ try {
8010
+ (0, import_child_process2.execFileSync)("git", ["rev-parse", "--abbrev-ref", `${branch}@{upstream}`], { stdio: "pipe" });
8011
+ hasUpstream = true;
8012
+ } catch {
8013
+ }
8014
+ const args = hasUpstream ? ["push"] : ["push", "--set-upstream", "origin", branch];
7978
8015
  try {
7979
- (0, import_child_process2.execFileSync)("git", ["push"], { stdio: "pipe" });
8016
+ (0, import_child_process2.execFileSync)("git", args, { stdio: "pipe" });
7980
8017
  } catch (err) {
7981
8018
  const stderr = err?.stderr?.toString() ?? "";
7982
8019
  if (stderr) process.stderr.write(stderr);
@@ -8091,19 +8128,36 @@ function getPushStats() {
8091
8128
  const branch = (0, import_child_process2.execFileSync)("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
8092
8129
  encoding: "utf-8"
8093
8130
  }).trim();
8094
- const countOutput = (0, import_child_process2.execFileSync)(
8095
- "git",
8096
- ["rev-list", "--count", `origin/${branch}..HEAD`],
8097
- { encoding: "utf-8" }
8098
- ).trim();
8099
- const parsedCount = parseInt(countOutput, 10);
8100
- const commits = Number.isFinite(parsedCount) ? parsedCount : 0;
8131
+ let upstream = null;
8132
+ try {
8133
+ upstream = (0, import_child_process2.execFileSync)(
8134
+ "git",
8135
+ ["rev-parse", "--abbrev-ref", `${branch}@{upstream}`],
8136
+ { encoding: "utf-8", stdio: "pipe" }
8137
+ ).trim();
8138
+ } catch {
8139
+ }
8140
+ if (upstream) {
8141
+ const countOutput = (0, import_child_process2.execFileSync)(
8142
+ "git",
8143
+ ["rev-list", "--count", `${upstream}..HEAD`],
8144
+ { encoding: "utf-8" }
8145
+ ).trim();
8146
+ const parsedCount = parseInt(countOutput, 10);
8147
+ const commits = Number.isFinite(parsedCount) ? parsedCount : 0;
8148
+ const stat2 = (0, import_child_process2.execFileSync)(
8149
+ "git",
8150
+ ["diff", "--shortstat", `${upstream}..HEAD`],
8151
+ { encoding: "utf-8" }
8152
+ ).trim();
8153
+ return { commits, stat: stat2 };
8154
+ }
8101
8155
  const stat = (0, import_child_process2.execFileSync)(
8102
8156
  "git",
8103
- ["diff", "--shortstat", `origin/${branch}..HEAD`],
8157
+ ["diff", "--shortstat", "HEAD~1..HEAD"],
8104
8158
  { encoding: "utf-8" }
8105
8159
  ).trim();
8106
- return { commits, stat };
8160
+ return { commits: 1, stat };
8107
8161
  } catch {
8108
8162
  return null;
8109
8163
  }
@@ -8747,7 +8801,8 @@ var smart_diff_exports = {};
8747
8801
  __export(smart_diff_exports, {
8748
8802
  classifyFile: () => classifyFile,
8749
8803
  preprocessDiff: () => preprocessDiff,
8750
- preprocessDiffWithSizeBudget: () => preprocessDiffWithSizeBudget
8804
+ preprocessDiffWithSizeBudget: () => preprocessDiffWithSizeBudget,
8805
+ splitDiffIntoChunks: () => splitDiffIntoChunks
8751
8806
  });
8752
8807
  function sanitizeFilepath(path) {
8753
8808
  return path.replace(/[\x00-\x1F\x7F[\]`]/g, "_").slice(0, 200);
@@ -8788,7 +8843,7 @@ function isMinified(content) {
8788
8843
  }
8789
8844
  function preprocessDiff(diff) {
8790
8845
  const files = parseDiffIntoFiles(diff);
8791
- if (files.length === 0) return { processedDiff: diff, summarized: [], aggressivelySummarized: [], tokensSaved: 0 };
8846
+ if (files.length === 0) return { processedDiff: diff, summarized: [], tokensSaved: 0, needsChunking: false };
8792
8847
  const kept = [];
8793
8848
  const summarized = [];
8794
8849
  let tokensSaved = 0;
@@ -8833,19 +8888,50 @@ function preprocessDiff(diff) {
8833
8888
  return {
8834
8889
  processedDiff: kept.join(""),
8835
8890
  summarized,
8836
- aggressivelySummarized: [],
8837
- tokensSaved
8891
+ tokensSaved,
8892
+ needsChunking: false
8838
8893
  };
8839
8894
  }
8840
- function buildFileSummary(file) {
8841
- const sizeKB = Math.round(file.content.length / 1024);
8842
- return `[modified: ${sanitizeFilepath(file.filepath)} \u2014 +${file.additions} \u2212${file.deletions} lines, ~${sizeKB}KB]
8843
- `;
8895
+ function stripContext(fileContent, contextLines) {
8896
+ const lines = fileContent.split("\n");
8897
+ const result = [];
8898
+ let inHeader = true;
8899
+ const pendingContext = [];
8900
+ let afterChange = 0;
8901
+ for (const line of lines) {
8902
+ if (inHeader) {
8903
+ result.push(line);
8904
+ if (line.startsWith("@@")) inHeader = false;
8905
+ continue;
8906
+ }
8907
+ if (line.startsWith("@@")) {
8908
+ pendingContext.length = 0;
8909
+ afterChange = 0;
8910
+ result.push(line);
8911
+ continue;
8912
+ }
8913
+ if (line.startsWith("+") || line.startsWith("-")) {
8914
+ if (contextLines > 0) {
8915
+ result.push(...pendingContext.slice(-contextLines));
8916
+ }
8917
+ pendingContext.length = 0;
8918
+ result.push(line);
8919
+ afterChange = contextLines;
8920
+ continue;
8921
+ }
8922
+ if (afterChange > 0) {
8923
+ result.push(line);
8924
+ afterChange--;
8925
+ } else {
8926
+ pendingContext.push(line);
8927
+ }
8928
+ }
8929
+ return result.join("\n");
8844
8930
  }
8845
- function preprocessDiffWithSizeBudget(diff, maxBytes = 5 * 1024 * 1024) {
8931
+ function preprocessDiffWithSizeBudget(diff, maxBytes = 750 * 1024) {
8846
8932
  const files = parseDiffIntoFiles(diff);
8847
8933
  if (files.length === 0) {
8848
- return { processedDiff: diff, summarized: [], aggressivelySummarized: [], tokensSaved: 0 };
8934
+ return { processedDiff: diff, summarized: [], tokensSaved: 0, needsChunking: false };
8849
8935
  }
8850
8936
  const entries = [];
8851
8937
  const summarized = [];
@@ -8856,7 +8942,7 @@ function preprocessDiffWithSizeBudget(diff, maxBytes = 5 * 1024 * 1024) {
8856
8942
  case "sourcemap":
8857
8943
  tokensSaved += estimateTokens(file.content);
8858
8944
  summarized.push(file.filepath);
8859
- entries.push({ file, isNoise: true, summaryLine: null });
8945
+ entries.push({ file, isNoise: true, summaryLine: null, strippedContent: null });
8860
8946
  break;
8861
8947
  case "lock":
8862
8948
  tokensSaved += estimateTokens(file.content);
@@ -8864,6 +8950,7 @@ function preprocessDiffWithSizeBudget(diff, maxBytes = 5 * 1024 * 1024) {
8864
8950
  entries.push({
8865
8951
  file,
8866
8952
  isNoise: true,
8953
+ strippedContent: null,
8867
8954
  summaryLine: `[lock file updated: ${sanitizeFilepath(file.filepath)} (+${file.additions} \u2212${file.deletions} lines)]
8868
8955
  `
8869
8956
  });
@@ -8874,6 +8961,7 @@ function preprocessDiffWithSizeBudget(diff, maxBytes = 5 * 1024 * 1024) {
8874
8961
  entries.push({
8875
8962
  file,
8876
8963
  isNoise: true,
8964
+ strippedContent: null,
8877
8965
  summaryLine: `[generated: ${sanitizeFilepath(file.filepath)} (+${file.additions} \u2212${file.deletions})]
8878
8966
  `
8879
8967
  });
@@ -8884,6 +8972,7 @@ function preprocessDiffWithSizeBudget(diff, maxBytes = 5 * 1024 * 1024) {
8884
8972
  entries.push({
8885
8973
  file,
8886
8974
  isNoise: true,
8975
+ strippedContent: null,
8887
8976
  summaryLine: `[vendored: ${sanitizeFilepath(file.filepath)} updated]
8888
8977
  `
8889
8978
  });
@@ -8896,83 +8985,75 @@ function preprocessDiffWithSizeBudget(diff, maxBytes = 5 * 1024 * 1024) {
8896
8985
  entries.push({
8897
8986
  file,
8898
8987
  isNoise: true,
8988
+ strippedContent: null,
8899
8989
  summaryLine: `[minified asset: ${sanitizeFilepath(file.filepath)} (${sizeKB} KB)]
8900
8990
  `
8901
8991
  });
8902
8992
  } else {
8903
- entries.push({ file, isNoise: false, summaryLine: null });
8993
+ entries.push({ file, isNoise: false, summaryLine: null, strippedContent: null });
8904
8994
  }
8905
8995
  break;
8906
8996
  }
8907
8997
  }
8908
- const aggressiveMap = /* @__PURE__ */ new Map();
8998
+ const codeEntries = entries.filter((e) => !e.isNoise);
8909
8999
  function buildOutput() {
8910
9000
  const parts = [];
8911
9001
  for (const entry of entries) {
8912
9002
  if (entry.isNoise) {
8913
9003
  if (entry.summaryLine !== null) parts.push(entry.summaryLine);
8914
- } else if (aggressiveMap.has(entry.file.filepath)) {
8915
- parts.push(aggressiveMap.get(entry.file.filepath));
8916
9004
  } else {
8917
- parts.push(entry.file.content);
9005
+ parts.push(entry.strippedContent ?? entry.file.content);
8918
9006
  }
8919
9007
  }
8920
9008
  return parts.join("");
8921
9009
  }
8922
- const codeEntries = entries.filter((e) => !e.isNoise);
8923
9010
  let output = buildOutput();
8924
9011
  if (output.length <= maxBytes) {
8925
- return {
8926
- processedDiff: output,
8927
- summarized,
8928
- aggressivelySummarized: [],
8929
- tokensSaved
8930
- };
9012
+ return { processedDiff: output, summarized, tokensSaved, needsChunking: false };
8931
9013
  }
8932
- const TIER1_THRESHOLD = 5 * 1024;
8933
9014
  for (const entry of codeEntries) {
8934
- if (entry.file.content.length > TIER1_THRESHOLD && !aggressiveMap.has(entry.file.filepath)) {
8935
- tokensSaved += estimateTokens(entry.file.content);
8936
- aggressiveMap.set(entry.file.filepath, buildFileSummary(entry.file));
8937
- }
9015
+ const stripped = stripContext(entry.file.content, 1);
9016
+ tokensSaved += estimateTokens(entry.file.content) - estimateTokens(stripped);
9017
+ entry.strippedContent = stripped;
8938
9018
  }
8939
9019
  output = buildOutput();
8940
9020
  if (output.length <= maxBytes) {
8941
- return {
8942
- processedDiff: output,
8943
- summarized,
8944
- aggressivelySummarized: [...aggressiveMap.keys()],
8945
- tokensSaved
8946
- };
9021
+ return { processedDiff: output, summarized, tokensSaved, needsChunking: false };
8947
9022
  }
8948
- const TIER2_THRESHOLD = 2 * 1024;
8949
9023
  for (const entry of codeEntries) {
8950
- if (entry.file.content.length > TIER2_THRESHOLD && !aggressiveMap.has(entry.file.filepath)) {
8951
- tokensSaved += estimateTokens(entry.file.content);
8952
- aggressiveMap.set(entry.file.filepath, buildFileSummary(entry.file));
8953
- }
9024
+ const stripped = stripContext(entry.file.content, 0);
9025
+ tokensSaved += estimateTokens(entry.strippedContent ?? entry.file.content) - estimateTokens(stripped);
9026
+ entry.strippedContent = stripped;
8954
9027
  }
8955
9028
  output = buildOutput();
8956
9029
  if (output.length <= maxBytes) {
8957
- return {
8958
- processedDiff: output,
8959
- summarized,
8960
- aggressivelySummarized: [...aggressiveMap.keys()],
8961
- tokensSaved
8962
- };
9030
+ return { processedDiff: output, summarized, tokensSaved, needsChunking: false };
8963
9031
  }
8964
- for (const entry of codeEntries) {
8965
- if (!aggressiveMap.has(entry.file.filepath)) {
8966
- tokensSaved += estimateTokens(entry.file.content);
8967
- aggressiveMap.set(entry.file.filepath, buildFileSummary(entry.file));
9032
+ return { processedDiff: output, summarized, tokensSaved, needsChunking: true };
9033
+ }
9034
+ function splitDiffIntoChunks(diff, maxChunkBytes = 600 * 1024) {
9035
+ const files = parseDiffIntoFiles(diff);
9036
+ if (files.length === 0) return [];
9037
+ const chunks = [];
9038
+ let currentDiff = "";
9039
+ let currentFiles = [];
9040
+ for (const file of files) {
9041
+ let content = file.content;
9042
+ if (content.length > maxChunkBytes) {
9043
+ content = stripContext(content, 0);
9044
+ }
9045
+ if (currentDiff.length > 0 && currentDiff.length + content.length > maxChunkBytes) {
9046
+ chunks.push({ diff: currentDiff, files: currentFiles });
9047
+ currentDiff = "";
9048
+ currentFiles = [];
8968
9049
  }
9050
+ currentDiff += content;
9051
+ currentFiles.push(file.filepath);
8969
9052
  }
8970
- return {
8971
- processedDiff: buildOutput(),
8972
- summarized,
8973
- aggressivelySummarized: [...aggressiveMap.keys()],
8974
- tokensSaved
8975
- };
9053
+ if (currentDiff.length > 0) {
9054
+ chunks.push({ diff: currentDiff, files: currentFiles });
9055
+ }
9056
+ return chunks;
8976
9057
  }
8977
9058
  var LOCK_FILES, GENERATED_PATTERNS, VENDORED_PREFIXES;
8978
9059
  var init_smart_diff = __esm({
@@ -10579,17 +10660,15 @@ async function runLocalCommit(args) {
10579
10660
  let diff = getStagedDiff(excludes);
10580
10661
  const changes = getStagedFiles();
10581
10662
  if (!args.noSmartDiff) {
10582
- const smartResult = preprocessDiffWithSizeBudget(diff, 5 * 1024 * 1024);
10663
+ const smartResult = preprocessDiffWithSizeBudget(diff);
10583
10664
  diff = smartResult.processedDiff;
10584
10665
  if (smartResult.summarized.length > 0 && !silent) {
10585
10666
  log.step(
10586
10667
  `smart-diff: ${smartResult.summarized.length} file(s) summarized (saved ~${Math.round(smartResult.tokensSaved / 1e3)}K tokens)`
10587
10668
  );
10588
10669
  }
10589
- if (smartResult.aggressivelySummarized.length > 0 && !silent) {
10590
- log.step(
10591
- `large-diff: ${smartResult.aggressivelySummarized.length} additional file(s) summarized to fit (commit message may be less specific)`
10592
- );
10670
+ if (smartResult.needsChunking && !silent) {
10671
+ log.step("large diff detected \u2014 local providers receive context-stripped diff");
10593
10672
  }
10594
10673
  }
10595
10674
  let rules = { ...await detectCommitlintRules(), ...config2.rules ?? {} };
@@ -11768,19 +11847,16 @@ async function runCommit(args) {
11768
11847
  const diff = getStagedDiff(excludes);
11769
11848
  const changes = getStagedFiles();
11770
11849
  let processedDiff = diff;
11850
+ let needsChunking = false;
11771
11851
  if (!args.noSmartDiff) {
11772
- const smartResult = preprocessDiffWithSizeBudget(diff, 5 * 1024 * 1024);
11852
+ const smartResult = preprocessDiffWithSizeBudget(diff);
11773
11853
  processedDiff = smartResult.processedDiff;
11854
+ needsChunking = smartResult.needsChunking;
11774
11855
  if (smartResult.summarized.length > 0) {
11775
11856
  log.step(
11776
11857
  `smart-diff: ${smartResult.summarized.length} file(s) summarized (saved ~${Math.round(smartResult.tokensSaved / 1e3)}K tokens)`
11777
11858
  );
11778
11859
  }
11779
- if (smartResult.aggressivelySummarized.length > 0) {
11780
- log.step(
11781
- `large-diff: ${smartResult.aggressivelySummarized.length} additional file(s) summarized to fit (commit message may be less specific \u2014 consider committing fewer files at a time)`
11782
- );
11783
- }
11784
11860
  }
11785
11861
  const commitlintRules = await detectCommitlintRules();
11786
11862
  let rules = { ...commitlintRules, ...config2.rules ?? {} };
@@ -11818,7 +11894,7 @@ async function runCommit(args) {
11818
11894
  const boxStyle = args.boxStyleOverride ?? config2.ui?.box?.style ?? "gradient";
11819
11895
  const spinner = createStageSpinner({
11820
11896
  stage: "aiGenerate",
11821
- message: `generating commit (${modelDisplay})...`,
11897
+ message: needsChunking ? `analyzing ${changes.trim().split("\n").length} files in chunks (${modelDisplay})...` : `generating commit (${modelDisplay})...`,
11822
11898
  ...uiCtx
11823
11899
  });
11824
11900
  if (!silent) spinner.start();
@@ -11826,14 +11902,63 @@ async function runCommit(args) {
11826
11902
  let generatedMessage;
11827
11903
  let diagnostics;
11828
11904
  try {
11829
- ({ message: generatedMessage, diagnostics } = await client.generateCommit(
11830
- processedDiff,
11831
- changes,
11832
- rules,
11833
- model,
11834
- recentCommits,
11835
- generationHints
11836
- ));
11905
+ if (needsChunking) {
11906
+ const chunks = splitDiffIntoChunks(processedDiff);
11907
+ if (chunks.length === 0) {
11908
+ spinner.stop();
11909
+ log.error("No parseable diff content to analyze.");
11910
+ process.exit(1);
11911
+ }
11912
+ spinner.stop();
11913
+ if (!silent) log.step(`large diff \u2014 analyzing ${chunks.length} chunk(s) in parallel...`);
11914
+ const results = await Promise.allSettled(
11915
+ chunks.map(
11916
+ (chunk) => client.summarizeChunk(chunk.diff, chunk.files.filter(Boolean).join("\n") || "unknown", model)
11917
+ )
11918
+ );
11919
+ const summaries = [];
11920
+ for (const r of results) {
11921
+ if (r.status === "fulfilled" && r.value) {
11922
+ summaries.push(r.value);
11923
+ }
11924
+ }
11925
+ if (summaries.length === 0) {
11926
+ log.error("All chunk summaries failed. Check your connection and try again.");
11927
+ process.exit(1);
11928
+ }
11929
+ if (results.some((r) => r.status === "rejected") && !silent) {
11930
+ const failed = results.filter((r) => r.status === "rejected").length;
11931
+ log.step(`${failed}/${results.length} chunk(s) failed \u2014 continuing with partial summaries`);
11932
+ }
11933
+ const combinedSummary = summaries.join("\n\n");
11934
+ const finalSpinner = createStageSpinner({
11935
+ stage: "aiGenerate",
11936
+ message: `generating commit from ${chunks.length} summaries (${modelDisplay})...`,
11937
+ ...uiCtx
11938
+ });
11939
+ if (!silent) finalSpinner.start();
11940
+ try {
11941
+ ({ message: generatedMessage, diagnostics } = await client.generateCommit(
11942
+ combinedSummary,
11943
+ changes,
11944
+ rules,
11945
+ model,
11946
+ recentCommits,
11947
+ generationHints
11948
+ ));
11949
+ } finally {
11950
+ finalSpinner.stop();
11951
+ }
11952
+ } else {
11953
+ ({ message: generatedMessage, diagnostics } = await client.generateCommit(
11954
+ processedDiff,
11955
+ changes,
11956
+ rules,
11957
+ model,
11958
+ recentCommits,
11959
+ generationHints
11960
+ ));
11961
+ }
11837
11962
  } finally {
11838
11963
  spinner.stop();
11839
11964
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quikcommit/cli",
3
- "version": "11.0.0",
3
+ "version": "12.0.0",
4
4
  "description": "AI-powered conventional commit messages",
5
5
  "bin": {
6
6
  "qc": "./dist/index.js"
@@ -34,7 +34,7 @@
34
34
  "esbuild": "^0.28.0",
35
35
  "typescript": "^5.9.3",
36
36
  "vitest": "^4.1.5",
37
- "@quikcommit/shared": "8.0.0"
37
+ "@quikcommit/shared": "9.0.0"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "node build.mjs",