@quikcommit/cli 13.0.0 → 13.2.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 +68 -50
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -11951,6 +11951,11 @@ async function runCommit(args) {
11951
11951
  }
11952
11952
  process.exit(1);
11953
11953
  }
11954
+ const { getLocalProviderConfig: getLocalProviderConfig2, runLocalCommit: runLocalCommit2 } = await Promise.resolve().then(() => (init_local(), local_exports));
11955
+ if (getLocalProviderConfig2()) {
11956
+ await runLocalCommit2(args);
11957
+ return;
11958
+ }
11954
11959
  const apiKey = apiKeyFlag ?? getApiKey();
11955
11960
  if (!apiKey) {
11956
11961
  log.error("Not authenticated. Run `qc login` first.");
@@ -12009,72 +12014,86 @@ async function runCommit(args) {
12009
12014
  const modelDisplay = model ?? "default";
12010
12015
  const uiCtx = buildUIContext(ui2, config2, args);
12011
12016
  const boxStyle = args.boxStyleOverride ?? config2.ui?.box?.style ?? "gradient";
12017
+ const t0 = Date.now();
12018
+ let generatedMessage;
12019
+ let diagnostics;
12020
+ async function generateViaChunks() {
12021
+ const chunks = splitDiffIntoChunks(processedDiff);
12022
+ if (chunks.length === 0) {
12023
+ log.error("No parseable diff content to analyze.");
12024
+ process.exit(1);
12025
+ }
12026
+ if (!silent) log.step(`large diff \u2014 analyzing ${chunks.length} chunk(s) in parallel...`);
12027
+ const results = await Promise.allSettled(
12028
+ chunks.map(
12029
+ (chunk) => client.summarizeChunk(chunk.diff, chunk.files.filter(Boolean).join("\n") || "unknown", model)
12030
+ )
12031
+ );
12032
+ const summaries = [];
12033
+ for (const r of results) {
12034
+ if (r.status === "fulfilled" && r.value) {
12035
+ summaries.push(r.value);
12036
+ }
12037
+ }
12038
+ if (summaries.length === 0) {
12039
+ log.error("All chunk summaries failed. Check your connection and try again.");
12040
+ process.exit(1);
12041
+ }
12042
+ if (results.some((r) => r.status === "rejected") && !silent) {
12043
+ const failed = results.filter((r) => r.status === "rejected").length;
12044
+ log.step(`${failed}/${results.length} chunk(s) failed \u2014 continuing with partial summaries`);
12045
+ }
12046
+ const combinedSummary = summaries.join("\n\n");
12047
+ const finalSpinner = createStageSpinner({
12048
+ stage: "aiGenerate",
12049
+ message: `generating commit from ${chunks.length} summaries (${modelDisplay})...`,
12050
+ ...uiCtx
12051
+ });
12052
+ if (!silent) finalSpinner.start();
12053
+ try {
12054
+ const result = await client.generateCommit(
12055
+ combinedSummary,
12056
+ changes,
12057
+ rules,
12058
+ model,
12059
+ recentCommits,
12060
+ generationHints
12061
+ );
12062
+ return result;
12063
+ } finally {
12064
+ finalSpinner.stop();
12065
+ }
12066
+ }
12012
12067
  const spinner = createStageSpinner({
12013
12068
  stage: "aiGenerate",
12014
12069
  message: needsChunking ? `analyzing ${changes.trim().split("\n").length} files in chunks (${modelDisplay})...` : `generating commit (${modelDisplay})...`,
12015
12070
  ...uiCtx
12016
12071
  });
12017
12072
  if (!silent) spinner.start();
12018
- const t0 = Date.now();
12019
- let generatedMessage;
12020
- let diagnostics;
12021
12073
  try {
12022
12074
  if (needsChunking) {
12023
- const chunks = splitDiffIntoChunks(processedDiff);
12024
- if (chunks.length === 0) {
12025
- spinner.stop();
12026
- log.error("No parseable diff content to analyze.");
12027
- process.exit(1);
12028
- }
12029
12075
  spinner.stop();
12030
- if (!silent) log.step(`large diff \u2014 analyzing ${chunks.length} chunk(s) in parallel...`);
12031
- const results = await Promise.allSettled(
12032
- chunks.map(
12033
- (chunk) => client.summarizeChunk(chunk.diff, chunk.files.filter(Boolean).join("\n") || "unknown", model)
12034
- )
12035
- );
12036
- const summaries = [];
12037
- for (const r of results) {
12038
- if (r.status === "fulfilled" && r.value) {
12039
- summaries.push(r.value);
12040
- }
12041
- }
12042
- if (summaries.length === 0) {
12043
- log.error("All chunk summaries failed. Check your connection and try again.");
12044
- process.exit(1);
12045
- }
12046
- if (results.some((r) => r.status === "rejected") && !silent) {
12047
- const failed = results.filter((r) => r.status === "rejected").length;
12048
- log.step(`${failed}/${results.length} chunk(s) failed \u2014 continuing with partial summaries`);
12049
- }
12050
- const combinedSummary = summaries.join("\n\n");
12051
- const finalSpinner = createStageSpinner({
12052
- stage: "aiGenerate",
12053
- message: `generating commit from ${chunks.length} summaries (${modelDisplay})...`,
12054
- ...uiCtx
12055
- });
12056
- if (!silent) finalSpinner.start();
12076
+ ({ message: generatedMessage, diagnostics } = await generateViaChunks());
12077
+ } else {
12057
12078
  try {
12058
12079
  ({ message: generatedMessage, diagnostics } = await client.generateCommit(
12059
- combinedSummary,
12080
+ processedDiff,
12060
12081
  changes,
12061
12082
  rules,
12062
12083
  model,
12063
12084
  recentCommits,
12064
12085
  generationHints
12065
12086
  ));
12066
- } finally {
12067
- finalSpinner.stop();
12087
+ } catch (err) {
12088
+ const is413 = err instanceof Error && /too large/i.test(err.message);
12089
+ if (is413) {
12090
+ spinner.stop();
12091
+ if (!silent) log.step("diff too large for single request \u2014 switching to chunk mode...");
12092
+ ({ message: generatedMessage, diagnostics } = await generateViaChunks());
12093
+ } else {
12094
+ throw err;
12095
+ }
12068
12096
  }
12069
- } else {
12070
- ({ message: generatedMessage, diagnostics } = await client.generateCommit(
12071
- processedDiff,
12072
- changes,
12073
- rules,
12074
- model,
12075
- recentCommits,
12076
- generationHints
12077
- ));
12078
12097
  }
12079
12098
  } finally {
12080
12099
  spinner.stop();
@@ -12709,8 +12728,7 @@ async function main() {
12709
12728
  await runLocalCommit2(values);
12710
12729
  return;
12711
12730
  }
12712
- const apiKeyToUse = apiKey ?? getApiKey();
12713
- if (!apiKeyToUse) {
12731
+ {
12714
12732
  const { getLocalProviderConfig: getLocalProviderConfig2 } = await Promise.resolve().then(() => (init_local(), local_exports));
12715
12733
  if (getLocalProviderConfig2()) {
12716
12734
  const { runLocalCommit: runLocalCommit2 } = await Promise.resolve().then(() => (init_local(), local_exports));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quikcommit/cli",
3
- "version": "13.0.0",
3
+ "version": "13.2.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": "10.0.0"
37
+ "@quikcommit/shared": "10.1.0"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "node build.mjs",