git-coco 0.7.5 → 0.7.6

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.
package/README.md CHANGED
@@ -6,123 +6,84 @@
6
6
  [![NPM Version](https://img.shields.io/npm/v/git-coco.svg)](https://www.npmjs.com/package/git-coco)
7
7
  [![NPM Downloads](https://img.shields.io/npm/dt/git-coco.svg)](https://www.npmjs.com/package/git-coco)
8
8
 
9
- Commit Copilot, or `coco`, is your personal scribe for git commit messages. Leveraging the power of [LangChain🦜🔗](https://js.langchain.com/) and LLMs to encapsulate your staged changes into meaningful commit messages!
9
+ `coco`, the Commit Copilot, is not just your scribe for git commit messages. With the power of [LangChain🦜🔗](https://js.langchain.com/) and LLMs, it now brings you a suite of tools to streamline your git workflow!
10
10
 
11
+ ## Commands
11
12
 
13
+ - **`commit`**: generates commit messages based on staged changes.
12
14
 
13
- ## Installation
15
+ - **`changelog`**: create changelogs for the current branch or a range of commits.
14
16
 
15
- Get started by adding `coco` to your project's development dependencies:
17
+ - **`init`**: step by step wizard to set up `coco` globally or for a project.
16
18
 
17
- ```bash
18
- npm i git-coco --save-dev
19
- ```
19
+ ## Getting Started
20
20
 
21
- Or, for global access, you can install `coco` system-wide:
21
+ **`coco init`** is the first step to getting started with `coco`. It will guide you through the installation process, including setting up your OpenAI API key and configuring `coco` to your preferences.
22
22
 
23
23
  ```bash
24
- npm i -g git-coco
24
+ # For local project use
25
+ npx git-coco@latest init -l project
26
+
27
+ # For global use
28
+ npx git-coco@latest init -l global
25
29
  ```
26
30
 
27
31
  ## Usage
28
32
 
29
- There are two main ways to use `coco`:
30
-
31
- 1. [Interactive Mode](#interactive)
32
- 2. [Command Line Interface (CLI)](#cli)
33
+ ### **`coco commit`**
33
34
 
34
- ### **Interactive Mode**
35
-
36
- Just type `coco` and let the friendly prompts guide you through the commit process!
35
+ Generates commit messages based on staged changes.
37
36
 
38
37
  ```bash
39
- coco -i
40
- ```
38
+ coco
41
39
 
42
- The interactive mode offers you several benefits:
40
+ # or
43
41
 
44
- - Preview and approve or regenerate the commit message before it's committed
45
- - Customize your prompts for a personalized commit experience
46
-
47
- ### **Command Line Interface (CLI)**
48
-
49
- If you're the type who likes to keep it simple, you can pass your commit message directly as a CLI argument:
50
-
51
- ```bash
52
- coco --openAIApiKey="sk_your-openai-api-key"
42
+ coco commit
53
43
  ```
54
44
 
55
- Assuming you've stored your API key in the config file ([learn more](#the-cococonfig)), you can also commit with:
56
-
57
- ```bash
58
- git commit -m $(coco)
59
- ```
45
+ ### **`coco changelog`**
60
46
 
61
- Alternatively, take advantage of `coco`'s full potential by allowing it to make the commit for you!
47
+ Creates changelogs.
62
48
 
63
49
  ```bash
64
- coco -s
65
- ```
50
+ # For the current branch
51
+ coco changelog
66
52
 
67
- ## **The `coco.config`**
53
+ # For a specific range
54
+ coco changelog -r HEAD~5:HEAD
55
+ ```
68
56
 
69
- `coco.config` houses the project-level settings and can be defined in multiple places, adhering to a hierarchical order of priority. If the same configuration is found in multiple places, the higher priority one will be considered.
70
57
 
71
- From highest to lowest, the priority order is:
58
+ ### Stdout vs. Interactive Mode
72
59
 
73
- 1. **Command Line Flags**: Flags in the command line have the highest priority, and they override all other settings.
74
- 2. **Environment Variables**: Next in line are environment variables. You can set any configuration option as an environment variable.
75
- 3. **Project Config (`.coco.config.json`)**: Create a `.coco.config.json` file in your project root to set configurations. It's recommended to store your OpenAI API key here alongside any other project-specific configurations.
76
- 4. **Git Profile (`.gitconfig`)**: You can define `coco` settings under a `[coco]` section in your git profile. These settings will be used unless overridden by higher-priority ones.
77
- 5. **XDG Configuration Directory**: If `XDG_CONFIG_HOME` is set, `coco` will look for a `coco/config` file in this directory for configurations.
60
+ `coco` offers two modes of operation: **stdout** and **interactive**, defaulting to **stdout**. You can specify your preferred mode in your config file or via command line flags.
78
61
 
79
- Here's an example `.coco.config.json` file:
62
+ ```bash
63
+ # Stdout mode
64
+ git commit -m $(coco)
80
65
 
81
- ```json
82
- {
83
- "openAIApiKey": "sk_your-openai-api-key",
84
- }
66
+ # Interactive mode
67
+ coco -i
85
68
  ```
86
69
 
87
- And the same settings in `.gitconfig`:
70
+ ### Generate and commit all in one
88
71
 
89
- ```ini
90
- [coco]
91
- openAIApiKey = sk_your-openai-api-key
92
- ```
72
+ `coco` can generate and commit your changes in one command.
93
73
 
94
- Remember, command line flags and environment variables should be defined in `UPPER_SNAKE_CASE`. For instance, the `openAIApiKey` setting becomes `OPENAI_API_KEY`.
74
+ ```bash
75
+ coco -s
76
+ ```
95
77
 
96
- ### Options
78
+ ## Configuration
97
79
 
98
- | Name | Type | Default Value | Description |
99
- |--------------------------|---------------------------------|-------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|
100
- | openAIApiKey | string | None | Your OpenAI API key |
101
- | tokenLimit | number | 500 | Maximum number of tokens for the commit message |
102
- | prompt | string | `"What are the changes in this commit?"` | Prompt for OpenAI GPT-3 |
103
- | temperature | number | 0.4 | Controls randomness in GPT-3 output. Lower values yield focused output; higher values offer diversity |
104
- | mode | `stdout` \| `interactive` | `stdout` | Preferred output method for generated commit messages |
105
- | summarizePrompt | string | `"Summarize the changes in this large file:"` | GPT-3 prompt for summarizing large files |
106
- | ignoredFiles | string[] | `["package-lock.json"]` | Paths of files to be excluded when generating commit messages |
107
- | ignoredExtensions | string[] | `[".map", ".lock"]` | File extensions to be excluded when generating commit messages |
80
+ The `.coco.config` documentation has moved to our [wiki](https://github.com/gfargo/coco/wiki/Config-Overview). Here, you'll find detailed information on setting up and customizing your experience.
108
81
 
109
- ## Roadmap
82
+ ### **Ignoring Files**
110
83
 
111
- - [x] Interactive mode 🤖
112
- - [x] Stdout 📤
113
- - [x] LangChain integration 🦜
114
- - [ ] Additional tests! 🧪
115
- - [ ] Conventional commits 🔜
116
- - [x] HuggingFace integration 🔜
117
- - [ ] Google Vertex AI integration (?)
118
- - [ ] Automatic changelog generation 🫣
119
- - [ ] Rebase support 🔀
120
- - [ ] `coco --amend b31dfc` 👩‍💻
84
+ You can specify files to be ignored when generating commit messages by adding them to your config file or via command line flags. Read more about ignoring files & extensions in the [wiki](https://github.com/gfargo/coco/wiki/Ignoring-Files-&-Extensions).
121
85
 
122
- ...and more! 🧑‍🔬 🚀
123
86
 
124
87
  ## Contribution
125
88
 
126
- Have an idea for a feature or want to get involved, we welcome contributions!
127
-
128
- Please check out our [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
89
+ We welcome contributions! Check out our [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
package/dist/index.d.ts CHANGED
@@ -19,7 +19,7 @@ declare const _default$2: {
19
19
  openInEditor: boolean;
20
20
  ignoredFiles: string[];
21
21
  ignoredExtensions: string[];
22
- service: "openai/text-davinci-003" | "openai/text-davinci-002" | "openai/text-davinci-001" | "openai/text-curie-001" | "openai/text-babbage-001" | "openai/text-ada-001" | "openai/davinci" | "openai/curie" | "openai/babbage" | "openai/ada" | "openai/code-davinci-002" | "openai/code-davinci-001" | "openai/code-cushman-002" | "openai/code-cushman-001" | "openai/davinci-codex" | "openai/cushman-codex" | "openai/text-davinci-edit-001" | "openai/code-davinci-edit-001" | "openai/text-embedding-ada-002" | "openai/text-similarity-davinci-001" | "openai/text-similarity-curie-001" | "openai/text-similarity-babbage-001" | "openai/text-similarity-ada-001" | "openai/text-search-davinci-doc-001" | "openai/text-search-curie-doc-001" | "openai/text-search-babbage-doc-001" | "openai/text-search-ada-doc-001" | "openai/code-search-babbage-code-001" | "openai/code-search-ada-code-001" | "openai/gpt2" | "openai/gpt-3.5-turbo" | "openai/gpt-3.5-turbo-0301" | "openai/gpt-3.5-turbo-0613" | "openai/gpt-3.5-turbo-16k" | "openai/gpt-3.5-turbo-16k-0613" | "openai/gpt-4" | "openai/gpt-4-0314" | "openai/gpt-4-0613" | "openai/gpt-4-32k" | "openai/gpt-4-32k-0314" | "openai/gpt-4-32k-0613" | "huggingface/text-davinci-003" | "huggingface/text-davinci-002" | "huggingface/text-davinci-001" | "huggingface/text-curie-001" | "huggingface/text-babbage-001" | "huggingface/text-ada-001" | "huggingface/davinci" | "huggingface/curie" | "huggingface/babbage" | "huggingface/ada" | "huggingface/code-davinci-002" | "huggingface/code-davinci-001" | "huggingface/code-cushman-002" | "huggingface/code-cushman-001" | "huggingface/davinci-codex" | "huggingface/cushman-codex" | "huggingface/text-davinci-edit-001" | "huggingface/code-davinci-edit-001" | "huggingface/text-embedding-ada-002" | "huggingface/text-similarity-davinci-001" | "huggingface/text-similarity-curie-001" | "huggingface/text-similarity-babbage-001" | "huggingface/text-similarity-ada-001" | "huggingface/text-search-davinci-doc-001" | "huggingface/text-search-curie-doc-001" | "huggingface/text-search-babbage-doc-001" | "huggingface/text-search-ada-doc-001" | "huggingface/code-search-babbage-code-001" | "huggingface/code-search-ada-code-001" | "huggingface/gpt2" | "huggingface/gpt-3.5-turbo" | "huggingface/gpt-3.5-turbo-0301" | "huggingface/gpt-3.5-turbo-0613" | "huggingface/gpt-3.5-turbo-16k" | "huggingface/gpt-3.5-turbo-16k-0613" | "huggingface/gpt-4" | "huggingface/gpt-4-0314" | "huggingface/gpt-4-0613" | "huggingface/gpt-4-32k" | "huggingface/gpt-4-32k-0314" | "huggingface/gpt-4-32k-0613";
22
+ service: "openai/text-davinci-003" | "openai/text-davinci-002" | "openai/text-davinci-001" | "openai/text-curie-001" | "openai/text-babbage-001" | "openai/text-ada-001" | "openai/davinci" | "openai/curie" | "openai/babbage" | "openai/ada" | "openai/code-davinci-002" | "openai/code-davinci-001" | "openai/code-cushman-002" | "openai/code-cushman-001" | "openai/davinci-codex" | "openai/cushman-codex" | "openai/text-davinci-edit-001" | "openai/code-davinci-edit-001" | "openai/text-embedding-ada-002" | "openai/text-similarity-davinci-001" | "openai/text-similarity-curie-001" | "openai/text-similarity-babbage-001" | "openai/text-similarity-ada-001" | "openai/text-search-davinci-doc-001" | "openai/text-search-curie-doc-001" | "openai/text-search-babbage-doc-001" | "openai/text-search-ada-doc-001" | "openai/code-search-babbage-code-001" | "openai/code-search-ada-code-001" | "openai/gpt2" | "openai/gpt-3.5-turbo" | "openai/gpt-3.5-turbo-0301" | "openai/gpt-3.5-turbo-0613" | "openai/gpt-3.5-turbo-16k" | "openai/gpt-3.5-turbo-16k-0613" | "openai/gpt-4" | "openai/gpt-4-0314" | "openai/gpt-4-0613" | "openai/gpt-4-32k" | "openai/gpt-4-32k-0314" | "openai/gpt-4-32k-0613" | "huggingface/text-davinci-003" | "huggingface/text-davinci-002" | "huggingface/text-davinci-001" | "huggingface/text-curie-001" | "huggingface/text-babbage-001" | "huggingface/text-ada-001" | "huggingface/davinci" | "huggingface/curie" | "huggingface/babbage" | "huggingface/ada" | "huggingface/code-davinci-002" | "huggingface/code-davinci-001" | "huggingface/code-cushman-002" | "huggingface/code-cushman-001" | "huggingface/davinci-codex" | "huggingface/cushman-codex" | "huggingface/text-davinci-edit-001" | "huggingface/code-davinci-edit-001" | "huggingface/text-embedding-ada-002" | "huggingface/text-similarity-davinci-001" | "huggingface/text-similarity-curie-001" | "huggingface/text-similarity-babbage-001" | "huggingface/text-similarity-ada-001" | "huggingface/text-search-davinci-doc-001" | "huggingface/text-search-curie-doc-001" | "huggingface/text-search-babbage-doc-001" | "huggingface/text-search-ada-doc-001" | "huggingface/code-search-babbage-code-001" | "huggingface/code-search-ada-code-001" | "huggingface/gpt2" | "huggingface/gpt-3.5-turbo" | "huggingface/gpt-3.5-turbo-0301" | "huggingface/gpt-3.5-turbo-0613" | "huggingface/gpt-3.5-turbo-16k" | "huggingface/gpt-3.5-turbo-16k-0613" | "huggingface/gpt-4" | "huggingface/gpt-4-0314" | "huggingface/gpt-4-0613" | "huggingface/gpt-4-32k" | "huggingface/gpt-4-32k-0314" | "huggingface/gpt-4-32k-0613" | undefined;
23
23
  openAIApiKey: string | undefined;
24
24
  huggingFaceHubApiKey: string | undefined;
25
25
  tokenLimit: number | undefined;
@@ -36,7 +36,7 @@ declare const _default$2: {
36
36
  openInEditor: boolean;
37
37
  ignoredFiles: string[];
38
38
  ignoredExtensions: string[];
39
- service: "openai/text-davinci-003" | "openai/text-davinci-002" | "openai/text-davinci-001" | "openai/text-curie-001" | "openai/text-babbage-001" | "openai/text-ada-001" | "openai/davinci" | "openai/curie" | "openai/babbage" | "openai/ada" | "openai/code-davinci-002" | "openai/code-davinci-001" | "openai/code-cushman-002" | "openai/code-cushman-001" | "openai/davinci-codex" | "openai/cushman-codex" | "openai/text-davinci-edit-001" | "openai/code-davinci-edit-001" | "openai/text-embedding-ada-002" | "openai/text-similarity-davinci-001" | "openai/text-similarity-curie-001" | "openai/text-similarity-babbage-001" | "openai/text-similarity-ada-001" | "openai/text-search-davinci-doc-001" | "openai/text-search-curie-doc-001" | "openai/text-search-babbage-doc-001" | "openai/text-search-ada-doc-001" | "openai/code-search-babbage-code-001" | "openai/code-search-ada-code-001" | "openai/gpt2" | "openai/gpt-3.5-turbo" | "openai/gpt-3.5-turbo-0301" | "openai/gpt-3.5-turbo-0613" | "openai/gpt-3.5-turbo-16k" | "openai/gpt-3.5-turbo-16k-0613" | "openai/gpt-4" | "openai/gpt-4-0314" | "openai/gpt-4-0613" | "openai/gpt-4-32k" | "openai/gpt-4-32k-0314" | "openai/gpt-4-32k-0613" | "huggingface/text-davinci-003" | "huggingface/text-davinci-002" | "huggingface/text-davinci-001" | "huggingface/text-curie-001" | "huggingface/text-babbage-001" | "huggingface/text-ada-001" | "huggingface/davinci" | "huggingface/curie" | "huggingface/babbage" | "huggingface/ada" | "huggingface/code-davinci-002" | "huggingface/code-davinci-001" | "huggingface/code-cushman-002" | "huggingface/code-cushman-001" | "huggingface/davinci-codex" | "huggingface/cushman-codex" | "huggingface/text-davinci-edit-001" | "huggingface/code-davinci-edit-001" | "huggingface/text-embedding-ada-002" | "huggingface/text-similarity-davinci-001" | "huggingface/text-similarity-curie-001" | "huggingface/text-similarity-babbage-001" | "huggingface/text-similarity-ada-001" | "huggingface/text-search-davinci-doc-001" | "huggingface/text-search-curie-doc-001" | "huggingface/text-search-babbage-doc-001" | "huggingface/text-search-ada-doc-001" | "huggingface/code-search-babbage-code-001" | "huggingface/code-search-ada-code-001" | "huggingface/gpt2" | "huggingface/gpt-3.5-turbo" | "huggingface/gpt-3.5-turbo-0301" | "huggingface/gpt-3.5-turbo-0613" | "huggingface/gpt-3.5-turbo-16k" | "huggingface/gpt-3.5-turbo-16k-0613" | "huggingface/gpt-4" | "huggingface/gpt-4-0314" | "huggingface/gpt-4-0613" | "huggingface/gpt-4-32k" | "huggingface/gpt-4-32k-0314" | "huggingface/gpt-4-32k-0613";
39
+ service: "openai/text-davinci-003" | "openai/text-davinci-002" | "openai/text-davinci-001" | "openai/text-curie-001" | "openai/text-babbage-001" | "openai/text-ada-001" | "openai/davinci" | "openai/curie" | "openai/babbage" | "openai/ada" | "openai/code-davinci-002" | "openai/code-davinci-001" | "openai/code-cushman-002" | "openai/code-cushman-001" | "openai/davinci-codex" | "openai/cushman-codex" | "openai/text-davinci-edit-001" | "openai/code-davinci-edit-001" | "openai/text-embedding-ada-002" | "openai/text-similarity-davinci-001" | "openai/text-similarity-curie-001" | "openai/text-similarity-babbage-001" | "openai/text-similarity-ada-001" | "openai/text-search-davinci-doc-001" | "openai/text-search-curie-doc-001" | "openai/text-search-babbage-doc-001" | "openai/text-search-ada-doc-001" | "openai/code-search-babbage-code-001" | "openai/code-search-ada-code-001" | "openai/gpt2" | "openai/gpt-3.5-turbo" | "openai/gpt-3.5-turbo-0301" | "openai/gpt-3.5-turbo-0613" | "openai/gpt-3.5-turbo-16k" | "openai/gpt-3.5-turbo-16k-0613" | "openai/gpt-4" | "openai/gpt-4-0314" | "openai/gpt-4-0613" | "openai/gpt-4-32k" | "openai/gpt-4-32k-0314" | "openai/gpt-4-32k-0613" | "huggingface/text-davinci-003" | "huggingface/text-davinci-002" | "huggingface/text-davinci-001" | "huggingface/text-curie-001" | "huggingface/text-babbage-001" | "huggingface/text-ada-001" | "huggingface/davinci" | "huggingface/curie" | "huggingface/babbage" | "huggingface/ada" | "huggingface/code-davinci-002" | "huggingface/code-davinci-001" | "huggingface/code-cushman-002" | "huggingface/code-cushman-001" | "huggingface/davinci-codex" | "huggingface/cushman-codex" | "huggingface/text-davinci-edit-001" | "huggingface/code-davinci-edit-001" | "huggingface/text-embedding-ada-002" | "huggingface/text-similarity-davinci-001" | "huggingface/text-similarity-curie-001" | "huggingface/text-similarity-babbage-001" | "huggingface/text-similarity-ada-001" | "huggingface/text-search-davinci-doc-001" | "huggingface/text-search-curie-doc-001" | "huggingface/text-search-babbage-doc-001" | "huggingface/text-search-ada-doc-001" | "huggingface/code-search-babbage-code-001" | "huggingface/code-search-ada-code-001" | "huggingface/gpt2" | "huggingface/gpt-3.5-turbo" | "huggingface/gpt-3.5-turbo-0301" | "huggingface/gpt-3.5-turbo-0613" | "huggingface/gpt-3.5-turbo-16k" | "huggingface/gpt-3.5-turbo-16k-0613" | "huggingface/gpt-4" | "huggingface/gpt-4-0314" | "huggingface/gpt-4-0613" | "huggingface/gpt-4-32k" | "huggingface/gpt-4-32k-0314" | "huggingface/gpt-4-32k-0613" | undefined;
40
40
  openAIApiKey: string | undefined;
41
41
  huggingFaceHubApiKey: string | undefined;
42
42
  tokenLimit: number | undefined;
@@ -62,7 +62,7 @@ declare const _default$1: {
62
62
  openInEditor: boolean;
63
63
  ignoredFiles: string[];
64
64
  ignoredExtensions: string[];
65
- service: "openai/text-davinci-003" | "openai/text-davinci-002" | "openai/text-davinci-001" | "openai/text-curie-001" | "openai/text-babbage-001" | "openai/text-ada-001" | "openai/davinci" | "openai/curie" | "openai/babbage" | "openai/ada" | "openai/code-davinci-002" | "openai/code-davinci-001" | "openai/code-cushman-002" | "openai/code-cushman-001" | "openai/davinci-codex" | "openai/cushman-codex" | "openai/text-davinci-edit-001" | "openai/code-davinci-edit-001" | "openai/text-embedding-ada-002" | "openai/text-similarity-davinci-001" | "openai/text-similarity-curie-001" | "openai/text-similarity-babbage-001" | "openai/text-similarity-ada-001" | "openai/text-search-davinci-doc-001" | "openai/text-search-curie-doc-001" | "openai/text-search-babbage-doc-001" | "openai/text-search-ada-doc-001" | "openai/code-search-babbage-code-001" | "openai/code-search-ada-code-001" | "openai/gpt2" | "openai/gpt-3.5-turbo" | "openai/gpt-3.5-turbo-0301" | "openai/gpt-3.5-turbo-0613" | "openai/gpt-3.5-turbo-16k" | "openai/gpt-3.5-turbo-16k-0613" | "openai/gpt-4" | "openai/gpt-4-0314" | "openai/gpt-4-0613" | "openai/gpt-4-32k" | "openai/gpt-4-32k-0314" | "openai/gpt-4-32k-0613" | "huggingface/text-davinci-003" | "huggingface/text-davinci-002" | "huggingface/text-davinci-001" | "huggingface/text-curie-001" | "huggingface/text-babbage-001" | "huggingface/text-ada-001" | "huggingface/davinci" | "huggingface/curie" | "huggingface/babbage" | "huggingface/ada" | "huggingface/code-davinci-002" | "huggingface/code-davinci-001" | "huggingface/code-cushman-002" | "huggingface/code-cushman-001" | "huggingface/davinci-codex" | "huggingface/cushman-codex" | "huggingface/text-davinci-edit-001" | "huggingface/code-davinci-edit-001" | "huggingface/text-embedding-ada-002" | "huggingface/text-similarity-davinci-001" | "huggingface/text-similarity-curie-001" | "huggingface/text-similarity-babbage-001" | "huggingface/text-similarity-ada-001" | "huggingface/text-search-davinci-doc-001" | "huggingface/text-search-curie-doc-001" | "huggingface/text-search-babbage-doc-001" | "huggingface/text-search-ada-doc-001" | "huggingface/code-search-babbage-code-001" | "huggingface/code-search-ada-code-001" | "huggingface/gpt2" | "huggingface/gpt-3.5-turbo" | "huggingface/gpt-3.5-turbo-0301" | "huggingface/gpt-3.5-turbo-0613" | "huggingface/gpt-3.5-turbo-16k" | "huggingface/gpt-3.5-turbo-16k-0613" | "huggingface/gpt-4" | "huggingface/gpt-4-0314" | "huggingface/gpt-4-0613" | "huggingface/gpt-4-32k" | "huggingface/gpt-4-32k-0314" | "huggingface/gpt-4-32k-0613";
65
+ service: "openai/text-davinci-003" | "openai/text-davinci-002" | "openai/text-davinci-001" | "openai/text-curie-001" | "openai/text-babbage-001" | "openai/text-ada-001" | "openai/davinci" | "openai/curie" | "openai/babbage" | "openai/ada" | "openai/code-davinci-002" | "openai/code-davinci-001" | "openai/code-cushman-002" | "openai/code-cushman-001" | "openai/davinci-codex" | "openai/cushman-codex" | "openai/text-davinci-edit-001" | "openai/code-davinci-edit-001" | "openai/text-embedding-ada-002" | "openai/text-similarity-davinci-001" | "openai/text-similarity-curie-001" | "openai/text-similarity-babbage-001" | "openai/text-similarity-ada-001" | "openai/text-search-davinci-doc-001" | "openai/text-search-curie-doc-001" | "openai/text-search-babbage-doc-001" | "openai/text-search-ada-doc-001" | "openai/code-search-babbage-code-001" | "openai/code-search-ada-code-001" | "openai/gpt2" | "openai/gpt-3.5-turbo" | "openai/gpt-3.5-turbo-0301" | "openai/gpt-3.5-turbo-0613" | "openai/gpt-3.5-turbo-16k" | "openai/gpt-3.5-turbo-16k-0613" | "openai/gpt-4" | "openai/gpt-4-0314" | "openai/gpt-4-0613" | "openai/gpt-4-32k" | "openai/gpt-4-32k-0314" | "openai/gpt-4-32k-0613" | "huggingface/text-davinci-003" | "huggingface/text-davinci-002" | "huggingface/text-davinci-001" | "huggingface/text-curie-001" | "huggingface/text-babbage-001" | "huggingface/text-ada-001" | "huggingface/davinci" | "huggingface/curie" | "huggingface/babbage" | "huggingface/ada" | "huggingface/code-davinci-002" | "huggingface/code-davinci-001" | "huggingface/code-cushman-002" | "huggingface/code-cushman-001" | "huggingface/davinci-codex" | "huggingface/cushman-codex" | "huggingface/text-davinci-edit-001" | "huggingface/code-davinci-edit-001" | "huggingface/text-embedding-ada-002" | "huggingface/text-similarity-davinci-001" | "huggingface/text-similarity-curie-001" | "huggingface/text-similarity-babbage-001" | "huggingface/text-similarity-ada-001" | "huggingface/text-search-davinci-doc-001" | "huggingface/text-search-curie-doc-001" | "huggingface/text-search-babbage-doc-001" | "huggingface/text-search-ada-doc-001" | "huggingface/code-search-babbage-code-001" | "huggingface/code-search-ada-code-001" | "huggingface/gpt2" | "huggingface/gpt-3.5-turbo" | "huggingface/gpt-3.5-turbo-0301" | "huggingface/gpt-3.5-turbo-0613" | "huggingface/gpt-3.5-turbo-16k" | "huggingface/gpt-3.5-turbo-16k-0613" | "huggingface/gpt-4" | "huggingface/gpt-4-0314" | "huggingface/gpt-4-0613" | "huggingface/gpt-4-32k" | "huggingface/gpt-4-32k-0314" | "huggingface/gpt-4-32k-0613" | undefined;
66
66
  openAIApiKey: string | undefined;
67
67
  huggingFaceHubApiKey: string | undefined;
68
68
  tokenLimit: number | undefined;
@@ -80,7 +80,7 @@ declare const _default$1: {
80
80
  openInEditor: boolean;
81
81
  ignoredFiles: string[];
82
82
  ignoredExtensions: string[];
83
- service: "openai/text-davinci-003" | "openai/text-davinci-002" | "openai/text-davinci-001" | "openai/text-curie-001" | "openai/text-babbage-001" | "openai/text-ada-001" | "openai/davinci" | "openai/curie" | "openai/babbage" | "openai/ada" | "openai/code-davinci-002" | "openai/code-davinci-001" | "openai/code-cushman-002" | "openai/code-cushman-001" | "openai/davinci-codex" | "openai/cushman-codex" | "openai/text-davinci-edit-001" | "openai/code-davinci-edit-001" | "openai/text-embedding-ada-002" | "openai/text-similarity-davinci-001" | "openai/text-similarity-curie-001" | "openai/text-similarity-babbage-001" | "openai/text-similarity-ada-001" | "openai/text-search-davinci-doc-001" | "openai/text-search-curie-doc-001" | "openai/text-search-babbage-doc-001" | "openai/text-search-ada-doc-001" | "openai/code-search-babbage-code-001" | "openai/code-search-ada-code-001" | "openai/gpt2" | "openai/gpt-3.5-turbo" | "openai/gpt-3.5-turbo-0301" | "openai/gpt-3.5-turbo-0613" | "openai/gpt-3.5-turbo-16k" | "openai/gpt-3.5-turbo-16k-0613" | "openai/gpt-4" | "openai/gpt-4-0314" | "openai/gpt-4-0613" | "openai/gpt-4-32k" | "openai/gpt-4-32k-0314" | "openai/gpt-4-32k-0613" | "huggingface/text-davinci-003" | "huggingface/text-davinci-002" | "huggingface/text-davinci-001" | "huggingface/text-curie-001" | "huggingface/text-babbage-001" | "huggingface/text-ada-001" | "huggingface/davinci" | "huggingface/curie" | "huggingface/babbage" | "huggingface/ada" | "huggingface/code-davinci-002" | "huggingface/code-davinci-001" | "huggingface/code-cushman-002" | "huggingface/code-cushman-001" | "huggingface/davinci-codex" | "huggingface/cushman-codex" | "huggingface/text-davinci-edit-001" | "huggingface/code-davinci-edit-001" | "huggingface/text-embedding-ada-002" | "huggingface/text-similarity-davinci-001" | "huggingface/text-similarity-curie-001" | "huggingface/text-similarity-babbage-001" | "huggingface/text-similarity-ada-001" | "huggingface/text-search-davinci-doc-001" | "huggingface/text-search-curie-doc-001" | "huggingface/text-search-babbage-doc-001" | "huggingface/text-search-ada-doc-001" | "huggingface/code-search-babbage-code-001" | "huggingface/code-search-ada-code-001" | "huggingface/gpt2" | "huggingface/gpt-3.5-turbo" | "huggingface/gpt-3.5-turbo-0301" | "huggingface/gpt-3.5-turbo-0613" | "huggingface/gpt-3.5-turbo-16k" | "huggingface/gpt-3.5-turbo-16k-0613" | "huggingface/gpt-4" | "huggingface/gpt-4-0314" | "huggingface/gpt-4-0613" | "huggingface/gpt-4-32k" | "huggingface/gpt-4-32k-0314" | "huggingface/gpt-4-32k-0613";
83
+ service: "openai/text-davinci-003" | "openai/text-davinci-002" | "openai/text-davinci-001" | "openai/text-curie-001" | "openai/text-babbage-001" | "openai/text-ada-001" | "openai/davinci" | "openai/curie" | "openai/babbage" | "openai/ada" | "openai/code-davinci-002" | "openai/code-davinci-001" | "openai/code-cushman-002" | "openai/code-cushman-001" | "openai/davinci-codex" | "openai/cushman-codex" | "openai/text-davinci-edit-001" | "openai/code-davinci-edit-001" | "openai/text-embedding-ada-002" | "openai/text-similarity-davinci-001" | "openai/text-similarity-curie-001" | "openai/text-similarity-babbage-001" | "openai/text-similarity-ada-001" | "openai/text-search-davinci-doc-001" | "openai/text-search-curie-doc-001" | "openai/text-search-babbage-doc-001" | "openai/text-search-ada-doc-001" | "openai/code-search-babbage-code-001" | "openai/code-search-ada-code-001" | "openai/gpt2" | "openai/gpt-3.5-turbo" | "openai/gpt-3.5-turbo-0301" | "openai/gpt-3.5-turbo-0613" | "openai/gpt-3.5-turbo-16k" | "openai/gpt-3.5-turbo-16k-0613" | "openai/gpt-4" | "openai/gpt-4-0314" | "openai/gpt-4-0613" | "openai/gpt-4-32k" | "openai/gpt-4-32k-0314" | "openai/gpt-4-32k-0613" | "huggingface/text-davinci-003" | "huggingface/text-davinci-002" | "huggingface/text-davinci-001" | "huggingface/text-curie-001" | "huggingface/text-babbage-001" | "huggingface/text-ada-001" | "huggingface/davinci" | "huggingface/curie" | "huggingface/babbage" | "huggingface/ada" | "huggingface/code-davinci-002" | "huggingface/code-davinci-001" | "huggingface/code-cushman-002" | "huggingface/code-cushman-001" | "huggingface/davinci-codex" | "huggingface/cushman-codex" | "huggingface/text-davinci-edit-001" | "huggingface/code-davinci-edit-001" | "huggingface/text-embedding-ada-002" | "huggingface/text-similarity-davinci-001" | "huggingface/text-similarity-curie-001" | "huggingface/text-similarity-babbage-001" | "huggingface/text-similarity-ada-001" | "huggingface/text-search-davinci-doc-001" | "huggingface/text-search-curie-doc-001" | "huggingface/text-search-babbage-doc-001" | "huggingface/text-search-ada-doc-001" | "huggingface/code-search-babbage-code-001" | "huggingface/code-search-ada-code-001" | "huggingface/gpt2" | "huggingface/gpt-3.5-turbo" | "huggingface/gpt-3.5-turbo-0301" | "huggingface/gpt-3.5-turbo-0613" | "huggingface/gpt-3.5-turbo-16k" | "huggingface/gpt-3.5-turbo-16k-0613" | "huggingface/gpt-4" | "huggingface/gpt-4-0314" | "huggingface/gpt-4-0613" | "huggingface/gpt-4-32k" | "huggingface/gpt-4-32k-0314" | "huggingface/gpt-4-32k-0613" | undefined;
84
84
  openAIApiKey: string | undefined;
85
85
  huggingFaceHubApiKey: string | undefined;
86
86
  tokenLimit: number | undefined;
@@ -76,6 +76,8 @@ const CONFIG_KEYS = Object.keys({
76
76
  openAIApiKey: '',
77
77
  prompt: '',
78
78
  });
79
+ const COCO_CONFIG_START_COMMENT = '# -- start coco config --';
80
+ const COCO_CONFIG_END_COMMENT = '# -- end coco config --';
79
81
 
80
82
  async function updateFileSection({ filePath, startComment, endComment, getNewContent, confirmUpdate = true, confirmMessage = (path) => `A section already exists in ${path}, do you want to override it?`, }) {
81
83
  const lines = fs__default.existsSync(filePath) ? fs__default.readFileSync(filePath, 'utf-8').split(/\r?\n/) : [];
@@ -196,8 +198,6 @@ function formatEnvValue(value) {
196
198
  return `${value}`;
197
199
  }
198
200
  const appendToEnvFile = async (filePath, config) => {
199
- const startComment = '# -- Start coco config --';
200
- const endComment = '# -- End coco config --';
201
201
  const getNewContent = async () => {
202
202
  return Object.entries(config)
203
203
  .map(([key, value]) => `${toEnvVarName(key)}=${formatEnvValue(value)}`)
@@ -205,8 +205,8 @@ const appendToEnvFile = async (filePath, config) => {
205
205
  };
206
206
  await updateFileSection({
207
207
  filePath,
208
- startComment,
209
- endComment,
208
+ startComment: COCO_CONFIG_START_COMMENT,
209
+ endComment: COCO_CONFIG_END_COMMENT,
210
210
  getNewContent,
211
211
  confirmMessage: CONFIG_ALREADY_EXISTS,
212
212
  });
@@ -250,10 +250,7 @@ const appendToGitConfig = async (filePath, config) => {
250
250
  if (!fs.existsSync(filePath)) {
251
251
  throw new Error(`File ${filePath} does not exist.`);
252
252
  }
253
- const startComment = '# -- Start coco config --';
254
- const endComment = '# -- End coco config --';
255
253
  const header = '[coco]';
256
- // Function to generate new content for the coco section
257
254
  const getNewContent = async () => {
258
255
  const contentLines = [header];
259
256
  for (const key in config) {
@@ -271,8 +268,8 @@ const appendToGitConfig = async (filePath, config) => {
271
268
  };
272
269
  await updateFileSection({
273
270
  filePath,
274
- startComment,
275
- endComment,
271
+ startComment: COCO_CONFIG_START_COMMENT,
272
+ endComment: COCO_CONFIG_END_COMMENT,
276
273
  getNewContent,
277
274
  confirmUpdate: true,
278
275
  confirmMessage: CONFIG_ALREADY_EXISTS,
@@ -318,7 +315,7 @@ function loadIgnore(config) {
318
315
  * @param {Config} config
319
316
  * @returns {Config} Updated config
320
317
  **/
321
- function loadProjectConfig(config) {
318
+ function loadProjectJsonConfig(config) {
322
319
  // TODO: Add validation based of JSON schema?
323
320
  // @see https://github.com/acornejo/jjv
324
321
  if (fs.existsSync('.coco.config.json')) {
@@ -327,7 +324,10 @@ function loadProjectConfig(config) {
327
324
  }
328
325
  return config;
329
326
  }
330
- const appendToProjectConfig = (filePath, config) => {
327
+ const appendToProjectJsonConfig = (filePath, config) => {
328
+ if (!fs.existsSync(filePath)) {
329
+ fs.writeFileSync(filePath, '{}');
330
+ }
331
331
  fs.writeFileSync(filePath, JSON.stringify({
332
332
  $schema: 'https://git-co.co/schema.json',
333
333
  ...config,
@@ -374,7 +374,7 @@ function loadConfig(argv = {}) {
374
374
  config = loadIgnore(config);
375
375
  config = loadXDGConfig(config);
376
376
  config = loadGitConfig(config);
377
- config = loadProjectConfig(config);
377
+ config = loadProjectJsonConfig(config);
378
378
  config = loadEnvConfig(config);
379
379
  return { ...config, ...argv };
380
380
  }
@@ -662,6 +662,9 @@ async function collectDiffs(node, getFileDiff, tokenizer, logger) {
662
662
  }
663
663
 
664
664
  function getModelAndProviderFromService(service) {
665
+ if (!service) {
666
+ throw new Error(`Missing service`);
667
+ }
665
668
  const [provider, model] = service.split(/\/(.*)/s);
666
669
  if (!model || !provider) {
667
670
  throw new Error(`Invalid service: ${service}`);
@@ -1686,13 +1689,9 @@ function getPathToUsersGitConfig() {
1686
1689
  return path__default.join(os__default.homedir(), '.gitconfig');
1687
1690
  }
1688
1691
 
1689
- async function createProjectFileAndReturnPath(fileName, contents) {
1692
+ async function getProjectConfigFilePath(configFileName) {
1690
1693
  const projectRoot = findProjectRoot(process.cwd());
1691
- const configFile = `${projectRoot}/${fileName}`;
1692
- if (!fs__default.existsSync(configFile)) {
1693
- fs__default.writeFileSync(configFile, contents || '');
1694
- }
1695
- return configFile;
1694
+ return `${projectRoot}/${configFileName}`;
1696
1695
  }
1697
1696
 
1698
1697
  const handler = async (argv, logger) => {
@@ -1716,29 +1715,6 @@ const handler = async (argv, logger) => {
1716
1715
  ],
1717
1716
  });
1718
1717
  }
1719
- let configFilePath = '';
1720
- switch (level) {
1721
- case 'project':
1722
- const projectConfiguration = await select({
1723
- message: 'select type project level configuration:',
1724
- choices: [
1725
- {
1726
- name: '.coco.config.json',
1727
- value: '.coco.config.json',
1728
- },
1729
- {
1730
- name: '.env',
1731
- value: '.env',
1732
- },
1733
- ],
1734
- });
1735
- configFilePath = await createProjectFileAndReturnPath(projectConfiguration);
1736
- break;
1737
- case 'global':
1738
- default:
1739
- configFilePath = getPathToUsersGitConfig();
1740
- break;
1741
- }
1742
1718
  // interactive v.s stdout mode
1743
1719
  const mode = (await select({
1744
1720
  message: 'select mode:',
@@ -1835,15 +1811,38 @@ const handler = async (argv, logger) => {
1835
1811
  const isApproved = await confirm({
1836
1812
  message: 'looking good? (API key hidden for security)',
1837
1813
  });
1814
+ let configFilePath = '';
1815
+ switch (level) {
1816
+ case 'project':
1817
+ const projectConfiguration = (await select({
1818
+ message: 'where would you like to store the project config?',
1819
+ choices: [
1820
+ {
1821
+ name: '.coco.config.json',
1822
+ value: '.coco.config.json',
1823
+ },
1824
+ {
1825
+ name: '.env',
1826
+ value: '.env',
1827
+ },
1828
+ ],
1829
+ }));
1830
+ configFilePath = await getProjectConfigFilePath(projectConfiguration);
1831
+ break;
1832
+ case 'global':
1833
+ default:
1834
+ configFilePath = getPathToUsersGitConfig();
1835
+ break;
1836
+ }
1838
1837
  if (isApproved) {
1839
1838
  if (configFilePath.endsWith('.gitconfig')) {
1840
1839
  await appendToGitConfig(configFilePath, config);
1841
1840
  }
1842
- else if (configFilePath === '.env') {
1841
+ else if (configFilePath.endsWith('.env')) {
1843
1842
  await appendToEnvFile(configFilePath, config);
1844
1843
  }
1845
- else if (configFilePath === '.coco.config.json') {
1846
- await appendToProjectConfig(configFilePath, config);
1844
+ else if (configFilePath.endsWith('.coco.config.json')) {
1845
+ await appendToProjectJsonConfig(configFilePath, config);
1847
1846
  }
1848
1847
  // After config is written, check for package installation
1849
1848
  await checkAndHandlePackageInstallation({ global: level === 'global', logger });
package/dist/index.js CHANGED
@@ -97,6 +97,8 @@ const CONFIG_KEYS = Object.keys({
97
97
  openAIApiKey: '',
98
98
  prompt: '',
99
99
  });
100
+ const COCO_CONFIG_START_COMMENT = '# -- start coco config --';
101
+ const COCO_CONFIG_END_COMMENT = '# -- end coco config --';
100
102
 
101
103
  async function updateFileSection({ filePath, startComment, endComment, getNewContent, confirmUpdate = true, confirmMessage = (path) => `A section already exists in ${path}, do you want to override it?`, }) {
102
104
  const lines = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8').split(/\r?\n/) : [];
@@ -217,8 +219,6 @@ function formatEnvValue(value) {
217
219
  return `${value}`;
218
220
  }
219
221
  const appendToEnvFile = async (filePath, config) => {
220
- const startComment = '# -- Start coco config --';
221
- const endComment = '# -- End coco config --';
222
222
  const getNewContent = async () => {
223
223
  return Object.entries(config)
224
224
  .map(([key, value]) => `${toEnvVarName(key)}=${formatEnvValue(value)}`)
@@ -226,8 +226,8 @@ const appendToEnvFile = async (filePath, config) => {
226
226
  };
227
227
  await updateFileSection({
228
228
  filePath,
229
- startComment,
230
- endComment,
229
+ startComment: COCO_CONFIG_START_COMMENT,
230
+ endComment: COCO_CONFIG_END_COMMENT,
231
231
  getNewContent,
232
232
  confirmMessage: CONFIG_ALREADY_EXISTS,
233
233
  });
@@ -271,10 +271,7 @@ const appendToGitConfig = async (filePath, config) => {
271
271
  if (!fs__namespace.existsSync(filePath)) {
272
272
  throw new Error(`File ${filePath} does not exist.`);
273
273
  }
274
- const startComment = '# -- Start coco config --';
275
- const endComment = '# -- End coco config --';
276
274
  const header = '[coco]';
277
- // Function to generate new content for the coco section
278
275
  const getNewContent = async () => {
279
276
  const contentLines = [header];
280
277
  for (const key in config) {
@@ -292,8 +289,8 @@ const appendToGitConfig = async (filePath, config) => {
292
289
  };
293
290
  await updateFileSection({
294
291
  filePath,
295
- startComment,
296
- endComment,
292
+ startComment: COCO_CONFIG_START_COMMENT,
293
+ endComment: COCO_CONFIG_END_COMMENT,
297
294
  getNewContent,
298
295
  confirmUpdate: true,
299
296
  confirmMessage: CONFIG_ALREADY_EXISTS,
@@ -339,7 +336,7 @@ function loadIgnore(config) {
339
336
  * @param {Config} config
340
337
  * @returns {Config} Updated config
341
338
  **/
342
- function loadProjectConfig(config) {
339
+ function loadProjectJsonConfig(config) {
343
340
  // TODO: Add validation based of JSON schema?
344
341
  // @see https://github.com/acornejo/jjv
345
342
  if (fs__namespace.existsSync('.coco.config.json')) {
@@ -348,7 +345,10 @@ function loadProjectConfig(config) {
348
345
  }
349
346
  return config;
350
347
  }
351
- const appendToProjectConfig = (filePath, config) => {
348
+ const appendToProjectJsonConfig = (filePath, config) => {
349
+ if (!fs__namespace.existsSync(filePath)) {
350
+ fs__namespace.writeFileSync(filePath, '{}');
351
+ }
352
352
  fs__namespace.writeFileSync(filePath, JSON.stringify({
353
353
  $schema: 'https://git-co.co/schema.json',
354
354
  ...config,
@@ -395,7 +395,7 @@ function loadConfig(argv = {}) {
395
395
  config = loadIgnore(config);
396
396
  config = loadXDGConfig(config);
397
397
  config = loadGitConfig(config);
398
- config = loadProjectConfig(config);
398
+ config = loadProjectJsonConfig(config);
399
399
  config = loadEnvConfig(config);
400
400
  return { ...config, ...argv };
401
401
  }
@@ -683,6 +683,9 @@ async function collectDiffs(node, getFileDiff, tokenizer, logger) {
683
683
  }
684
684
 
685
685
  function getModelAndProviderFromService(service) {
686
+ if (!service) {
687
+ throw new Error(`Missing service`);
688
+ }
686
689
  const [provider, model] = service.split(/\/(.*)/s);
687
690
  if (!model || !provider) {
688
691
  throw new Error(`Invalid service: ${service}`);
@@ -1707,13 +1710,9 @@ function getPathToUsersGitConfig() {
1707
1710
  return path.join(os.homedir(), '.gitconfig');
1708
1711
  }
1709
1712
 
1710
- async function createProjectFileAndReturnPath(fileName, contents) {
1713
+ async function getProjectConfigFilePath(configFileName) {
1711
1714
  const projectRoot = findProjectRoot(process.cwd());
1712
- const configFile = `${projectRoot}/${fileName}`;
1713
- if (!fs.existsSync(configFile)) {
1714
- fs.writeFileSync(configFile, contents || '');
1715
- }
1716
- return configFile;
1715
+ return `${projectRoot}/${configFileName}`;
1717
1716
  }
1718
1717
 
1719
1718
  const handler = async (argv, logger) => {
@@ -1737,29 +1736,6 @@ const handler = async (argv, logger) => {
1737
1736
  ],
1738
1737
  });
1739
1738
  }
1740
- let configFilePath = '';
1741
- switch (level) {
1742
- case 'project':
1743
- const projectConfiguration = await prompts$1.select({
1744
- message: 'select type project level configuration:',
1745
- choices: [
1746
- {
1747
- name: '.coco.config.json',
1748
- value: '.coco.config.json',
1749
- },
1750
- {
1751
- name: '.env',
1752
- value: '.env',
1753
- },
1754
- ],
1755
- });
1756
- configFilePath = await createProjectFileAndReturnPath(projectConfiguration);
1757
- break;
1758
- case 'global':
1759
- default:
1760
- configFilePath = getPathToUsersGitConfig();
1761
- break;
1762
- }
1763
1739
  // interactive v.s stdout mode
1764
1740
  const mode = (await prompts$1.select({
1765
1741
  message: 'select mode:',
@@ -1856,15 +1832,38 @@ const handler = async (argv, logger) => {
1856
1832
  const isApproved = await prompts$1.confirm({
1857
1833
  message: 'looking good? (API key hidden for security)',
1858
1834
  });
1835
+ let configFilePath = '';
1836
+ switch (level) {
1837
+ case 'project':
1838
+ const projectConfiguration = (await prompts$1.select({
1839
+ message: 'where would you like to store the project config?',
1840
+ choices: [
1841
+ {
1842
+ name: '.coco.config.json',
1843
+ value: '.coco.config.json',
1844
+ },
1845
+ {
1846
+ name: '.env',
1847
+ value: '.env',
1848
+ },
1849
+ ],
1850
+ }));
1851
+ configFilePath = await getProjectConfigFilePath(projectConfiguration);
1852
+ break;
1853
+ case 'global':
1854
+ default:
1855
+ configFilePath = getPathToUsersGitConfig();
1856
+ break;
1857
+ }
1859
1858
  if (isApproved) {
1860
1859
  if (configFilePath.endsWith('.gitconfig')) {
1861
1860
  await appendToGitConfig(configFilePath, config);
1862
1861
  }
1863
- else if (configFilePath === '.env') {
1862
+ else if (configFilePath.endsWith('.env')) {
1864
1863
  await appendToEnvFile(configFilePath, config);
1865
1864
  }
1866
- else if (configFilePath === '.coco.config.json') {
1867
- await appendToProjectConfig(configFilePath, config);
1865
+ else if (configFilePath.endsWith('.coco.config.json')) {
1866
+ await appendToProjectJsonConfig(configFilePath, config);
1868
1867
  }
1869
1868
  // After config is written, check for package installation
1870
1869
  await checkAndHandlePackageInstallation({ global: level === 'global', logger });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-coco",
3
- "version": "0.7.5",
3
+ "version": "0.7.6",
4
4
  "description": "zero-effort git commits with coco.",
5
5
  "author": "gfargo <ghfargo@gmail.com>",
6
6
  "license": "MIT",