@quikcommit/cli 1.0.1 → 2.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 (3) hide show
  1. package/README.md +7 -7
  2. package/dist/index.js +407 -44
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -21,7 +21,7 @@ npm install -g @quikcommit/cli
21
21
  bun add -g @quikcommit/cli
22
22
  ```
23
23
 
24
- **Pre-built binaries** (no Node/Bun required) — download from [GitHub Releases](https://github.com/whrit/quikcommit/releases/latest):
24
+ **Pre-built binaries** (no Node/Bun required) — download from [GitHub Releases](https://github.com/Quikcommit-Internal/public/releases/latest):
25
25
 
26
26
  | Platform | File |
27
27
  |----------|------|
@@ -32,7 +32,7 @@ bun add -g @quikcommit/cli
32
32
 
33
33
  ```bash
34
34
  # Example: macOS Apple Silicon
35
- curl -fsSL https://github.com/whrit/quikcommit/releases/latest/download/qc-darwin-arm64 \
35
+ curl -fsSL https://github.com/Quikcommit-Internal/public/releases/latest/download/qc-darwin-arm64 \
36
36
  -o /usr/local/bin/qc && chmod +x /usr/local/bin/qc
37
37
  ```
38
38
 
@@ -229,11 +229,11 @@ Credentials are stored separately at `~/.config/qc/credentials` (mode 600).
229
229
 
230
230
  ## Links
231
231
 
232
- - [GitHub](https://github.com/whrit/quikcommit)
233
- - [Full Documentation](https://github.com/whrit/quikcommit/tree/main/docs)
234
- - [Getting Started](https://github.com/whrit/quikcommit/blob/main/docs/getting-started.md)
235
- - [CLI Reference](https://github.com/whrit/quikcommit/blob/main/docs/cli-reference.md)
236
- - [Local Providers](https://github.com/whrit/quikcommit/blob/main/docs/local-providers.md)
232
+ - [GitHub](https://github.com/Quikcommit-Internal/public)
233
+ - [Full Documentation](https://github.com/Quikcommit-Internal/public/tree/main/docs)
234
+ - [Getting Started](https://github.com/Quikcommit-Internal/public/blob/main/docs/getting-started.md)
235
+ - [CLI Reference](https://github.com/Quikcommit-Internal/public/blob/main/docs/cli-reference.md)
236
+ - [Local Providers](https://github.com/Quikcommit-Internal/public/blob/main/docs/local-providers.md)
237
237
 
238
238
  ---
239
239
 
package/dist/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
3
2
  "use strict";
4
3
  var __create = Object.create;
5
4
  var __defProp = Object.defineProperty;
@@ -186,6 +185,13 @@ var init_api = __esm({
186
185
  );
187
186
  return { message: data.message ?? "" };
188
187
  }
188
+ async generateChangeset(req) {
189
+ const data = await this.request("/v1/changeset", req);
190
+ return {
191
+ packages: data.packages ?? [],
192
+ summary: data.summary ?? ""
193
+ };
194
+ }
189
195
  async fetchJson(endpoint, options) {
190
196
  if (!this.apiKey) {
191
197
  throw new Error("Not authenticated. Run `qc login` first.");
@@ -344,6 +350,32 @@ function getCommitsSince(ref, to = "HEAD") {
344
350
  return { hash: hash ?? "", subject: rest.join(" ").trim() };
345
351
  });
346
352
  }
353
+ function getChangedFilesSince(base = "main") {
354
+ validateRef(base, "base");
355
+ const output = (0, import_child_process.execFileSync)("git", ["diff", `${base}..HEAD`, "--name-only"], {
356
+ encoding: "utf-8",
357
+ maxBuffer: 10 * 1024 * 1024
358
+ });
359
+ return output.trim().split("\n").filter(Boolean);
360
+ }
361
+ function getOnlineLog(base = "main") {
362
+ validateRef(base, "base");
363
+ return (0, import_child_process.execFileSync)(
364
+ "git",
365
+ ["log", `${base}..HEAD`, "--oneline", "--max-count=200"],
366
+ {
367
+ encoding: "utf-8",
368
+ maxBuffer: 5 * 1024 * 1024
369
+ }
370
+ ).trim();
371
+ }
372
+ function getFullDiff(base = "main") {
373
+ validateRef(base, "base");
374
+ return (0, import_child_process.execFileSync)("git", ["diff", `${base}..HEAD`], {
375
+ encoding: "utf-8",
376
+ maxBuffer: 10 * 1024 * 1024
377
+ });
378
+ }
347
379
  var import_child_process, import_fs2, import_path2, import_os2, SAFE_GIT_REF;
348
380
  var init_git = __esm({
349
381
  "src/git.ts"() {
@@ -357,6 +389,12 @@ var init_git = __esm({
357
389
  });
358
390
 
359
391
  // src/monorepo.ts
392
+ var monorepo_exports = {};
393
+ __export(monorepo_exports, {
394
+ autoDetectScope: () => autoDetectScope,
395
+ detectWorkspace: () => detectWorkspace,
396
+ getPackageForFile: () => getPackageForFile
397
+ });
360
398
  function findGitRoot(start) {
361
399
  try {
362
400
  return (0, import_child_process2.execFileSync)("git", ["rev-parse", "--show-toplevel"], {
@@ -440,10 +478,18 @@ function matchGlobPattern(rel, pattern) {
440
478
  return null;
441
479
  }
442
480
  const prefix = dir + "/";
443
- if (rel.startsWith(prefix)) {
444
- const rest = rel.slice(prefix.length);
445
- const pkg = rest.split("/")[0];
446
- return pkg || null;
481
+ const hasGlob = /\*/.test(pattern);
482
+ if (hasGlob) {
483
+ if (rel.startsWith(prefix)) {
484
+ const rest = rel.slice(prefix.length);
485
+ const pkg = rest.split("/")[0];
486
+ return pkg || null;
487
+ }
488
+ } else {
489
+ if (rel === dir || rel.startsWith(prefix)) {
490
+ const segments = dir.split("/").filter(Boolean);
491
+ return segments[segments.length - 1] ?? null;
492
+ }
447
493
  }
448
494
  return null;
449
495
  }
@@ -734,6 +780,312 @@ var init_changelog = __esm({
734
780
  }
735
781
  });
736
782
 
783
+ // src/commands/changeset.ts
784
+ var changeset_exports = {};
785
+ __export(changeset_exports, {
786
+ changeset: () => changeset,
787
+ formatChangesetFile: () => formatChangesetFile,
788
+ generateSlug: () => generateSlug,
789
+ mapFilesToPackages: () => mapFilesToPackages
790
+ });
791
+ function generateSlug() {
792
+ const pick = (arr) => arr[Math.floor(Math.random() * arr.length)];
793
+ return `${pick(ADJECTIVES)}-${pick(ANIMALS)}-${pick(VERBS)}`;
794
+ }
795
+ function mapFilesToPackages(files, workspace) {
796
+ const dirToName = /* @__PURE__ */ new Map();
797
+ for (const file of files) {
798
+ const dirName = getPackageForFile(file, workspace);
799
+ if (!dirName || dirToName.has(dirName)) continue;
800
+ for (const pattern of workspace.packages) {
801
+ const hasGlob = /\*/.test(pattern);
802
+ const dir = pattern.replace(/\/?\*\*?$/, "").replace(/\/$/, "");
803
+ const pkgJsonPath = hasGlob ? (0, import_path5.join)(workspace.root, dir, dirName, "package.json") : (0, import_path5.join)(workspace.root, pattern.replace(/\/$/, ""), "package.json");
804
+ try {
805
+ const pkg = JSON.parse((0, import_fs5.readFileSync)(pkgJsonPath, "utf-8"));
806
+ dirToName.set(dirName, pkg.name ?? dirName);
807
+ break;
808
+ } catch {
809
+ }
810
+ }
811
+ if (!dirToName.has(dirName)) {
812
+ dirToName.set(dirName, dirName);
813
+ }
814
+ }
815
+ return dirToName;
816
+ }
817
+ function formatChangesetFile(packages, summary) {
818
+ const frontmatter = packages.map((p) => `"${p.name}": ${p.bump}`).join("\n");
819
+ return `---
820
+ ${frontmatter}
821
+ ---
822
+
823
+ ${summary}
824
+ `;
825
+ }
826
+ async function prompt(rl, question) {
827
+ return new Promise((resolve) => rl.question(question, resolve));
828
+ }
829
+ async function changeset(options) {
830
+ const base = options.base ?? "main";
831
+ const apiKey = getApiKey();
832
+ if (!apiKey) {
833
+ console.error("Error: Not authenticated. Run `qc login` first.");
834
+ process.exit(1);
835
+ }
836
+ const { detectWorkspace: detectWorkspace2 } = await Promise.resolve().then(() => (init_monorepo(), monorepo_exports));
837
+ const workspace = detectWorkspace2();
838
+ if (!workspace) {
839
+ console.error(
840
+ "No workspace packages found. Is this a pnpm monorepo?"
841
+ );
842
+ process.exit(1);
843
+ }
844
+ const changedFiles = getChangedFilesSince(base);
845
+ if (changedFiles.length === 0) {
846
+ console.error(`No changes detected vs ${base}.`);
847
+ process.exit(1);
848
+ }
849
+ const packageMap = mapFilesToPackages(changedFiles, workspace);
850
+ const packageNames = Array.from(packageMap.values());
851
+ if (packageNames.length === 0) {
852
+ console.error("No workspace packages detected in changed files.");
853
+ process.exit(1);
854
+ }
855
+ const commits = getOnlineLog(base);
856
+ const diff = getFullDiff(base);
857
+ const commitCount = commits.split("\n").filter(Boolean).length;
858
+ console.error(
859
+ `Analyzing changes vs ${base}... ${commitCount} commit(s), ${packageNames.length} package(s) changed`
860
+ );
861
+ const client = new ApiClient({ apiKey });
862
+ let result;
863
+ const msg = (e) => e instanceof Error ? e.message : String(e);
864
+ const isTransient = (m) => /invalid json|no changeset|unexpected response|ai worker|timeout|502|503|504/i.test(m);
865
+ let attempts = 0;
866
+ while (true) {
867
+ try {
868
+ result = await client.generateChangeset({
869
+ diff,
870
+ packages: packageNames,
871
+ commits,
872
+ model: options.model
873
+ });
874
+ break;
875
+ } catch (err) {
876
+ const m = msg(err);
877
+ if (!isTransient(m)) {
878
+ console.error(m);
879
+ process.exit(1);
880
+ }
881
+ if (attempts === 0) {
882
+ attempts++;
883
+ continue;
884
+ }
885
+ console.error(m);
886
+ process.exit(1);
887
+ }
888
+ }
889
+ const resultNames = new Set(result.packages.map((p) => p.name));
890
+ for (const name of packageNames) {
891
+ if (!resultNames.has(name)) {
892
+ result.packages.push({ name, bump: "patch", reason: "included in changeset" });
893
+ }
894
+ }
895
+ console.log("");
896
+ for (const pkg of result.packages) {
897
+ console.log(` ${pkg.name.padEnd(32)} ${pkg.bump.padEnd(7)} \u2014 ${pkg.reason}`);
898
+ }
899
+ console.log("");
900
+ console.log(`Summary: ${result.summary}`);
901
+ console.log("");
902
+ const rl = readline.createInterface({
903
+ input: process.stdin,
904
+ output: process.stdout
905
+ });
906
+ try {
907
+ const answer = (await prompt(rl, "Accept all? [Y/n/edit] > ")).trim().toLowerCase();
908
+ if (answer === "n") {
909
+ console.error("Aborted.");
910
+ process.exit(0);
911
+ }
912
+ if (answer === "edit") {
913
+ for (let i = 0; i < result.packages.length; i++) {
914
+ const pkg = result.packages[i];
915
+ const response = (await prompt(rl, ` ${pkg.name} [${pkg.bump}]: major/minor/patch? > `)).trim().toLowerCase();
916
+ if (response === "major" || response === "minor" || response === "patch") {
917
+ result.packages[i] = { ...pkg, bump: response };
918
+ }
919
+ }
920
+ }
921
+ } finally {
922
+ rl.close();
923
+ }
924
+ const slug = generateSlug();
925
+ const gitRoot = getGitRoot();
926
+ const changesetDir = (0, import_path5.join)(gitRoot, ".changeset");
927
+ if (!(0, import_fs5.existsSync)(changesetDir)) {
928
+ (0, import_fs5.mkdirSync)(changesetDir, { recursive: true });
929
+ }
930
+ const filePath = (0, import_path5.join)(changesetDir, `${slug}.md`);
931
+ const content = formatChangesetFile(result.packages, result.summary);
932
+ (0, import_fs5.writeFileSync)(filePath, content, "utf-8");
933
+ console.log(`
934
+ \u2713 Written .changeset/${slug}.md`);
935
+ }
936
+ var import_fs5, import_path5, readline, ADJECTIVES, ANIMALS, VERBS;
937
+ var init_changeset = __esm({
938
+ "src/commands/changeset.ts"() {
939
+ "use strict";
940
+ import_fs5 = require("fs");
941
+ import_path5 = require("path");
942
+ readline = __toESM(require("readline"));
943
+ init_config();
944
+ init_api();
945
+ init_git();
946
+ init_monorepo();
947
+ ADJECTIVES = [
948
+ "bouncy",
949
+ "brave",
950
+ "calm",
951
+ "clean",
952
+ "cool",
953
+ "damp",
954
+ "epic",
955
+ "fair",
956
+ "fast",
957
+ "firm",
958
+ "flat",
959
+ "free",
960
+ "glad",
961
+ "gold",
962
+ "good",
963
+ "gray",
964
+ "huge",
965
+ "keen",
966
+ "kind",
967
+ "lazy",
968
+ "lean",
969
+ "lush",
970
+ "mild",
971
+ "neat",
972
+ "nice",
973
+ "noble",
974
+ "pure",
975
+ "rare",
976
+ "rich",
977
+ "safe",
978
+ "sharp",
979
+ "slim",
980
+ "slow",
981
+ "soft",
982
+ "swift",
983
+ "tall",
984
+ "tame",
985
+ "tidy",
986
+ "tiny",
987
+ "tough",
988
+ "trim",
989
+ "true",
990
+ "vast",
991
+ "warm",
992
+ "wild",
993
+ "wise"
994
+ ];
995
+ ANIMALS = [
996
+ "ant",
997
+ "bear",
998
+ "bee",
999
+ "bird",
1000
+ "bug",
1001
+ "cat",
1002
+ "crab",
1003
+ "crow",
1004
+ "deer",
1005
+ "dog",
1006
+ "dove",
1007
+ "duck",
1008
+ "elk",
1009
+ "fish",
1010
+ "frog",
1011
+ "goat",
1012
+ "hawk",
1013
+ "lamb",
1014
+ "lark",
1015
+ "lion",
1016
+ "lynx",
1017
+ "mole",
1018
+ "moth",
1019
+ "mule",
1020
+ "owl",
1021
+ "pony",
1022
+ "puma",
1023
+ "raven",
1024
+ "slug",
1025
+ "snail",
1026
+ "swan",
1027
+ "toad",
1028
+ "vole",
1029
+ "wasp",
1030
+ "wolf",
1031
+ "wren",
1032
+ "yak"
1033
+ ];
1034
+ VERBS = [
1035
+ "bite",
1036
+ "bolt",
1037
+ "burn",
1038
+ "buzz",
1039
+ "call",
1040
+ "cast",
1041
+ "chase",
1042
+ "chew",
1043
+ "claw",
1044
+ "climb",
1045
+ "crawl",
1046
+ "dart",
1047
+ "dash",
1048
+ "dive",
1049
+ "draw",
1050
+ "drift",
1051
+ "drop",
1052
+ "eat",
1053
+ "fall",
1054
+ "find",
1055
+ "flee",
1056
+ "flip",
1057
+ "flow",
1058
+ "fly",
1059
+ "glow",
1060
+ "gnaw",
1061
+ "growl",
1062
+ "howl",
1063
+ "hunt",
1064
+ "jump",
1065
+ "kick",
1066
+ "leap",
1067
+ "lick",
1068
+ "lift",
1069
+ "lurk",
1070
+ "pace",
1071
+ "peck",
1072
+ "play",
1073
+ "race",
1074
+ "roam",
1075
+ "roar",
1076
+ "roll",
1077
+ "run",
1078
+ "skim",
1079
+ "sniff",
1080
+ "soar",
1081
+ "spin",
1082
+ "swim",
1083
+ "wade",
1084
+ "walk"
1085
+ ];
1086
+ }
1087
+ });
1088
+
737
1089
  // src/commands/init.ts
738
1090
  var init_exports = {};
739
1091
  __export(init_exports, {
@@ -749,12 +1101,12 @@ async function init(options) {
749
1101
  console.error("Error: Not a git repository");
750
1102
  process.exit(1);
751
1103
  }
752
- const hookPath = (0, import_path5.join)(hooksDir, "prepare-commit-msg");
1104
+ const hookPath = (0, import_path6.join)(hooksDir, "prepare-commit-msg");
753
1105
  if (options.uninstall) {
754
- if ((0, import_fs5.existsSync)(hookPath)) {
755
- const content = (0, import_fs5.readFileSync)(hookPath, "utf-8");
1106
+ if ((0, import_fs6.existsSync)(hookPath)) {
1107
+ const content = (0, import_fs6.readFileSync)(hookPath, "utf-8");
756
1108
  if (content.includes("QuikCommit")) {
757
- (0, import_fs5.unlinkSync)(hookPath);
1109
+ (0, import_fs6.unlinkSync)(hookPath);
758
1110
  console.log("QuikCommit hook removed.");
759
1111
  } else {
760
1112
  console.log("Hook exists but was not installed by QuikCommit. Skipping.");
@@ -764,8 +1116,8 @@ async function init(options) {
764
1116
  }
765
1117
  return;
766
1118
  }
767
- if ((0, import_fs5.existsSync)(hookPath)) {
768
- const content = (0, import_fs5.readFileSync)(hookPath, "utf-8");
1119
+ if ((0, import_fs6.existsSync)(hookPath)) {
1120
+ const content = (0, import_fs6.readFileSync)(hookPath, "utf-8");
769
1121
  if (content.includes("QuikCommit")) {
770
1122
  console.log("QuikCommit hook is already installed.");
771
1123
  return;
@@ -775,17 +1127,17 @@ async function init(options) {
775
1127
  );
776
1128
  process.exit(1);
777
1129
  }
778
- (0, import_fs5.writeFileSync)(hookPath, HOOK_CONTENT);
779
- (0, import_fs5.chmodSync)(hookPath, 493);
1130
+ (0, import_fs6.writeFileSync)(hookPath, HOOK_CONTENT);
1131
+ (0, import_fs6.chmodSync)(hookPath, 493);
780
1132
  console.log("QuikCommit hook installed.");
781
1133
  console.log("Now just run `git commit` and a message will be generated automatically.");
782
1134
  }
783
- var import_fs5, import_path5, import_child_process5, HOOK_CONTENT;
1135
+ var import_fs6, import_path6, import_child_process5, HOOK_CONTENT;
784
1136
  var init_init = __esm({
785
1137
  "src/commands/init.ts"() {
786
1138
  "use strict";
787
- import_fs5 = require("fs");
788
- import_path5 = require("path");
1139
+ import_fs6 = require("fs");
1140
+ import_path6 = require("path");
789
1141
  import_child_process5 = require("child_process");
790
1142
  HOOK_CONTENT = `#!/bin/sh
791
1143
  # QuikCommit - auto-generate commit messages
@@ -860,10 +1212,10 @@ function detectLocalCommitlintRules() {
860
1212
  "commitlint.config.mjs"
861
1213
  ];
862
1214
  for (const file of files) {
863
- const path = (0, import_path6.join)(cwd, file);
864
- if (!(0, import_fs6.existsSync)(path)) continue;
1215
+ const path = (0, import_path7.join)(cwd, file);
1216
+ if (!(0, import_fs7.existsSync)(path)) continue;
865
1217
  try {
866
- const content = (0, import_fs6.readFileSync)(path, "utf-8");
1218
+ const content = (0, import_fs7.readFileSync)(path, "utf-8");
867
1219
  let parsed;
868
1220
  if (file.endsWith(".json") || file === ".commitlintrc") {
869
1221
  parsed = JSON.parse(content);
@@ -875,10 +1227,10 @@ function detectLocalCommitlintRules() {
875
1227
  } catch {
876
1228
  }
877
1229
  }
878
- const pkgPath = (0, import_path6.join)(cwd, "package.json");
879
- if ((0, import_fs6.existsSync)(pkgPath)) {
1230
+ const pkgPath = (0, import_path7.join)(cwd, "package.json");
1231
+ if ((0, import_fs7.existsSync)(pkgPath)) {
880
1232
  try {
881
- const content = (0, import_fs6.readFileSync)(pkgPath, "utf-8");
1233
+ const content = (0, import_fs7.readFileSync)(pkgPath, "utf-8");
882
1234
  const pkg = JSON.parse(content);
883
1235
  if (pkg.commitlint) {
884
1236
  const rules = mapCommitlintToRules(pkg.commitlint);
@@ -941,12 +1293,12 @@ async function team(subcommand, args) {
941
1293
  process.exit(1);
942
1294
  }
943
1295
  }
944
- var import_fs6, import_path6;
1296
+ var import_fs7, import_path7;
945
1297
  var init_team = __esm({
946
1298
  "src/commands/team.ts"() {
947
1299
  "use strict";
948
- import_fs6 = require("fs");
949
- import_path6 = require("path");
1300
+ import_fs7 = require("fs");
1301
+ import_path7 = require("path");
950
1302
  init_api();
951
1303
  init_config();
952
1304
  }
@@ -1072,9 +1424,9 @@ __export(local_exports, {
1072
1424
  });
1073
1425
  function getLegacyProvider() {
1074
1426
  try {
1075
- const p = (0, import_path7.join)(CONFIG_PATH2, "provider");
1076
- if ((0, import_fs7.existsSync)(p)) {
1077
- const v = (0, import_fs7.readFileSync)(p, "utf-8").trim().toLowerCase();
1427
+ const p = (0, import_path8.join)(CONFIG_PATH2, "provider");
1428
+ if ((0, import_fs8.existsSync)(p)) {
1429
+ const v = (0, import_fs8.readFileSync)(p, "utf-8").trim().toLowerCase();
1078
1430
  if (["ollama", "lmstudio", "openrouter", "custom", "cloudflare"].includes(v)) {
1079
1431
  return v;
1080
1432
  }
@@ -1085,9 +1437,9 @@ function getLegacyProvider() {
1085
1437
  }
1086
1438
  function getLegacyBaseUrl(provider) {
1087
1439
  try {
1088
- const p = (0, import_path7.join)(CONFIG_PATH2, "base_url");
1089
- if ((0, import_fs7.existsSync)(p)) {
1090
- return (0, import_fs7.readFileSync)(p, "utf-8").trim();
1440
+ const p = (0, import_path8.join)(CONFIG_PATH2, "base_url");
1441
+ if ((0, import_fs8.existsSync)(p)) {
1442
+ return (0, import_fs8.readFileSync)(p, "utf-8").trim();
1091
1443
  }
1092
1444
  } catch {
1093
1445
  }
@@ -1095,9 +1447,9 @@ function getLegacyBaseUrl(provider) {
1095
1447
  }
1096
1448
  function getLegacyModel(provider) {
1097
1449
  try {
1098
- const p = (0, import_path7.join)(CONFIG_PATH2, "model");
1099
- if ((0, import_fs7.existsSync)(p)) {
1100
- const v = (0, import_fs7.readFileSync)(p, "utf-8").trim();
1450
+ const p = (0, import_path8.join)(CONFIG_PATH2, "model");
1451
+ if ((0, import_fs8.existsSync)(p)) {
1452
+ const v = (0, import_fs8.readFileSync)(p, "utf-8").trim();
1101
1453
  if (v) return v;
1102
1454
  }
1103
1455
  } catch {
@@ -1116,7 +1468,7 @@ function getLocalProviderConfig() {
1116
1468
  return { provider, baseUrl, model, apiKey };
1117
1469
  }
1118
1470
  function buildUserPrompt(changes, diff, rules) {
1119
- let prompt = `Generate a commit message for these changes:
1471
+ let prompt2 = `Generate a commit message for these changes:
1120
1472
 
1121
1473
  ## File changes:
1122
1474
  <file_changes>
@@ -1130,14 +1482,14 @@ ${diff}
1130
1482
 
1131
1483
  `;
1132
1484
  if (rules && Object.keys(rules).length > 0) {
1133
- prompt += `Rules: ${JSON.stringify(rules)}
1485
+ prompt2 += `Rules: ${JSON.stringify(rules)}
1134
1486
 
1135
1487
  `;
1136
1488
  }
1137
- prompt += `Important:
1489
+ prompt2 += `Important:
1138
1490
  - Follow conventional commit format: <type>(<scope>): <subject>
1139
1491
  - Response should be the commit message only, no explanations`;
1140
- return prompt;
1492
+ return prompt2;
1141
1493
  }
1142
1494
  function buildRequest(provider, baseUrl, userContent, diff, changes, model, apiKey, rules) {
1143
1495
  const headers = {
@@ -1147,7 +1499,7 @@ function buildRequest(provider, baseUrl, userContent, diff, changes, model, apiK
1147
1499
  headers["Authorization"] = `Bearer ${apiKey}`;
1148
1500
  }
1149
1501
  if (provider === "openrouter") {
1150
- headers["HTTP-Referer"] = "https://github.com/quikcommit/quikcommit";
1502
+ headers["HTTP-Referer"] = "https://github.com/Quikcommit-Internal/public";
1151
1503
  headers["X-Title"] = "qc - AI Commit Message Generator";
1152
1504
  }
1153
1505
  let url;
@@ -1284,18 +1636,18 @@ async function runLocalCommit(messageOnly, push, modelFlag) {
1284
1636
  gitPush();
1285
1637
  }
1286
1638
  }
1287
- var import_fs7, import_path7, import_os4, CONFIG_PATH2, PROVIDER_URLS, DEFAULT_MODELS;
1639
+ var import_fs8, import_path8, import_os4, CONFIG_PATH2, PROVIDER_URLS, DEFAULT_MODELS;
1288
1640
  var init_local = __esm({
1289
1641
  "src/local.ts"() {
1290
1642
  "use strict";
1291
- import_fs7 = require("fs");
1292
- import_path7 = require("path");
1643
+ import_fs8 = require("fs");
1644
+ import_path8 = require("path");
1293
1645
  import_os4 = require("os");
1294
1646
  init_config();
1295
1647
  init_dist();
1296
1648
  init_git();
1297
1649
  init_monorepo();
1298
- CONFIG_PATH2 = (0, import_path7.join)((0, import_os4.homedir)(), CONFIG_DIR);
1650
+ CONFIG_PATH2 = (0, import_path8.join)((0, import_os4.homedir)(), CONFIG_DIR);
1299
1651
  PROVIDER_URLS = {
1300
1652
  ollama: "http://localhost:11434",
1301
1653
  lmstudio: "http://localhost:1234/v1",
@@ -1326,6 +1678,7 @@ Usage:
1326
1678
  qc --push Commit and push to origin
1327
1679
  qc pr Generate PR description from branch commits
1328
1680
  qc changelog Generate changelog from commits since last tag
1681
+ qc changeset Automate pnpm changeset with AI
1329
1682
  qc init Install prepare-commit-msg hook for auto-generation
1330
1683
  qc login Sign in via browser
1331
1684
  qc logout Clear local credentials
@@ -1337,7 +1690,7 @@ Options:
1337
1690
  -m, --message-only Generate message only
1338
1691
  -p, --push Commit and push after generating
1339
1692
  --api-key <key> Use this API key (overrides credentials file)
1340
- --base <branch> Base branch for qc pr (default: main)
1693
+ --base <branch> Base branch for qc pr, qc changeset (default: main)
1341
1694
  --create Create PR with gh CLI after qc pr
1342
1695
  --from <ref> Start ref for qc changelog (default: latest tag)
1343
1696
  --to <ref> End ref for qc changelog (default: HEAD)
@@ -1411,6 +1764,8 @@ function parseArgs(args) {
1411
1764
  command = "config";
1412
1765
  } else if (arg === "upgrade") {
1413
1766
  command = "upgrade";
1767
+ } else if (arg === "changeset") {
1768
+ command = "changeset";
1414
1769
  } else if (arg === "--model" && i + 1 < args.length) {
1415
1770
  model = args[++i];
1416
1771
  } else if (arg === "--local" || arg === "--use-ollama" || arg === "--use-lmstudio" || arg === "--use-openrouter" || arg === "--use-cloudflare") {
@@ -1535,6 +1890,14 @@ async function main() {
1535
1890
  });
1536
1891
  return;
1537
1892
  }
1893
+ if (command === "changeset") {
1894
+ const { changeset: changeset2 } = await Promise.resolve().then(() => (init_changeset(), changeset_exports));
1895
+ await changeset2({
1896
+ base: values.base,
1897
+ model: values.model ?? getConfig().model
1898
+ });
1899
+ return;
1900
+ }
1538
1901
  if (command === "init") {
1539
1902
  const { init: init2 } = await Promise.resolve().then(() => (init_init(), init_exports));
1540
1903
  await init2({ uninstall: values.uninstall });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quikcommit/cli",
3
- "version": "1.0.1",
3
+ "version": "2.0.0",
4
4
  "description": "AI-powered conventional commit messages",
5
5
  "bin": {
6
6
  "qc": "./dist/index.js"
@@ -20,7 +20,7 @@
20
20
  "license": "MIT",
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "https://github.com/quikcommit/quikcommit"
23
+ "url": "https://github.com/Quikcommit-Internal/public"
24
24
  },
25
25
  "publishConfig": {
26
26
  "access": "public"
@@ -32,7 +32,7 @@
32
32
  "vitest": "~4.0.18"
33
33
  },
34
34
  "dependencies": {
35
- "@quikcommit/shared": "1.0.0"
35
+ "@quikcommit/shared": "2.0.0"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "node build.mjs",