git-coco 0.7.4 → 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 +41 -80
- package/dist/index.d.ts +6 -4
- package/dist/index.esm.mjs +50 -51
- package/dist/index.js +50 -51
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,123 +6,84 @@
|
|
|
6
6
|
[](https://www.npmjs.com/package/git-coco)
|
|
7
7
|
[](https://www.npmjs.com/package/git-coco)
|
|
8
8
|
|
|
9
|
-
Commit Copilot,
|
|
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
|
-
|
|
15
|
+
- **`changelog`**: create changelogs for the current branch or a range of commits.
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
- **`init`**: step by step wizard to set up `coco` globally or for a project.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
npm i git-coco --save-dev
|
|
19
|
-
```
|
|
19
|
+
## Getting Started
|
|
20
20
|
|
|
21
|
-
|
|
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
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
1. [Interactive Mode](#interactive)
|
|
32
|
-
2. [Command Line Interface (CLI)](#cli)
|
|
33
|
+
### **`coco commit`**
|
|
33
34
|
|
|
34
|
-
|
|
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
|
|
40
|
-
```
|
|
38
|
+
coco
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
# or
|
|
43
41
|
|
|
44
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
git commit -m $(coco)
|
|
59
|
-
```
|
|
45
|
+
### **`coco changelog`**
|
|
60
46
|
|
|
61
|
-
|
|
47
|
+
Creates changelogs.
|
|
62
48
|
|
|
63
49
|
```bash
|
|
64
|
-
|
|
65
|
-
|
|
50
|
+
# For the current branch
|
|
51
|
+
coco changelog
|
|
66
52
|
|
|
67
|
-
|
|
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
|
-
|
|
58
|
+
### Stdout vs. Interactive Mode
|
|
72
59
|
|
|
73
|
-
|
|
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
|
-
|
|
62
|
+
```bash
|
|
63
|
+
# Stdout mode
|
|
64
|
+
git commit -m $(coco)
|
|
80
65
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"openAIApiKey": "sk_your-openai-api-key",
|
|
84
|
-
}
|
|
66
|
+
# Interactive mode
|
|
67
|
+
coco -i
|
|
85
68
|
```
|
|
86
69
|
|
|
87
|
-
|
|
70
|
+
### Generate and commit all in one
|
|
88
71
|
|
|
89
|
-
|
|
90
|
-
[coco]
|
|
91
|
-
openAIApiKey = sk_your-openai-api-key
|
|
92
|
-
```
|
|
72
|
+
`coco` can generate and commit your changes in one command.
|
|
93
73
|
|
|
94
|
-
|
|
74
|
+
```bash
|
|
75
|
+
coco -s
|
|
76
|
+
```
|
|
95
77
|
|
|
96
|
-
|
|
78
|
+
## Configuration
|
|
97
79
|
|
|
98
|
-
|
|
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
|
-
|
|
82
|
+
### **Ignoring Files**
|
|
110
83
|
|
|
111
|
-
|
|
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
|
-
|
|
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;
|
|
@@ -99,6 +99,7 @@ declare const _default: {
|
|
|
99
99
|
builder: (yargs: yargs.Argv<{}>) => yargs.Argv<yargs.Omit<{}, string> & yargs.InferredOptionTypes<Record<string, yargs.Options>>>;
|
|
100
100
|
handler: (argv: {
|
|
101
101
|
[x: string]: unknown;
|
|
102
|
+
level?: "global" | "project" | undefined;
|
|
102
103
|
interactive: boolean;
|
|
103
104
|
help: boolean;
|
|
104
105
|
verbose: boolean;
|
|
@@ -106,6 +107,7 @@ declare const _default: {
|
|
|
106
107
|
$0: string;
|
|
107
108
|
} | Promise<{
|
|
108
109
|
[x: string]: unknown;
|
|
110
|
+
level?: "global" | "project" | undefined;
|
|
109
111
|
interactive: boolean;
|
|
110
112
|
help: boolean;
|
|
111
113
|
verbose: boolean;
|
package/dist/index.esm.mjs
CHANGED
|
@@ -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
|
|
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
|
|
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 =
|
|
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
|
|
1692
|
+
async function getProjectConfigFilePath(configFileName) {
|
|
1690
1693
|
const projectRoot = findProjectRoot(process.cwd());
|
|
1691
|
-
|
|
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) => {
|
|
@@ -1701,11 +1700,11 @@ const handler = async (argv, logger) => {
|
|
|
1701
1700
|
let level = options?.level;
|
|
1702
1701
|
if (!level) {
|
|
1703
1702
|
level = await select({
|
|
1704
|
-
message: 'configure coco
|
|
1703
|
+
message: 'configure coco for the current user or project?',
|
|
1705
1704
|
choices: [
|
|
1706
1705
|
{
|
|
1707
|
-
name: '
|
|
1708
|
-
value: '
|
|
1706
|
+
name: 'global',
|
|
1707
|
+
value: 'global',
|
|
1709
1708
|
description: 'add coco config to your global git config',
|
|
1710
1709
|
},
|
|
1711
1710
|
{
|
|
@@ -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 'system':
|
|
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,18 +1811,41 @@ 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
|
|
1841
|
+
else if (configFilePath.endsWith('.env')) {
|
|
1843
1842
|
await appendToEnvFile(configFilePath, config);
|
|
1844
1843
|
}
|
|
1845
|
-
else if (configFilePath
|
|
1846
|
-
await
|
|
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
|
-
await checkAndHandlePackageInstallation({ global: level === '
|
|
1848
|
+
await checkAndHandlePackageInstallation({ global: level === 'global', logger });
|
|
1850
1849
|
logger.log(`\ninit successful! 🦾🤖🎉`, { color: 'green' });
|
|
1851
1850
|
}
|
|
1852
1851
|
else {
|
|
@@ -1861,8 +1860,8 @@ const options = {
|
|
|
1861
1860
|
level: {
|
|
1862
1861
|
type: 'string',
|
|
1863
1862
|
alias: 'l',
|
|
1864
|
-
description: '
|
|
1865
|
-
choices: ['
|
|
1863
|
+
description: 'configure coco for the current user or project?',
|
|
1864
|
+
choices: ['global', 'project'],
|
|
1866
1865
|
},
|
|
1867
1866
|
};
|
|
1868
1867
|
const builder = (yargs) => {
|
|
@@ -1871,7 +1870,7 @@ const builder = (yargs) => {
|
|
|
1871
1870
|
|
|
1872
1871
|
var init = {
|
|
1873
1872
|
command: 'init',
|
|
1874
|
-
desc: '
|
|
1873
|
+
desc: 'install & configure coco globally or for the current project',
|
|
1875
1874
|
builder,
|
|
1876
1875
|
handler: commandExecutor(handler),
|
|
1877
1876
|
options,
|
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
|
|
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
|
|
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 =
|
|
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
|
|
1713
|
+
async function getProjectConfigFilePath(configFileName) {
|
|
1711
1714
|
const projectRoot = findProjectRoot(process.cwd());
|
|
1712
|
-
|
|
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) => {
|
|
@@ -1722,11 +1721,11 @@ const handler = async (argv, logger) => {
|
|
|
1722
1721
|
let level = options?.level;
|
|
1723
1722
|
if (!level) {
|
|
1724
1723
|
level = await prompts$1.select({
|
|
1725
|
-
message: 'configure coco
|
|
1724
|
+
message: 'configure coco for the current user or project?',
|
|
1726
1725
|
choices: [
|
|
1727
1726
|
{
|
|
1728
|
-
name: '
|
|
1729
|
-
value: '
|
|
1727
|
+
name: 'global',
|
|
1728
|
+
value: 'global',
|
|
1730
1729
|
description: 'add coco config to your global git config',
|
|
1731
1730
|
},
|
|
1732
1731
|
{
|
|
@@ -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 'system':
|
|
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,18 +1832,41 @@ 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
|
|
1862
|
+
else if (configFilePath.endsWith('.env')) {
|
|
1864
1863
|
await appendToEnvFile(configFilePath, config);
|
|
1865
1864
|
}
|
|
1866
|
-
else if (configFilePath
|
|
1867
|
-
await
|
|
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
|
-
await checkAndHandlePackageInstallation({ global: level === '
|
|
1869
|
+
await checkAndHandlePackageInstallation({ global: level === 'global', logger });
|
|
1871
1870
|
logger.log(`\ninit successful! 🦾🤖🎉`, { color: 'green' });
|
|
1872
1871
|
}
|
|
1873
1872
|
else {
|
|
@@ -1882,8 +1881,8 @@ const options = {
|
|
|
1882
1881
|
level: {
|
|
1883
1882
|
type: 'string',
|
|
1884
1883
|
alias: 'l',
|
|
1885
|
-
description: '
|
|
1886
|
-
choices: ['
|
|
1884
|
+
description: 'configure coco for the current user or project?',
|
|
1885
|
+
choices: ['global', 'project'],
|
|
1887
1886
|
},
|
|
1888
1887
|
};
|
|
1889
1888
|
const builder = (yargs) => {
|
|
@@ -1892,7 +1891,7 @@ const builder = (yargs) => {
|
|
|
1892
1891
|
|
|
1893
1892
|
var init = {
|
|
1894
1893
|
command: 'init',
|
|
1895
|
-
desc: '
|
|
1894
|
+
desc: 'install & configure coco globally or for the current project',
|
|
1896
1895
|
builder,
|
|
1897
1896
|
handler: commandExecutor(handler),
|
|
1898
1897
|
options,
|