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