cloving 0.3.11 → 0.3.12
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/dist/cloving_gpt/index.js +31 -38
- package/dist/commands/generate/commit.js +1 -1
- package/dist/commands/generate/docs.js +11 -0
- package/dist/commands/generate/review.js +1 -1
- package/dist/commands/tokens.js +24 -0
- package/dist/index.js +3 -3
- package/dist/managers/BlockManager.js +17 -13
- package/dist/managers/ChatManager.js +22 -208
- package/dist/managers/CodeManager.js +58 -55
- package/dist/managers/CommitManager.js +1 -1
- package/dist/managers/DocsManager.js +86 -0
- package/dist/managers/DocumentationManager.js +2 -1
- package/dist/managers/InitManager.js +2 -1
- package/dist/managers/ReviewManager.js +59 -169
- package/dist/managers/ShellManager.js +49 -0
- package/dist/managers/StreamManager.js +291 -0
- package/dist/managers/UnitTestManager.js +3 -3
- package/dist/package.json +2 -2
- package/dist/utils/config_utils.js +43 -0
- package/dist/utils/git_utils.js +29 -0
- package/dist/utils/prompt_utils.js +125 -307
- package/dist/utils/prompts/CODEGEN_COULDNT_APPLY.md +5 -0
- package/dist/utils/prompts/CODEGEN_EXAMPLES.md +82 -0
- package/dist/utils/prompts/CODEGEN_INSTRUCTIONS.md +42 -0
- package/dist/utils/prompts/DOCS_INSTRUCTIONS.md +9 -0
- package/dist/utils/prompts/INIT_INSTRUCTIONS.md +132 -0
- package/dist/utils/prompts/REVIEW_INSTRUCTIONS.md +49 -0
- package/dist/utils/prompts/SHELL_INSTRUCTIONS.md +15 -0
- package/dist/utils/prompts/SPECIAL_FILES.md +66 -0
- package/dist/utils/prompts/index.js +27 -0
- package/package.json +2 -2
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module prompt_utils
|
|
4
|
+
* @description Provides utility functions for generating prompts, handling files, and running commands.
|
|
5
|
+
*/
|
|
2
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
8
|
};
|
|
5
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.addFileOrDirectoryToContext = exports.readFileContent = exports.fetchModels = exports.runCommand = exports.generateFileList = exports.getAllFilesInDirectory = exports.checkForSpecialFiles = exports.collectSpecialFileContents = exports.
|
|
10
|
+
exports.addFileOrDirectoryToContext = exports.readFileContent = exports.fetchModels = exports.runCommand = exports.generateFileList = exports.getAllFilesInDirectory = exports.checkForSpecialFiles = exports.collectSpecialFileContents = exports.generateReviewPrompt = exports.generateShellPrompt = exports.generateDocsPrompt = exports.generateCodegenPrompt = exports.getPackageVersion = void 0;
|
|
7
11
|
const fs_1 = __importDefault(require("fs"));
|
|
8
12
|
const path_1 = __importDefault(require("path"));
|
|
9
13
|
const child_process_1 = require("child_process");
|
|
@@ -11,241 +15,33 @@ const isbinaryfile_1 = require("isbinaryfile");
|
|
|
11
15
|
const colors_1 = __importDefault(require("colors"));
|
|
12
16
|
const path_2 = require("path");
|
|
13
17
|
const config_utils_1 = require("./config_utils");
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
2. **Follow best practices and the latest standards found in the **Description of App** section.**
|
|
20
|
-
3. **Adhere to existing conventions and libraries in the codebase.**
|
|
21
|
-
|
|
22
|
-
### Request Handling
|
|
23
|
-
|
|
24
|
-
1. **Try to understand the request, but if anything is unclear, ask questions.**
|
|
25
|
-
2. **Decide if you need to propose edits to existing files not in the chat.**
|
|
26
|
-
- If yes, provide the full path names and ask the user to add them.
|
|
27
|
-
- Wait for user approval before proceeding.
|
|
28
|
-
3. **Propose changes using *CURRENT/NEW* Blocks.**
|
|
29
|
-
4. **Show the smallest possible *CURRENT* section that uniquely identifies the code.**
|
|
30
|
-
5. **To move code, use two *CURRENT/NEW* blocks: one to remove and one to add.**
|
|
31
|
-
6. **For new files or to replace an existing file, the *CURRENT* block is empty.**
|
|
32
|
-
|
|
33
|
-
### *CURRENT/NEW* Block Format
|
|
34
|
-
|
|
35
|
-
1. **Start a block with three backticks and the language name.**
|
|
36
|
-
\`\`\`typescript
|
|
37
|
-
2. **Next line: seven <, CURRENT, and the file path.**
|
|
38
|
-
<<<<<<< CURRENT path/to/file.ts
|
|
39
|
-
3. **Include the exact existing code to be changed, this section should never be just spaces or tabs unless it is a new file.**
|
|
40
|
-
4. **Divide with seven =.**
|
|
41
|
-
=======
|
|
42
|
-
5. **Add the new code.**
|
|
43
|
-
6. **End with seven > and NEW.**
|
|
44
|
-
>>>>>>> NEW
|
|
45
|
-
7. **Close the block with three backticks.**
|
|
46
|
-
\`\`\``;
|
|
47
|
-
exports.INIT_INSTRUCTIONS = `You are an AI assistant helping to initialize a project by analyzing its structure and technologies.
|
|
48
|
-
|
|
49
|
-
Please return JSON-formatted metadata about the project, including:
|
|
50
|
-
|
|
51
|
-
- The programming language(s) used
|
|
52
|
-
- The detected framework(s) (if any)
|
|
53
|
-
- The version of the language(s)
|
|
54
|
-
|
|
55
|
-
Here is a typescript interface for the expected response:
|
|
56
|
-
|
|
57
|
-
interface LanguageConfig {
|
|
58
|
-
name: string
|
|
59
|
-
version?: string
|
|
60
|
-
primary?: boolean
|
|
61
|
-
directory: string
|
|
62
|
-
extension: string
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
interface FrameworkConfig {
|
|
66
|
-
name: string
|
|
67
|
-
type: string
|
|
68
|
-
version?: string
|
|
69
|
-
primary?: boolean
|
|
70
|
-
directory?: string
|
|
71
|
-
extension?: string
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
interface TestingFrameworkConfig {
|
|
75
|
-
name: string
|
|
76
|
-
type: string
|
|
77
|
-
version?: string
|
|
78
|
-
directory?: string
|
|
79
|
-
runCommand?: string
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
interface BuildToolConfig {
|
|
83
|
-
name: string
|
|
84
|
-
type: string
|
|
85
|
-
version?: string
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
interface LinterConfig {
|
|
89
|
-
name: string
|
|
90
|
-
version?: string
|
|
91
|
-
type?: string
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
interface DatabaseConfig {
|
|
95
|
-
name: string
|
|
96
|
-
primary?: boolean
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface ClovingfileConfig {
|
|
100
|
-
languages: LanguageConfig[]
|
|
101
|
-
frameworks: FrameworkConfig[]
|
|
102
|
-
testingFrameworks?: TestingFrameworkConfig[]
|
|
103
|
-
buildTools: BuildToolConfig[]
|
|
104
|
-
packageManager: string
|
|
105
|
-
linters: LinterConfig[]
|
|
106
|
-
databases?: DatabaseConfig[]
|
|
107
|
-
projectType: string
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
Here is an example response:
|
|
111
|
-
|
|
112
|
-
{
|
|
113
|
-
"languages": [
|
|
114
|
-
{
|
|
115
|
-
"name": "TypeScript",
|
|
116
|
-
"version": "~> 5.5.3"
|
|
117
|
-
"primary": true,
|
|
118
|
-
"directory": "src",
|
|
119
|
-
"extension": ".ts"
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
"name": "JavaScript",
|
|
123
|
-
"version": "ES6+",
|
|
124
|
-
"directory": "src",
|
|
125
|
-
"extension": ".js"
|
|
126
|
-
}
|
|
127
|
-
],
|
|
128
|
-
"frameworks": [
|
|
129
|
-
{
|
|
130
|
-
"name": "Node.js",
|
|
131
|
-
"type": "Runtime environment",
|
|
132
|
-
"primary": true,
|
|
133
|
-
"directory": "src",
|
|
134
|
-
"extension": ".js"
|
|
135
|
-
}
|
|
136
|
-
],
|
|
137
|
-
"testingFrameworks": [
|
|
138
|
-
{
|
|
139
|
-
"name": "Jest",
|
|
140
|
-
"type": "Testing framework",
|
|
141
|
-
"version": "29.7.0"
|
|
142
|
-
"directory": "tests"
|
|
143
|
-
"runCommand": "yarn test"
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
"buildTools": [
|
|
147
|
-
{
|
|
148
|
-
"name": "TypeScript Compiler (tsc)",
|
|
149
|
-
"type": "Transpiler"
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
"name": "Vite",
|
|
153
|
-
"type": "Build tool",
|
|
154
|
-
"version": "5.3.3"
|
|
155
|
-
}
|
|
156
|
-
],
|
|
157
|
-
"packageManager": "Yarn",
|
|
158
|
-
"linters": [
|
|
159
|
-
{
|
|
160
|
-
"name": "ESLint",
|
|
161
|
-
"version": "9.6.0"
|
|
162
|
-
}
|
|
163
|
-
],
|
|
164
|
-
"databases": [
|
|
165
|
-
{
|
|
166
|
-
"name": "MongoDB",
|
|
167
|
-
"version": "5.0.3",
|
|
168
|
-
"primary": true
|
|
169
|
-
}
|
|
170
|
-
],
|
|
171
|
-
"projectType": "Command-line tool",
|
|
172
|
-
}`;
|
|
173
|
-
exports.SPECIAL_FILES = [
|
|
174
|
-
'package.json',
|
|
175
|
-
'Gemfile',
|
|
176
|
-
'requirements.txt',
|
|
177
|
-
'Pipfile',
|
|
178
|
-
'pyproject.toml',
|
|
179
|
-
'pom.xml',
|
|
180
|
-
'build.gradle',
|
|
181
|
-
'.csproj',
|
|
182
|
-
'packages.config',
|
|
183
|
-
'composer.json',
|
|
184
|
-
'CMakeLists.txt',
|
|
185
|
-
'conanfile.txt',
|
|
186
|
-
'conanfile.py',
|
|
187
|
-
'go.mod',
|
|
188
|
-
'Cargo.toml',
|
|
189
|
-
'Package.swift',
|
|
190
|
-
'build.gradle.kts',
|
|
191
|
-
'Podfile',
|
|
192
|
-
'Cartfile',
|
|
193
|
-
'cpanfile',
|
|
194
|
-
'DESCRIPTION',
|
|
195
|
-
'mix.exs',
|
|
196
|
-
'build.sbt',
|
|
197
|
-
'pubspec.yaml',
|
|
198
|
-
'stack.yaml',
|
|
199
|
-
'top.sls',
|
|
200
|
-
'requirements.yml',
|
|
201
|
-
'terraform.tf',
|
|
202
|
-
'versions.tf',
|
|
203
|
-
'main.yml',
|
|
204
|
-
'cabal.project',
|
|
205
|
-
'Project.toml',
|
|
206
|
-
'rockspec',
|
|
207
|
-
'rebar.config',
|
|
208
|
-
'project.clj',
|
|
209
|
-
'tsconfig.json',
|
|
210
|
-
'.eslintrc.js',
|
|
211
|
-
'.eslintrc.json',
|
|
212
|
-
'.eslintrc.yaml',
|
|
213
|
-
'.eslintrc.yml',
|
|
214
|
-
'.eslintrc',
|
|
215
|
-
'.prettierrc',
|
|
216
|
-
'.prettierrc.js',
|
|
217
|
-
'.prettierrc.json',
|
|
218
|
-
'.prettierrc.yaml',
|
|
219
|
-
'.prettierrc.yml',
|
|
220
|
-
'.prettierrc',
|
|
221
|
-
'.stylelintrc',
|
|
222
|
-
'.stylelintrc.json',
|
|
223
|
-
'.stylelintrc.yaml',
|
|
224
|
-
'.stylelintrc.yml',
|
|
225
|
-
'.stylelintrc',
|
|
226
|
-
'jest.config.js',
|
|
227
|
-
'jest.config.json',
|
|
228
|
-
'jest.config.ts',
|
|
229
|
-
'jest.config.cjs',
|
|
230
|
-
'jest.config.mjs',
|
|
231
|
-
'webpack.config.js',
|
|
232
|
-
'webpack.config.ts',
|
|
233
|
-
'webpack.config.cjs',
|
|
234
|
-
'webpack.config.mjs',
|
|
235
|
-
'webpack.config.common.js',
|
|
236
|
-
];
|
|
18
|
+
const prompts_1 = require("./prompts");
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves the package version from package.json.
|
|
21
|
+
* @returns {string} The version of the package.
|
|
22
|
+
*/
|
|
237
23
|
const getPackageVersion = () => {
|
|
238
24
|
const packagePath = (0, path_2.join)(__dirname, '..', 'package.json');
|
|
239
25
|
const packageJson = JSON.parse(fs_1.default.readFileSync(packagePath, 'utf8'));
|
|
240
26
|
return packageJson.version;
|
|
241
27
|
};
|
|
242
28
|
exports.getPackageVersion = getPackageVersion;
|
|
29
|
+
/**
|
|
30
|
+
* Renders a context file as a string.
|
|
31
|
+
* @param {Record<string, unknown> | string} contextFile - The context file to render.
|
|
32
|
+
* @returns {string} The rendered string representation of the context file.
|
|
33
|
+
*/
|
|
243
34
|
const renderAsString = (contextFile) => {
|
|
244
35
|
if (typeof contextFile === 'string') {
|
|
245
36
|
return contextFile;
|
|
246
37
|
}
|
|
247
38
|
return JSON.stringify(contextFile, null, 2);
|
|
248
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Generates a prompt for code generation based on context files and special files.
|
|
42
|
+
* @param {Record<string, string>} contextFilesContent - The content of context files.
|
|
43
|
+
* @returns {string} The generated prompt for code generation.
|
|
44
|
+
*/
|
|
249
45
|
const generateCodegenPrompt = (contextFilesContent) => {
|
|
250
46
|
const specialFileContents = (0, exports.collectSpecialFileContents)();
|
|
251
47
|
// detect if specialFileContents[file] is a string or an object
|
|
@@ -255,7 +51,7 @@ const generateCodegenPrompt = (contextFilesContent) => {
|
|
|
255
51
|
const contextFileContents = Object.keys(contextFilesContent)
|
|
256
52
|
.map((file) => `### Contents of **${file}**\n\n\`\`\`\n${contextFilesContent[file]}\n\`\`\`\n\n`)
|
|
257
53
|
.join('\n');
|
|
258
|
-
const prompt = `${
|
|
54
|
+
const prompt = `${prompts_1.CODEGEN_INSTRUCTIONS}
|
|
259
55
|
|
|
260
56
|
## Description of App
|
|
261
57
|
|
|
@@ -275,112 +71,99 @@ ${contextFileContents.length > 0 ? contextFileContents : 'No context files provi
|
|
|
275
71
|
|
|
276
72
|
${Object.keys(contextFilesContent).join('\n')}
|
|
277
73
|
|
|
278
|
-
${
|
|
279
|
-
|
|
280
|
-
### Example 1: Changing a Variable
|
|
281
|
-
|
|
282
|
-
\`\`\`typescript
|
|
283
|
-
<<<<<<< CURRENT path/to/file.ts
|
|
284
|
-
const myVariable = 'exact'
|
|
285
|
-
const oldVariable = 1
|
|
286
|
-
=======
|
|
287
|
-
const myVariable = 'exact'
|
|
288
|
-
const newVariable = 2
|
|
289
|
-
>>>>>>> NEW
|
|
290
|
-
\`\`\`
|
|
291
|
-
|
|
292
|
-
### Example 2: Create a New File
|
|
293
|
-
|
|
294
|
-
\`\`\`ruby
|
|
295
|
-
<<<<<<< CURRENT path/to/newfile.rb
|
|
296
|
-
=======
|
|
297
|
-
def new_function
|
|
298
|
-
puts 'Hello, world!'
|
|
299
|
-
end
|
|
300
|
-
>>>>>>> NEW
|
|
301
|
-
\`\`\`
|
|
302
|
-
|
|
303
|
-
### Example 3: Moving a Function
|
|
304
|
-
|
|
305
|
-
Removing it from path/to/file.py
|
|
306
|
-
|
|
307
|
-
\`\`\`python
|
|
308
|
-
<<<<<<< CURRENT path/to/file.py
|
|
309
|
-
def old_function():
|
|
310
|
-
return 'Old function'
|
|
311
|
-
=======
|
|
312
|
-
>>>>>>> NEW
|
|
313
|
-
\`\`\`
|
|
74
|
+
${prompts_1.CODEGEN_INSTRUCTIONS}
|
|
314
75
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
76
|
+
${prompts_1.CODEGEN_EXAMPLES}`;
|
|
77
|
+
return prompt;
|
|
78
|
+
};
|
|
79
|
+
exports.generateCodegenPrompt = generateCodegenPrompt;
|
|
80
|
+
/**
|
|
81
|
+
* Generates a prompt for documentation generation based on context files and special files.
|
|
82
|
+
* @param {Record<string, string>} contextFilesContent - The content of context files.
|
|
83
|
+
* @returns {string} The generated prompt for documentation generation.
|
|
84
|
+
*/
|
|
85
|
+
const generateDocsPrompt = (contextFilesContent) => {
|
|
86
|
+
const specialFileContents = (0, exports.collectSpecialFileContents)();
|
|
87
|
+
const specialFiles = Object.keys(specialFileContents)
|
|
88
|
+
.map((file) => `### Contents of **${file}**\n\n\`\`\`\n${renderAsString(specialFileContents[file])}\n\`\`\`\n\n`)
|
|
89
|
+
.join('\n');
|
|
90
|
+
const contextFileContents = Object.keys(contextFilesContent)
|
|
91
|
+
.map((file) => `### Contents of **${file}**\n\n\`\`\`\n${contextFilesContent[file]}\n\`\`\`\n\n`)
|
|
92
|
+
.join('\n');
|
|
93
|
+
const prompt = `${prompts_1.DOCS_INSTRUCTIONS}
|
|
321
94
|
|
|
322
|
-
|
|
323
|
-
def existing_function():
|
|
324
|
-
return 'Existing function'
|
|
95
|
+
${prompts_1.CODEGEN_INSTRUCTIONS}
|
|
325
96
|
|
|
326
|
-
|
|
327
|
-
return 'Old function'
|
|
328
|
-
>>>>>>> NEW
|
|
329
|
-
\`\`\`
|
|
97
|
+
${prompts_1.CODEGEN_EXAMPLES}
|
|
330
98
|
|
|
331
|
-
|
|
99
|
+
## Description of App
|
|
332
100
|
|
|
333
|
-
\`\`\`
|
|
334
|
-
|
|
335
|
-
public void oldFunction() {
|
|
336
|
-
System.out.println("Old function")
|
|
337
|
-
}
|
|
338
|
-
=======
|
|
339
|
-
>>>>>>> NEW
|
|
101
|
+
\`\`\`json
|
|
102
|
+
${JSON.stringify((0, config_utils_1.getClovingConfig)(), null, 2)}
|
|
340
103
|
\`\`\`
|
|
341
104
|
|
|
342
|
-
|
|
105
|
+
## Special Files
|
|
343
106
|
|
|
344
|
-
|
|
107
|
+
${specialFiles.length > 0 ? specialFiles : 'No special files provided.'}
|
|
345
108
|
|
|
346
|
-
|
|
347
|
-
<<<<<<< CURRENT path/to/file.rb
|
|
348
|
-
=======
|
|
349
|
-
def new_function
|
|
350
|
-
puts 'Hello, world!'
|
|
351
|
-
end
|
|
352
|
-
>>>>>>> NEW
|
|
353
|
-
\`\`\`
|
|
109
|
+
## Context Files
|
|
354
110
|
|
|
355
|
-
|
|
111
|
+
${contextFileContents.length > 0 ? contextFileContents : 'No context files provided.'}
|
|
356
112
|
|
|
357
|
-
|
|
113
|
+
## Directory structure
|
|
358
114
|
|
|
359
|
-
|
|
115
|
+
${Object.keys(contextFilesContent).join('\n')}
|
|
360
116
|
|
|
361
|
-
|
|
117
|
+
${prompts_1.DOCS_INSTRUCTIONS}`;
|
|
362
118
|
return prompt;
|
|
363
119
|
};
|
|
364
|
-
exports.
|
|
120
|
+
exports.generateDocsPrompt = generateDocsPrompt;
|
|
121
|
+
/**
|
|
122
|
+
* Generates a prompt for shell commands based on the current shell and OS.
|
|
123
|
+
* @returns {string} The generated prompt for shell commands.
|
|
124
|
+
*/
|
|
365
125
|
const generateShellPrompt = () => {
|
|
366
126
|
const shell = (0, child_process_1.execSync)('echo $SHELL').toString().trim();
|
|
367
127
|
const os = (0, child_process_1.execSync)('echo $OSTYPE').toString().trim();
|
|
368
|
-
return
|
|
128
|
+
return `${prompts_1.SHELL_INSTRUCTIONS}\n\n## Context\n\nShell: ${shell}\n\nOS: ${os}`;
|
|
129
|
+
};
|
|
130
|
+
exports.generateShellPrompt = generateShellPrompt;
|
|
131
|
+
const generateReviewPrompt = (options, contextFiles) => {
|
|
132
|
+
let prompt = `${prompts_1.REVIEW_INSTRUCTIONS}`;
|
|
133
|
+
if (options.files) {
|
|
134
|
+
const contextFileContents = Object.keys(contextFiles)
|
|
135
|
+
.map((file) => `### Contents of ${file}\n\n${contextFiles[file]}\n\n`)
|
|
136
|
+
.join('\n');
|
|
137
|
+
prompt += `### Description of App
|
|
138
|
+
|
|
139
|
+
${JSON.stringify((0, config_utils_1.getClovingConfig)(), null, 2)}
|
|
369
140
|
|
|
370
|
-
|
|
141
|
+
${contextFileContents}
|
|
371
142
|
|
|
372
|
-
|
|
143
|
+
### Request
|
|
373
144
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
145
|
+
I would like you to explain the code and document a description of it.
|
|
146
|
+
List any bugs in the new code as well as recommended fixes for those bugs with code examples.
|
|
147
|
+
Format the output of this code review in Markdown format.`;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
prompt += `### Request
|
|
377
151
|
|
|
378
|
-
|
|
152
|
+
Do not use any data from the example response structure, only use the structure.
|
|
153
|
+
I would like you to explain why these change are being made and document a description of these changes.
|
|
154
|
+
Also list any bugs in the new code as well as recommended fixes for those bugs with code examples.
|
|
155
|
+
Format the output of this code review in Markdown format.`;
|
|
156
|
+
}
|
|
157
|
+
return prompt;
|
|
379
158
|
};
|
|
380
|
-
exports.
|
|
159
|
+
exports.generateReviewPrompt = generateReviewPrompt;
|
|
160
|
+
/**
|
|
161
|
+
* Collects the contents of special files.
|
|
162
|
+
* @returns {Record<string, string | Record<string, unknown>>} An object containing the contents of special files.
|
|
163
|
+
*/
|
|
381
164
|
const collectSpecialFileContents = () => {
|
|
382
165
|
const specialFileContents = {};
|
|
383
|
-
for (const file of
|
|
166
|
+
for (const file of prompts_1.SPECIAL_FILES) {
|
|
384
167
|
if (fs_1.default.existsSync(file)) {
|
|
385
168
|
try {
|
|
386
169
|
const content = fs_1.default.readFileSync(file, 'utf-8');
|
|
@@ -394,8 +177,17 @@ const collectSpecialFileContents = () => {
|
|
|
394
177
|
return specialFileContents;
|
|
395
178
|
};
|
|
396
179
|
exports.collectSpecialFileContents = collectSpecialFileContents;
|
|
397
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Checks if any special files exist in the current directory.
|
|
182
|
+
* @returns {boolean} True if any special files exist, false otherwise.
|
|
183
|
+
*/
|
|
184
|
+
const checkForSpecialFiles = () => prompts_1.SPECIAL_FILES.some((file) => fs_1.default.existsSync(file));
|
|
398
185
|
exports.checkForSpecialFiles = checkForSpecialFiles;
|
|
186
|
+
/**
|
|
187
|
+
* Recursively gets all non-binary files in a directory.
|
|
188
|
+
* @param {string} dir - The directory to search.
|
|
189
|
+
* @returns {Promise<string[]>} A promise that resolves with an array of file paths.
|
|
190
|
+
*/
|
|
399
191
|
const getAllFilesInDirectory = async (dir) => {
|
|
400
192
|
const subdirs = await fs_1.default.promises.readdir(dir);
|
|
401
193
|
const files = await Promise.all(subdirs.map(async (subdir) => {
|
|
@@ -415,6 +207,10 @@ const getAllFilesInDirectory = async (dir) => {
|
|
|
415
207
|
return files.flat();
|
|
416
208
|
};
|
|
417
209
|
exports.getAllFilesInDirectory = getAllFilesInDirectory;
|
|
210
|
+
/**
|
|
211
|
+
* Generates a list of files in the current directory and its subdirectories.
|
|
212
|
+
* @returns {Promise<string[]>} A promise that resolves with an array of file paths.
|
|
213
|
+
*/
|
|
418
214
|
const generateFileList = async () => {
|
|
419
215
|
try {
|
|
420
216
|
const lsOutput = await (0, exports.runCommand)('ls', []);
|
|
@@ -430,6 +226,12 @@ const generateFileList = async () => {
|
|
|
430
226
|
}
|
|
431
227
|
};
|
|
432
228
|
exports.generateFileList = generateFileList;
|
|
229
|
+
/**
|
|
230
|
+
* Runs a shell command and returns its output.
|
|
231
|
+
* @param {string} command - The command to run.
|
|
232
|
+
* @param {string[]} args - The arguments for the command.
|
|
233
|
+
* @returns {Promise<string[]>} A promise that resolves with an array of output lines.
|
|
234
|
+
*/
|
|
433
235
|
const runCommand = (command, args) => {
|
|
434
236
|
return new Promise((resolve, reject) => {
|
|
435
237
|
const process = (0, child_process_1.spawn)(command, args);
|
|
@@ -451,6 +253,10 @@ const runCommand = (command, args) => {
|
|
|
451
253
|
});
|
|
452
254
|
};
|
|
453
255
|
exports.runCommand = runCommand;
|
|
256
|
+
/**
|
|
257
|
+
* Fetches available models using the 'cloving models' command.
|
|
258
|
+
* @returns {Promise<string[]>} A promise that resolves with an array of available models.
|
|
259
|
+
*/
|
|
454
260
|
const fetchModels = async () => {
|
|
455
261
|
try {
|
|
456
262
|
const modelsOutput = await (0, exports.runCommand)('cloving', ['models']);
|
|
@@ -462,6 +268,11 @@ const fetchModels = async () => {
|
|
|
462
268
|
}
|
|
463
269
|
};
|
|
464
270
|
exports.fetchModels = fetchModels;
|
|
271
|
+
/**
|
|
272
|
+
* Reads the content of a file.
|
|
273
|
+
* @param {string} file - The path to the file.
|
|
274
|
+
* @returns {string} The content of the file.
|
|
275
|
+
*/
|
|
465
276
|
const readFileContent = (file) => {
|
|
466
277
|
try {
|
|
467
278
|
return fs_1.default.readFileSync(file, 'utf-8');
|
|
@@ -494,6 +305,13 @@ const addDirectoryToContext = async (dirPath, contextFiles, baseDir) => {
|
|
|
494
305
|
}
|
|
495
306
|
}
|
|
496
307
|
};
|
|
308
|
+
/**
|
|
309
|
+
* Adds a file or directory to the context.
|
|
310
|
+
* @param {string} contextFile - The path to the file or directory to add.
|
|
311
|
+
* @param {Record<string, string>} contextFiles - The current context files.
|
|
312
|
+
* @param {Record<string, any>} options - Additional options.
|
|
313
|
+
* @returns {Promise<Record<string, string>>} A promise that resolves with the updated context files.
|
|
314
|
+
*/
|
|
497
315
|
const addFileOrDirectoryToContext = async (contextFile, contextFiles, options) => {
|
|
498
316
|
const filePath = path_1.default.resolve(contextFile);
|
|
499
317
|
const baseDir = process.cwd();
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
## Code Generation Failed
|
|
2
|
+
|
|
3
|
+
Some of the provided code blocks could not be applied, please match the existing code with a few more lines of context and make sure it is a character for character exact match. Never use "rest of the existing code" or "rest of the code" in your response, instead break the code block into smaller blocks.
|
|
4
|
+
|
|
5
|
+
## Details
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
### Example 1: Changing a Variable
|
|
2
|
+
|
|
3
|
+
```typescript
|
|
4
|
+
<<<<<<< CURRENT path/to/file.ts
|
|
5
|
+
const myVariable = 'exact'
|
|
6
|
+
const oldVariable = 1
|
|
7
|
+
=======
|
|
8
|
+
const myVariable = 'exact'
|
|
9
|
+
const newVariable = 2
|
|
10
|
+
>>>>>>> NEW
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Example 2: Create a New File
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
<<<<<<< CURRENT path/to/newfile.rb
|
|
17
|
+
=======
|
|
18
|
+
def new_function
|
|
19
|
+
puts 'Hello, world!'
|
|
20
|
+
end
|
|
21
|
+
>>>>>>> NEW
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Example 3: Moving a Function
|
|
25
|
+
|
|
26
|
+
Removing it from path/to/file.py
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
<<<<<<< CURRENT path/to/file.py
|
|
30
|
+
def old_function():
|
|
31
|
+
return 'Old function'
|
|
32
|
+
=======
|
|
33
|
+
>>>>>>> NEW
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Adding it to path/to/newfile.py
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
<<<<<<< CURRENT path/to/newfile.py
|
|
40
|
+
def existing_function():
|
|
41
|
+
return 'Existing function'
|
|
42
|
+
|
|
43
|
+
=======
|
|
44
|
+
def existing_function():
|
|
45
|
+
return 'Existing function'
|
|
46
|
+
|
|
47
|
+
def old_function():
|
|
48
|
+
return 'Old function'
|
|
49
|
+
>>>>>>> NEW
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Example 4: Removing a Function
|
|
53
|
+
|
|
54
|
+
```java
|
|
55
|
+
<<<<<<< CURRENT path/to/file.java
|
|
56
|
+
public void oldFunction() {
|
|
57
|
+
System.out.println("Old function")
|
|
58
|
+
}
|
|
59
|
+
=======
|
|
60
|
+
>>>>>>> NEW
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Example 5: Replace a file
|
|
64
|
+
|
|
65
|
+
This will replace the entire contents of **path/to/file.rb** with the new content:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
<<<<<<< CURRENT path/to/file.rb
|
|
69
|
+
=======
|
|
70
|
+
def new_function
|
|
71
|
+
puts 'Hello, world!'
|
|
72
|
+
end
|
|
73
|
+
>>>>>>> NEW
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Don't Invent Code That Isn't Provided in Context
|
|
77
|
+
|
|
78
|
+
A file might be referenced by just the file name without the full path, but the code must be provided in the *Context Files* section.
|
|
79
|
+
|
|
80
|
+
Unless you believe you are creating a whole new file, never ever under any circumstances make up code in the CURRENT block that was not provided to you in the *Context Files* section.
|
|
81
|
+
|
|
82
|
+
If a required file hasn't been provided in the *Context Files* section, stop everything and ask the user to provide it in the context by adding -f path/to/file to the command or add path/to/file in the interactive chat.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# AI Code Generation Instructions
|
|
2
|
+
|
|
3
|
+
## General Guidelines
|
|
4
|
+
|
|
5
|
+
1. **Respond as an expert software developer.**
|
|
6
|
+
2. **Follow best practices and the latest standards found in the **Description of App** section.**
|
|
7
|
+
3. **Adhere to existing conventions and libraries in the codebase.**
|
|
8
|
+
|
|
9
|
+
## Request Handling
|
|
10
|
+
|
|
11
|
+
1. **Try to understand the request, but if anything is unclear, ask questions.**
|
|
12
|
+
2. **Decide if you need to propose edits to existing files not in the chat.**
|
|
13
|
+
- If yes, provide the full path names and ask the user to add them.
|
|
14
|
+
- Wait for user approval before proceeding.
|
|
15
|
+
3. **Propose changes using *CURRENT/NEW* Blocks.**
|
|
16
|
+
4. **Show the smallest possible *CURRENT* section that uniquely identifies the code.**
|
|
17
|
+
5. **To move code, use two *CURRENT/NEW* blocks: one to remove and one to add.**
|
|
18
|
+
6. **For new files or to replace an existing file, the *CURRENT* block is empty.**
|
|
19
|
+
|
|
20
|
+
## *CURRENT/NEW* Block Format
|
|
21
|
+
|
|
22
|
+
1. **Start a block with a one line description of change**
|
|
23
|
+
1. **Then provide three backticks and the language name.**
|
|
24
|
+
```typescript
|
|
25
|
+
2. **Next line: seven <, CURRENT, and the file path.**
|
|
26
|
+
<<<<<<< CURRENT path/to/file.ts
|
|
27
|
+
3. **Include the exact existing code to be changed, this section should always have some code characters in it, not just spaces or tabs. The only exception is when creating a brand new file.**
|
|
28
|
+
4. **Divide with seven =.**
|
|
29
|
+
=======
|
|
30
|
+
5. **Add the new code.**
|
|
31
|
+
6. **End with seven > and NEW.**
|
|
32
|
+
>>>>>>> NEW
|
|
33
|
+
7. **Close the block with three backticks.**
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Don't Invent Code That Isn't Provided in Context
|
|
37
|
+
|
|
38
|
+
A file might be referenced by just the file name without the full path, but the code must be provided in the *Context Files* section.
|
|
39
|
+
|
|
40
|
+
Unless you believe you are creating a whole new file, never ever under any circumstances make up code in the CURRENT block that was not provided to you in the *Context Files* section.
|
|
41
|
+
|
|
42
|
+
If a required file hasn't been provided in the *Context Files* section, stop everything and ask the user to provide it in the context by adding -f path/to/file to the command or add path/to/file in the interactive chat.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## Documentation Instructions
|
|
2
|
+
|
|
3
|
+
Add documentation to the files in context. Provide the updated files with added documentation using the CURRENT/NEW block format. Only include the parts of the files that have changed.
|
|
4
|
+
Add or update documentation comments for each function, class, and module definition as appropriate. Use the standard documentation format for the respective language (e.g., JSDoc for JavaScript/TypeScript, docstrings for Python, etc.).
|
|
5
|
+
|
|
6
|
+
### Note
|
|
7
|
+
|
|
8
|
+
Whenever possible, break up the changes into pieces and make sure every change is in its own CURRENT / NEW block.
|
|
9
|
+
Do not allow empty CURRENT blocks and if you add content to the CURRENT block, you also have to add the same content to the NEW block.`
|