opencommit 1.1.11 → 1.1.13

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 +4 -4
  2. package/out/cli.cjs +297 -46
  3. package/package.json +4 -2
package/README.md CHANGED
@@ -20,7 +20,7 @@ All the commits in this repo are done with OpenCommit — look into [the commits
20
20
 
21
21
  ## Setup
22
22
 
23
- 1. Install opencommit globally to use in any repository:
23
+ 1. Install OpenCommit globally to use in any repository:
24
24
 
25
25
  ```sh
26
26
  npm install -g opencommit
@@ -28,7 +28,7 @@ All the commits in this repo are done with OpenCommit — look into [the commits
28
28
 
29
29
  2. Get your API key from [OpenAI](https://platform.openai.com/account/api-keys). Make sure you add payment details, so API works.
30
30
 
31
- 3. Set the key to opencommit config:
31
+ 3. Set the key to OpenCommit config:
32
32
 
33
33
  ```sh
34
34
  opencommit config set OPENAI_API_KEY=<your_api_key>
@@ -38,7 +38,7 @@ All the commits in this repo are done with OpenCommit — look into [the commits
38
38
 
39
39
  ## Usage
40
40
 
41
- You can call `opencommit` directly to generate a commit message for your staged changes:
41
+ You can call OpenCommit directly to generate a commit message for your staged changes:
42
42
 
43
43
  ```sh
44
44
  git add <files...>
@@ -86,7 +86,7 @@ oc config set description=false
86
86
 
87
87
  ## Git hook
88
88
 
89
- You can set opencommit as Git [`prepare-commit-msg`](https://git-scm.com/docs/githooks#_prepare_commit_msg) hook. Hook integrates with you IDE Source Control and allows you edit the message before commit.
89
+ You can set OpenCommit as Git [`prepare-commit-msg`](https://git-scm.com/docs/githooks#_prepare_commit_msg) hook. Hook integrates with you IDE Source Control and allows you edit the message before commit.
90
90
 
91
91
  To set the hook:
92
92
 
package/out/cli.cjs CHANGED
@@ -75,13 +75,13 @@ var require_ini = __commonJS({
75
75
  const out = /* @__PURE__ */ Object.create(null);
76
76
  let p4 = out;
77
77
  let section = null;
78
- const re = /^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i;
78
+ const re2 = /^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i;
79
79
  const lines = str.split(/[\r\n]+/g);
80
80
  for (const line of lines) {
81
81
  if (!line || line.match(/^\s*[;#]/)) {
82
82
  continue;
83
83
  }
84
- const match = line.match(re);
84
+ const match = line.match(re2);
85
85
  if (!match) {
86
86
  continue;
87
87
  }
@@ -15482,7 +15482,7 @@ function G3(t, e2) {
15482
15482
  // package.json
15483
15483
  var package_default = {
15484
15484
  name: "opencommit",
15485
- version: "1.1.10",
15485
+ version: "1.1.12",
15486
15486
  description: "GPT CLI to auto-generate impressive commits in 1 second. Killing lame commits with AI \u{1F92F}\u{1F52B}",
15487
15487
  keywords: [
15488
15488
  "git",
@@ -15524,7 +15524,8 @@ var package_default = {
15524
15524
  dev: "ts-node ./src/cli.ts",
15525
15525
  build: "rimraf out && esbuild ./src/cli.ts --bundle --outfile=out/cli.cjs --format=cjs --platform=node",
15526
15526
  deploy: "npm run build && npm version patch && npm publish --tag latest",
15527
- lint: "eslint src --ext ts && tsc --noEmit"
15527
+ lint: "eslint src --ext ts && tsc --noEmit",
15528
+ format: "prettier --write src"
15528
15529
  },
15529
15530
  devDependencies: {
15530
15531
  "@types/ini": "^1.3.31",
@@ -15535,6 +15536,7 @@ var package_default = {
15535
15536
  dotenv: "^16.0.3",
15536
15537
  esbuild: "^0.15.18",
15537
15538
  eslint: "^8.28.0",
15539
+ prettier: "^2.8.4",
15538
15540
  "ts-node": "^10.9.1",
15539
15541
  typescript: "^4.9.3"
15540
15542
  },
@@ -15880,6 +15882,38 @@ var sD2 = class extends h2 {
15880
15882
  });
15881
15883
  }
15882
15884
  };
15885
+ var iD2 = class extends h2 {
15886
+ constructor(u2) {
15887
+ super(u2, false), this.cursor = 0, this.options = u2.options, this.value = [...u2.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: F4 }) => F4 === u2.cursorAt), 0), this.on("key", (F4) => {
15888
+ F4 === "a" && this.toggleAll();
15889
+ }), this.on("cursor", (F4) => {
15890
+ switch (F4) {
15891
+ case "left":
15892
+ case "up":
15893
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
15894
+ break;
15895
+ case "down":
15896
+ case "right":
15897
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
15898
+ break;
15899
+ case "space":
15900
+ this.toggleValue();
15901
+ break;
15902
+ }
15903
+ });
15904
+ }
15905
+ get _value() {
15906
+ return this.options[this.cursor].value;
15907
+ }
15908
+ toggleAll() {
15909
+ const u2 = this.value.length === this.options.length;
15910
+ this.value = u2 ? [] : this.options.map((F4) => F4.value);
15911
+ }
15912
+ toggleValue() {
15913
+ const u2 = this.value.includes(this._value);
15914
+ this.value = u2 ? this.value.filter((F4) => F4 !== this._value) : [...this.value, this._value];
15915
+ }
15916
+ };
15883
15917
  function aD2({ input: t = import_node_process.stdin, output: u2 = import_node_process.stdout, overwrite: F4 = true, hideCursor: e2 = true } = {}) {
15884
15918
  const s = f.createInterface({ input: t, output: u2, prompt: "", tabSize: 1 });
15885
15919
  f.emitKeypressEvents(t, s), t.isTTY && t.setRawMode(true);
@@ -15960,6 +15994,50 @@ ${import_picocolors.default.cyan(o)}
15960
15994
  }
15961
15995
  } }).prompt();
15962
15996
  };
15997
+ var re = (r2) => {
15998
+ const n = (s, t) => {
15999
+ const i2 = s.label ?? String(s.value);
16000
+ return t === "active" ? `${import_picocolors.default.cyan(_5)} ${i2} ${s.hint ? import_picocolors.default.dim(`(${s.hint})`) : ""}` : t === "selected" ? `${import_picocolors.default.green(y4)} ${import_picocolors.default.dim(i2)}` : t === "cancelled" ? `${import_picocolors.default.strikethrough(import_picocolors.default.dim(i2))}` : t === "active-selected" ? `${import_picocolors.default.green(y4)} ${i2} ${s.hint ? import_picocolors.default.dim(`(${s.hint})`) : ""}` : t === "submitted" ? `${import_picocolors.default.dim(i2)}` : `${import_picocolors.default.dim(A2)} ${import_picocolors.default.dim(i2)}`;
16001
+ };
16002
+ return new iD2({ options: r2.options, initialValues: r2.initialValues, required: r2.required ?? true, cursorAt: r2.cursorAt, validate(s) {
16003
+ if (this.required && s.length === 0)
16004
+ return `Please select at least one option.
16005
+ ${import_picocolors.default.reset(import_picocolors.default.dim(`Press ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" space ")))} to select, ${import_picocolors.default.gray(import_picocolors.default.bgWhite(import_picocolors.default.inverse(" enter ")))} to submit`))}`;
16006
+ }, render() {
16007
+ let s = `${import_picocolors.default.gray(a)}
16008
+ ${h3(this.state)} ${r2.message}
16009
+ `;
16010
+ switch (this.state) {
16011
+ case "submit":
16012
+ return `${s}${import_picocolors.default.gray(a)} ${this.options.filter(({ value: t }) => this.value.includes(t)).map((t) => n(t, "submitted")).join(import_picocolors.default.dim(", ")) || import_picocolors.default.dim("none")}`;
16013
+ case "cancel": {
16014
+ const t = this.options.filter(({ value: i2 }) => this.value.includes(i2)).map((i2) => n(i2, "cancelled")).join(import_picocolors.default.dim(", "));
16015
+ return `${s}${import_picocolors.default.gray(a)} ${t.trim() ? `${t}
16016
+ ${import_picocolors.default.gray(a)}` : ""}`;
16017
+ }
16018
+ case "error": {
16019
+ const t = this.error.split(`
16020
+ `).map((i2, c3) => c3 === 0 ? `${import_picocolors.default.yellow(o)} ${import_picocolors.default.yellow(i2)}` : ` ${i2}`).join(`
16021
+ `);
16022
+ return s + import_picocolors.default.yellow(a) + " " + this.options.map((i2, c3) => {
16023
+ const l = this.value.includes(i2.value), $4 = c3 === this.cursor;
16024
+ return $4 && l ? n(i2, "active-selected") : l ? n(i2, "selected") : n(i2, $4 ? "active" : "inactive");
16025
+ }).join(`
16026
+ ${import_picocolors.default.yellow(a)} `) + `
16027
+ ` + t + `
16028
+ `;
16029
+ }
16030
+ default:
16031
+ return `${s}${import_picocolors.default.cyan(a)} ${this.options.map((t, i2) => {
16032
+ const c3 = this.value.includes(t.value), l = i2 === this.cursor;
16033
+ return l && c3 ? n(t, "active-selected") : c3 ? n(t, "selected") : n(t, l ? "active" : "inactive");
16034
+ }).join(`
16035
+ ${import_picocolors.default.cyan(a)} `)}
16036
+ ${import_picocolors.default.cyan(o)}
16037
+ `;
16038
+ }
16039
+ } }).prompt();
16040
+ };
15963
16041
  var ae = (r2 = "") => {
15964
16042
  process.stdout.write(`${import_picocolors.default.gray(L5)} ${r2}
15965
16043
  `);
@@ -16471,6 +16549,100 @@ var chalk = createChalk();
16471
16549
  var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
16472
16550
  var source_default = chalk;
16473
16551
 
16552
+ // src/i18n/en.json
16553
+ var en_default = {
16554
+ localLanguage: "english",
16555
+ commitFix: "fix(server.ts): change port variable case from lowercase port to uppercase PORT",
16556
+ commitFeat: "feat(server.ts): add support for process.env.PORT environment variable",
16557
+ commitDescription: "The port variable is now named PORT, which improves consistency with the naming conventions as PORT is a constant. Support for an environment variable allows the application to be more flexible as it can now run on any available port specified via the process.env.PORT environment variable."
16558
+ };
16559
+
16560
+ // src/i18n/de.json
16561
+ var de_default = {
16562
+ localLanguage: "Deutsch",
16563
+ commitFix: "fix(server.ts): \xC4ndere die Gro\xDF- und Kleinschreibung der Port-Variable von Kleinbuchstaben auf Gro\xDFbuchstaben PORT.",
16564
+ commitFeat: "Funktion(server.ts): Unterst\xFCtzung f\xFCr die Umgebungsvariable process.env.PORT hinzuf\xFCgen",
16565
+ commitDescription: "Die Port-Variable hei\xDFt jetzt PORT, was die Konsistenz mit den Namenskonventionen verbessert, da PORT eine Konstante ist. Die Unterst\xFCtzung f\xFCr eine Umgebungsvariable erm\xF6glicht es der Anwendung, flexibler zu sein, da sie jetzt auf jedem verf\xFCgbaren Port laufen kann, der \xFCber die Umgebungsvariable process.env.PORT angegeben wird."
16566
+ };
16567
+
16568
+ // src/i18n/fr.json
16569
+ var fr_default = {
16570
+ localLanguage: "fran\xE7aise",
16571
+ commitFix: "corriger(server.ts) : changer la casse de la variable de port de minuscules \xE0 majuscules (PORT)",
16572
+ commitFeat: "fonctionnalit\xE9(server.ts) : ajouter la prise en charge de la variable d'environnement process.env.PORT",
16573
+ commitDescription: "La variable de port est maintenant nomm\xE9e PORT, ce qui am\xE9liore la coh\xE9rence avec les conventions de nommage car PORT est une constante. La prise en charge d'une variable d'environnement permet \xE0 l'application d'\xEAtre plus flexible car elle peut maintenant s'ex\xE9cuter sur n'importe quel port disponible sp\xE9cifi\xE9 via la variable d'environnement process.env.PORT."
16574
+ };
16575
+
16576
+ // src/i18n/it.json
16577
+ var it_default = {
16578
+ localLanguage: "italiano",
16579
+ commitFix: "fix(server.ts): cambia il caso della variabile di porta da minuscolo port a maiuscolo PORT",
16580
+ commitFeat: "funzionalit\xE0(server.ts): aggiungi supporto per la variabile di ambiente process.env.PORT",
16581
+ commitDescription: "La variabile di porta \xE8 ora chiamata PORT, il che migliora la coerenza con le convenzioni di denominazione in quanto PORT \xE8 una costante. Il supporto per una variabile di ambiente consente all'applicazione di essere pi\xF9 flessibile poich\xE9 ora pu\xF2 essere eseguita su qualsiasi porta disponibile specificata tramite la variabile di ambiente process.env.PORT."
16582
+ };
16583
+
16584
+ // src/i18n/ko.json
16585
+ var ko_default = {
16586
+ localLanguage: "\uD55C\uAD6D\uC5B4",
16587
+ commitFix: "fix(server.ts): \uD3EC\uD2B8 \uBCC0\uC218\uB97C \uC18C\uBB38\uC790 port\uC5D0\uC11C \uB300\uBB38\uC790 PORT\uB85C \uBCC0\uACBD",
16588
+ commitFeat: "\uD53C\uD2B8(server.ts): process.env.PORT \uD658\uACBD \uBCC0\uC218 \uC9C0\uC6D0 \uCD94\uAC00",
16589
+ commitDescription: "\uD3EC\uD2B8 \uBCC0\uC218\uB294 \uC774\uC81C PORT\uB85C \uC774\uB984\uC774 \uC9C0\uC815\uB418\uC5B4 \uC0C1\uC218\uC778 PORT\uC640 \uC77C\uAD00\uC131 \uC788\uB294 \uC774\uB984 \uADDC\uCE59\uC744 \uB530\uB985\uB2C8\uB2E4. \uD658\uACBD \uBCC0\uC218 \uC9C0\uC6D0\uC744 \uD1B5\uD574 \uC560\uD50C\uB9AC\uCF00\uC774\uC158\uC740 \uC774\uC81C process.env.PORT \uD658\uACBD \uBCC0\uC218\uB85C \uC9C0\uC815\uB41C \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBAA8\uB4E0 \uD3EC\uD2B8\uC5D0\uC11C \uC2E4\uD589\uD560 \uC218 \uC788\uC73C\uBBC0\uB85C \uB354 \uC720\uC5F0\uD574\uC84C\uC2B5\uB2C8\uB2E4."
16590
+ };
16591
+
16592
+ // src/i18n/zh_CN.json
16593
+ var zh_CN_default = {
16594
+ localLanguage: "\u7B80\u4F53\u4E2D\u6587",
16595
+ commitFix: "\u4FEE\u590D(server.ts)\uFF1A\u5C06\u7AEF\u53E3\u53D8\u91CF\u4ECE\u5C0F\u5199port\u6539\u4E3A\u5927\u5199PORT",
16596
+ commitFeat: "\u529F\u80FD(server.ts)\uFF1A\u6DFB\u52A0\u5BF9process.env.PORT\u73AF\u5883\u53D8\u91CF\u7684\u652F\u6301",
16597
+ commitDescription: "\u73B0\u5728\u7AEF\u53E3\u53D8\u91CF\u88AB\u547D\u540D\u4E3APORT\uFF0C\u8FD9\u63D0\u9AD8\u4E86\u547D\u540D\u7EA6\u5B9A\u7684\u4E00\u81F4\u6027\uFF0C\u56E0\u4E3APORT\u662F\u4E00\u4E2A\u5E38\u91CF\u3002\u73AF\u5883\u53D8\u91CF\u7684\u652F\u6301\u4F7F\u5E94\u7528\u7A0B\u5E8F\u66F4\u52A0\u7075\u6D3B\uFF0C\u56E0\u4E3A\u5B83\u73B0\u5728\u53EF\u4EE5\u901A\u8FC7process.env.PORT\u73AF\u5883\u53D8\u91CF\u5728\u4EFB\u4F55\u53EF\u7528\u7AEF\u53E3\u4E0A\u8FD0\u884C\u3002"
16598
+ };
16599
+
16600
+ // src/i18n/zh_TW.json
16601
+ var zh_TW_default = {
16602
+ localLanguage: "\u7E41\u9AD4\u4E2D\u6587",
16603
+ commitFix: "\u4FEE\u6B63(server.ts)\uFF1A\u5C07\u7AEF\u53E3\u8B8A\u6578\u5F9E\u5C0F\u5BEB\u7AEF\u53E3\u6539\u70BA\u5927\u5BEBPORT",
16604
+ commitFeat: "\u529F\u80FD(server.ts)\uFF1A\u65B0\u589E\u5C0Dprocess.env.PORT\u74B0\u5883\u8B8A\u6578\u7684\u652F\u63F4",
16605
+ commitDescription: "\u73FE\u5728port\u8B8A\u6578\u5DF2\u66F4\u540D\u70BAPORT\uFF0C\u4EE5\u7B26\u5408\u547D\u540D\u6163\u4F8B\uFF0C\u56E0\u70BAPORT\u662F\u4E00\u500B\u5E38\u91CF\u3002\u652F\u63F4\u74B0\u5883\u8B8A\u6578\u53EF\u4EE5\u4F7F\u61C9\u7528\u7A0B\u5E8F\u66F4\u9748\u6D3B\uFF0C\u56E0\u70BA\u5B83\u73FE\u5728\u53EF\u4EE5\u901A\u904Eprocess.env.PORT\u74B0\u5883\u8B8A\u6578\u904B\u884C\u5728\u4EFB\u4F55\u53EF\u7528\u7AEF\u53E3\u4E0A\u3002"
16606
+ };
16607
+
16608
+ // src/i18n/ja.json
16609
+ var ja_default = {
16610
+ localLanguage: "\u306B\u307B\u3093\u3054",
16611
+ commitFix: "\u4FEE\u6B63(server.ts): \u30DD\u30FC\u30C8\u5909\u6570\u306E\u30B1\u30FC\u30B9\u3092\u5C0F\u6587\u5B57\u306E\u30DD\u30FC\u30C8\u304B\u3089\u5927\u6587\u5B57\u306EPORT\u306B\u5909\u66F4",
16612
+ commitFeat: "\u65B0\u6A5F\u80FD(server.ts): process.env.PORT\u74B0\u5883\u5909\u6570\u306E\u30B5\u30DD\u30FC\u30C8\u3092\u8FFD\u52A0\u3059\u308B",
16613
+ commitDescription: "\u30DD\u30FC\u30C8\u5909\u6570\u306F\u73FE\u5728PORT\u3068\u3044\u3046\u540D\u524D\u306B\u306A\u3063\u3066\u304A\u308A\u3001PORT\u306F\u5B9A\u6570\u3067\u3042\u308B\u305F\u3081\u547D\u540D\u898F\u5247\u306B\u4E00\u8CAB\u6027\u304C\u3042\u308A\u307E\u3059\u3002\u74B0\u5883\u5909\u6570\u306E\u30B5\u30DD\u30FC\u30C8\u306B\u3088\u308A\u3001\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306F\u3088\u308A\u67D4\u8EDF\u306B\u306A\u308A\u3001process.env.PORT\u74B0\u5883\u5909\u6570\u3067\u6307\u5B9A\u3055\u308C\u305F\u4EFB\u610F\u306E\u5229\u7528\u53EF\u80FD\u306A\u30DD\u30FC\u30C8\u3067\u5B9F\u884C\u3067\u304D\u308B\u3088\u3046\u306B\u306A\u308A\u307E\u3057"
16614
+ };
16615
+
16616
+ // src/i18n/index.ts
16617
+ var i18n = {
16618
+ en: en_default,
16619
+ zh_CN: zh_CN_default,
16620
+ zh_TW: zh_TW_default,
16621
+ ja: ja_default,
16622
+ de: de_default,
16623
+ fr: fr_default,
16624
+ it: it_default,
16625
+ ko: ko_default
16626
+ };
16627
+ var I18N_CONFIG_ALIAS = {
16628
+ zh_CN: ["zh_CN", "\u7B80\u4F53\u4E2D\u6587", "\u4E2D\u6587", "\u7B80\u4F53"],
16629
+ zh_TW: ["zh_TW", "\u7E41\u9AD4\u4E2D\u6587", "\u7E41\u9AD4"],
16630
+ ja: ["ja", "Japanese", "\u306B\u307B\u3093\u3054"],
16631
+ ko: ["ko", "Korean", "\uD55C\uAD6D\uC5B4"],
16632
+ de: ["de", "German", "Deutsch"],
16633
+ fr: ["fr", "French", "fran\xE7aise"],
16634
+ it: ["it", "Italian", "italiano"]
16635
+ };
16636
+ function getI18nLocal(value) {
16637
+ for (const key in I18N_CONFIG_ALIAS) {
16638
+ const aliases2 = I18N_CONFIG_ALIAS[key];
16639
+ if (aliases2.includes(value)) {
16640
+ return key;
16641
+ }
16642
+ }
16643
+ return false;
16644
+ }
16645
+
16474
16646
  // src/commands/config.ts
16475
16647
  var validateConfig = (key, condition, validationMessage) => {
16476
16648
  if (!condition) {
@@ -16510,6 +16682,14 @@ var configValidators = {
16510
16682
  "Must be true or false"
16511
16683
  );
16512
16684
  return value;
16685
+ },
16686
+ ["language" /* language */](value) {
16687
+ validateConfig(
16688
+ "language" /* language */,
16689
+ getI18nLocal(value),
16690
+ `${value} is not supported yet`
16691
+ );
16692
+ return getI18nLocal(value);
16513
16693
  }
16514
16694
  };
16515
16695
  var configPath = (0, import_path.join)((0, import_os.homedir)(), ".opencommit");
@@ -17498,32 +17678,55 @@ var assertGitRepo = async () => {
17498
17678
  throw new Error(error);
17499
17679
  }
17500
17680
  };
17501
- var excludeBigFilesFromDiff = ["*-lock.*", "*.lock"].map(
17502
- (file) => `:(exclude)${file}`
17503
- );
17504
- var getStagedGitDiff = async (isStageAllFlag = false) => {
17505
- if (isStageAllFlag) {
17506
- const stageAllSpinner = le();
17507
- stageAllSpinner.start("Staging all changes");
17508
- await execa("git", ["add", "."]);
17509
- stageAllSpinner.stop("Done");
17510
- }
17511
- const diffStaged = ["diff", "--staged"];
17681
+ var getStagedFiles = async () => {
17512
17682
  const { stdout: files } = await execa("git", [
17513
- ...diffStaged,
17683
+ "diff",
17514
17684
  "--name-only",
17515
- ...excludeBigFilesFromDiff
17685
+ "--cached"
17516
17686
  ]);
17517
17687
  if (!files)
17518
- return null;
17688
+ return [];
17689
+ return files.split("\n").sort();
17690
+ };
17691
+ var getChangedFiles = async () => {
17692
+ const { stdout: modified } = await execa("git", ["ls-files", "--modified"]);
17693
+ const { stdout: others } = await execa("git", [
17694
+ "ls-files",
17695
+ "--others",
17696
+ "--exclude-standard"
17697
+ ]);
17698
+ const files = [...modified.split("\n"), ...others.split("\n")].filter(
17699
+ (file) => !!file
17700
+ );
17701
+ return files.sort();
17702
+ };
17703
+ var gitAdd = async ({ files }) => {
17704
+ const gitAddSpinner = le();
17705
+ gitAddSpinner.start("Adding files to commit");
17706
+ await execa("git", ["add", ...files]);
17707
+ gitAddSpinner.stop("Done");
17708
+ };
17709
+ var getDiff = async ({ files }) => {
17710
+ const lockFiles = files.filter(
17711
+ (file) => file.includes(".lock") || file.includes("-lock.")
17712
+ );
17713
+ if (lockFiles.length) {
17714
+ ce(
17715
+ `Some files are '.lock' files which are excluded by default from 'git diff'. No commit messages are generated for this files:
17716
+ ${lockFiles.join(
17717
+ "\n"
17718
+ )}`
17719
+ );
17720
+ }
17721
+ const filesWithoutLocks = files.filter(
17722
+ (file) => !file.includes(".lock") && !file.includes("-lock.")
17723
+ );
17519
17724
  const { stdout: diff } = await execa("git", [
17520
- ...diffStaged,
17521
- ...excludeBigFilesFromDiff
17725
+ "diff",
17726
+ "--staged",
17727
+ ...filesWithoutLocks
17522
17728
  ]);
17523
- return {
17524
- files: files.split("\n").sort(),
17525
- diff
17526
- };
17729
+ return diff;
17527
17730
  };
17528
17731
 
17529
17732
  // src/commands/githook.ts
@@ -20480,10 +20683,11 @@ function mergeStrings(arr, maxStringLength) {
20480
20683
 
20481
20684
  // src/generateCommitMessageFromGitDiff.ts
20482
20685
  var config2 = getConfig();
20686
+ var translation = i18n[config2?.language || "en"];
20483
20687
  var INIT_MESSAGES_PROMPT = [
20484
20688
  {
20485
20689
  role: import_openai2.ChatCompletionRequestMessageRoleEnum.System,
20486
- content: `You are to act as the author of a commit message in git. Your mission is to create clean and comprehensive commit messages in the conventional commit convention. I'll send you an output of 'git diff --staged' command, and you convert it into a commit message. ${config2?.emoji ? "Use Gitmoji convention to preface the commit" : "Do not preface the commit with anything"}, use the present tense. ${config2?.description ? `Add a short description of what commit is about after the commit message. Don't start it with "This commit", just describe the changes.` : "Don't add any descriptions to the commit, only commit message."}`
20690
+ content: `You are to act as the author of a commit message in git. Your mission is to create clean and comprehensive commit messages in the conventional commit convention. I'll send you an output of 'git diff --staged' command, and you convert it into a commit message. ${config2?.emoji ? "Use Gitmoji convention to preface the commit" : "Do not preface the commit with anything"}, use the present tense. ${config2?.description ? `Add a short description of what commit is about after the commit message. Don't start it with "This commit", just describe the changes.` : "Don't add any descriptions to the commit, only commit message."} Use ${translation.localLanguage} to answer.}`
20487
20691
  },
20488
20692
  {
20489
20693
  role: import_openai2.ChatCompletionRequestMessageRoleEnum.User,
@@ -20512,9 +20716,9 @@ var INIT_MESSAGES_PROMPT = [
20512
20716
  },
20513
20717
  {
20514
20718
  role: import_openai2.ChatCompletionRequestMessageRoleEnum.Assistant,
20515
- content: `${config2?.emoji ? "\u{1F41B} " : ""}fix(server.ts): change port variable case from lowercase port to uppercase PORT
20516
- ${config2?.emoji ? "\u2728 " : ""}feat(server.ts): add support for process.env.PORT environment variable
20517
- ${config2?.description ? "The port variable is now named PORT, which improves consistency with the naming conventions as PORT is a constant. Support for an environment variable allows the application to be more flexible as it can now run on any available port specified via the process.env.PORT environment variable." : ""}`
20719
+ content: `${config2?.emoji ? "\u{1F41B} " : ""}${translation.commitFix}
20720
+ ${config2?.emoji ? "\u2728 " : ""}${translation.commitFeat}
20721
+ ${config2?.description ? translation.commitDescription : ""}`
20518
20722
  }
20519
20723
  ];
20520
20724
  var generateCommitMessageChatCompletionPrompt = (diff) => {
@@ -20592,7 +20796,14 @@ var prepareCommitMessageHook = async () => {
20592
20796
  }
20593
20797
  if (commitSource)
20594
20798
  return;
20595
- const staged = await getStagedGitDiff();
20799
+ const changedFiles = await getChangedFiles();
20800
+ if (changedFiles)
20801
+ await gitAdd({ files: changedFiles });
20802
+ else {
20803
+ ce("No changes detected, write some code and run `oc` again");
20804
+ process.exit(1);
20805
+ }
20806
+ const staged = await getStagedFiles();
20596
20807
  if (!staged)
20597
20808
  return;
20598
20809
  ae("opencommit");
@@ -20603,7 +20814,7 @@ var prepareCommitMessageHook = async () => {
20603
20814
  );
20604
20815
  }
20605
20816
  const commitMessage = await generateCommitMessageWithChatCompletion(
20606
- staged.diff
20817
+ await getDiff({ files: staged })
20607
20818
  );
20608
20819
  if (typeof commitMessage !== "string")
20609
20820
  throw new Error(commitMessage.error);
@@ -20618,6 +20829,18 @@ var prepareCommitMessageHook = async () => {
20618
20829
  }
20619
20830
  };
20620
20831
 
20832
+ // src/utils/trytm.ts
20833
+ var trytm = async (promise) => {
20834
+ try {
20835
+ const data = await promise;
20836
+ return [data, null];
20837
+ } catch (throwable) {
20838
+ if (throwable instanceof Error)
20839
+ return [null, throwable];
20840
+ throw throwable;
20841
+ }
20842
+ };
20843
+
20621
20844
  // src/commands/commit.ts
20622
20845
  var generateCommitMessageFromGitDiff = async (diff) => {
20623
20846
  await assertGitRepo();
@@ -20662,36 +20885,64 @@ ${source_default.grey("\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2
20662
20885
  ce(`${source_default.gray("\u2716")} process cancelled`);
20663
20886
  };
20664
20887
  async function commit(isStageAllFlag = false) {
20888
+ if (isStageAllFlag) {
20889
+ const changedFiles2 = await getChangedFiles();
20890
+ if (changedFiles2)
20891
+ await gitAdd({ files: changedFiles2 });
20892
+ else {
20893
+ ce("No changes detected, write some code and run `oc` again");
20894
+ process.exit(1);
20895
+ }
20896
+ }
20897
+ const [stagedFiles, errorStagedFiles] = await trytm(getStagedFiles());
20898
+ const [changedFiles, errorChangedFiles] = await trytm(getChangedFiles());
20899
+ if (!changedFiles?.length && !stagedFiles?.length) {
20900
+ ce(source_default.red("No changes detected"));
20901
+ process.exit(1);
20902
+ }
20665
20903
  ae("open-commit");
20666
- const stagedFilesSpinner = le();
20667
- stagedFilesSpinner.start("Counting staged files");
20668
- const staged = await getStagedGitDiff(isStageAllFlag);
20669
- if (!staged && isStageAllFlag) {
20670
- ce(
20671
- `${source_default.red(
20672
- "No changes detected"
20673
- )} \u2014 write some code, stage the files ${source_default.hex("0000FF").bold("`git add .`")} and rerun ${source_default.hex("0000FF").bold("`oc`")} command.`
20674
- );
20904
+ if (errorChangedFiles ?? errorStagedFiles) {
20905
+ ce(`${source_default.red("\u2716")} ${errorChangedFiles ?? errorStagedFiles}`);
20675
20906
  process.exit(1);
20676
20907
  }
20677
- if (!staged) {
20678
- ce(
20679
- `${source_default.red("Nothing to commit")} \u2014 stage the files ${source_default.hex("0000FF").bold("`git add .`")} and rerun ${source_default.hex("0000FF").bold("`oc`")} command.`
20680
- );
20908
+ const stagedFilesSpinner = le();
20909
+ stagedFilesSpinner.start("Counting staged files");
20910
+ if (!stagedFiles.length) {
20681
20911
  stagedFilesSpinner.stop("No files are staged");
20682
20912
  const isStageAllAndCommitConfirmedByUser = await Q3({
20683
20913
  message: "Do you want to stage all files and generate commit message?"
20684
20914
  });
20685
20915
  if (isStageAllAndCommitConfirmedByUser && !eD2(isStageAllAndCommitConfirmedByUser)) {
20686
20916
  await commit(true);
20917
+ process.exit(1);
20687
20918
  }
20919
+ if (stagedFiles.length === 0 && changedFiles.length > 0) {
20920
+ const files = await re({
20921
+ message: source_default.cyan("Select the files you want to add to the commit:"),
20922
+ options: changedFiles.map((file) => ({
20923
+ value: file,
20924
+ label: file
20925
+ }))
20926
+ });
20927
+ if (eD2(files))
20928
+ process.exit(1);
20929
+ await gitAdd({ files });
20930
+ }
20931
+ await commit(false);
20688
20932
  process.exit(1);
20689
20933
  }
20690
20934
  stagedFilesSpinner.stop(
20691
- `${staged.files.length} staged files:
20692
- ${staged.files.map((file) => ` ${file}`).join("\n")}`
20935
+ `${stagedFiles.length} staged files:
20936
+ ${stagedFiles.map((file) => ` ${file}`).join("\n")}`
20693
20937
  );
20694
- await generateCommitMessageFromGitDiff(staged.diff);
20938
+ const [, generateCommitError] = await trytm(
20939
+ generateCommitMessageFromGitDiff(await getDiff({ files: stagedFiles }))
20940
+ );
20941
+ if (generateCommitError) {
20942
+ ce(`${source_default.red("\u2716")} ${generateCommitError}`);
20943
+ process.exit(1);
20944
+ }
20945
+ process.exit(0);
20695
20946
  }
20696
20947
 
20697
20948
  // src/cli.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencommit",
3
- "version": "1.1.11",
3
+ "version": "1.1.13",
4
4
  "description": "GPT CLI to auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫",
5
5
  "keywords": [
6
6
  "git",
@@ -42,7 +42,8 @@
42
42
  "dev": "ts-node ./src/cli.ts",
43
43
  "build": "rimraf out && esbuild ./src/cli.ts --bundle --outfile=out/cli.cjs --format=cjs --platform=node",
44
44
  "deploy": "npm run build && npm version patch && npm publish --tag latest",
45
- "lint": "eslint src --ext ts && tsc --noEmit"
45
+ "lint": "eslint src --ext ts && tsc --noEmit",
46
+ "format": "prettier --write src"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@types/ini": "^1.3.31",
@@ -53,6 +54,7 @@
53
54
  "dotenv": "^16.0.3",
54
55
  "esbuild": "^0.15.18",
55
56
  "eslint": "^8.28.0",
57
+ "prettier": "^2.8.4",
56
58
  "ts-node": "^10.9.1",
57
59
  "typescript": "^4.9.3"
58
60
  },