cloving 0.3.13 → 0.3.14
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/index.js +0 -0
- package/dist/managers/ChatManager.js +0 -1
- package/dist/package.json +1 -1
- package/package.json +1 -1
- package/dist/abstract_gpt/index.js +0 -55
- package/dist/cloving_gpt/adapters/Adapter.js +0 -2
- package/dist/cloving_gpt/adapters/gpt4all.js +0 -29
- package/dist/commands/analyze.js +0 -47
- package/dist/commands/check.js +0 -7
- package/dist/commands/commit.js +0 -44
- package/dist/commands/describe.js +0 -235
- package/dist/commands/generate/documentation.js +0 -11
- package/dist/commands/generate/fizzbuzz.js +0 -35
- package/dist/commands/generate/init.js +0 -15
- package/dist/commands/generate/sh.js +0 -95
- package/dist/commands/project/build.js +0 -88
- package/dist/commands/project/complete.js +0 -12
- package/dist/commands/project/init.js +0 -82
- package/dist/commands/project/plan.js +0 -108
- package/dist/commands/review.js +0 -50
- package/dist/commands/unit_tests.js +0 -150
- package/dist/commands/update.js +0 -7
- package/dist/file2.js +0 -4
- package/dist/managers/DocumentationManager.js +0 -114
- package/dist/managers/src/managers/ProxyManager.js +0 -1
- package/dist/newfile.js +0 -2
- package/dist/utils/command_utils.js +0 -384
- package/dist/utils/gitUtils.js +0 -42
- package/dist/utils/modelUtils.js +0 -7
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.buildProject = void 0;
|
|
7
|
-
const copy_paste_1 = __importDefault(require("copy-paste"));
|
|
8
|
-
const fs_1 = require("fs");
|
|
9
|
-
const cli_highlight_1 = __importDefault(require("cli-highlight"));
|
|
10
|
-
const prompts_1 = require("@inquirer/prompts");
|
|
11
|
-
const cloving_gpt_1 = __importDefault(require("../../cloving_gpt"));
|
|
12
|
-
const config_utils_1 = require("../../utils/config_utils");
|
|
13
|
-
const git_utils_1 = require("../../utils/git_utils");
|
|
14
|
-
const string_utils_1 = require("../../utils/string_utils");
|
|
15
|
-
const generatePrompt = async (projectName, projectTask, filesList, incompletePlanItem) => {
|
|
16
|
-
const context = [];
|
|
17
|
-
for (const codeFile of filesList) {
|
|
18
|
-
if (await fs_1.promises?.stat(codeFile).then(stat => stat.isFile()).catch(() => false)) {
|
|
19
|
-
const fileContents = await fs_1.promises.readFile(codeFile, 'utf-8');
|
|
20
|
-
context.push(`### **Contents of ${codeFile}**\n\n${fileContents}\n\n### **End of ${codeFile}**`);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return `==== begin task description ====
|
|
24
|
-
Task name: ${projectName}
|
|
25
|
-
Task description: ${projectTask}
|
|
26
|
-
==== end task description ====
|
|
27
|
-
|
|
28
|
-
${context}
|
|
29
|
-
|
|
30
|
-
Please implement the following plan item, please include full file path names in all code snippets:
|
|
31
|
-
|
|
32
|
-
${incompletePlanItem}`;
|
|
33
|
-
};
|
|
34
|
-
const buildProject = async (options) => {
|
|
35
|
-
options.silent = (0, config_utils_1.getConfig)(options).globalSilent || false;
|
|
36
|
-
const gpt = new cloving_gpt_1.default(options);
|
|
37
|
-
const projectName = (0, git_utils_1.getCurrentBranchName)();
|
|
38
|
-
const projectConfig = (0, config_utils_1.getProjectConfig)(projectName);
|
|
39
|
-
// Filter out completed plan items for selection
|
|
40
|
-
const planItems = Object.entries(projectConfig.plan || {});
|
|
41
|
-
if (planItems.length === 0) {
|
|
42
|
-
console.log('No plan items found.');
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
// Use @inquirer/prompts to select a plan item
|
|
46
|
-
const selectedPlanItemKey = await (0, prompts_1.select)({
|
|
47
|
-
message: 'Select a plan item:',
|
|
48
|
-
choices: planItems.map(([key, item]) => ({ name: key, value: key })),
|
|
49
|
-
});
|
|
50
|
-
const selectedPlanItem = planItems.find(([key]) => key === selectedPlanItemKey);
|
|
51
|
-
if (!selectedPlanItem) {
|
|
52
|
-
console.log('Selected plan item not found.');
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
const planText = `## **${selectedPlanItem[0]}**\n\n${selectedPlanItem[1].details.join('\n\n')}`;
|
|
56
|
-
const prompt = await generatePrompt(projectName, projectConfig.task, projectConfig.files || [], planText);
|
|
57
|
-
const projectCode = await gpt.generateText({ prompt });
|
|
58
|
-
(0, string_utils_1.parseMarkdownInstructions)(projectCode).map(code => {
|
|
59
|
-
if (code.trim().startsWith('```')) {
|
|
60
|
-
const lines = code.split('\n');
|
|
61
|
-
const language = code.match(/```(\w+)/)?.[1] || 'plaintext';
|
|
62
|
-
console.log(lines[0]);
|
|
63
|
-
try {
|
|
64
|
-
console.log((0, cli_highlight_1.default)(lines.slice(1, -1).join('\n'), { language }));
|
|
65
|
-
}
|
|
66
|
-
catch (error) {
|
|
67
|
-
// don't highlight if it fails
|
|
68
|
-
console.log(lines.slice(1, -1).join('\n'));
|
|
69
|
-
}
|
|
70
|
-
console.log(lines.slice(-1)[0]);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
console.log((0, cli_highlight_1.default)(code, { language: 'markdown' }));
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
// Prompt the user to copy the project to the clipboard using @inquirer/prompts
|
|
77
|
-
const copyToClipboard = await (0, prompts_1.confirm)({
|
|
78
|
-
message: 'Do you want to copy this project to the clipboard?',
|
|
79
|
-
default: true,
|
|
80
|
-
});
|
|
81
|
-
if (copyToClipboard) {
|
|
82
|
-
copy_paste_1.default.copy(projectCode, () => {
|
|
83
|
-
console.log('Project copied to clipboard');
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
exports.buildProject = buildProject;
|
|
88
|
-
exports.default = exports.buildProject;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.completeProject = void 0;
|
|
4
|
-
const config_utils_1 = require("../../utils/config_utils");
|
|
5
|
-
const git_utils_1 = require("../../utils/git_utils");
|
|
6
|
-
const completeProject = async (options) => {
|
|
7
|
-
options.silent = (0, config_utils_1.getConfig)(options).globalSilent || false;
|
|
8
|
-
const projectName = (0, git_utils_1.getCurrentBranchName)();
|
|
9
|
-
(0, config_utils_1.removeProjectConfig)(projectName);
|
|
10
|
-
};
|
|
11
|
-
exports.completeProject = completeProject;
|
|
12
|
-
exports.default = exports.completeProject;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.initProject = void 0;
|
|
7
|
-
const fs_1 = require("fs");
|
|
8
|
-
const prompts_1 = require("@inquirer/prompts");
|
|
9
|
-
const cloving_gpt_1 = __importDefault(require("../../cloving_gpt"));
|
|
10
|
-
const config_utils_1 = require("../../utils/config_utils");
|
|
11
|
-
const git_utils_1 = require("../../utils/git_utils");
|
|
12
|
-
const config_utils_2 = require("../../utils/config_utils");
|
|
13
|
-
const generatePrompt = async (projectName, projectTask) => {
|
|
14
|
-
const filesList = await (0, config_utils_2.getAllFiles)({}, false);
|
|
15
|
-
return `Here is a description of my app:
|
|
16
|
-
|
|
17
|
-
${JSON.stringify((0, config_utils_2.getClovingConfig)(), null, 2)}
|
|
18
|
-
|
|
19
|
-
Here is a list of all my source files:
|
|
20
|
-
|
|
21
|
-
==== begin list of source files ====
|
|
22
|
-
${filesList.join("\n")}
|
|
23
|
-
==== end list of source files ====
|
|
24
|
-
|
|
25
|
-
Please enumerate all the files in the provided list that are pertinent for this task:
|
|
26
|
-
|
|
27
|
-
==== begin task description ====
|
|
28
|
-
Task name: ${projectName}
|
|
29
|
-
Task description: ${projectTask}
|
|
30
|
-
==== end task description ====
|
|
31
|
-
|
|
32
|
-
Also, list any test files that might be relevant to these files.
|
|
33
|
-
|
|
34
|
-
Give me this output format for your answer:
|
|
35
|
-
|
|
36
|
-
## files
|
|
37
|
-
|
|
38
|
-
app/models/foo.rb
|
|
39
|
-
app/views/baz/bar.html.erb
|
|
40
|
-
|
|
41
|
-
## relevant test files
|
|
42
|
-
|
|
43
|
-
test/models/foo_test.rb
|
|
44
|
-
test/controllers/baz_controller_test.rb`;
|
|
45
|
-
};
|
|
46
|
-
const initProject = async (options) => {
|
|
47
|
-
options.silent = (0, config_utils_1.getConfig)(options).globalSilent || false;
|
|
48
|
-
const gpt = new cloving_gpt_1.default(options);
|
|
49
|
-
const defaultBranchName = await (0, git_utils_1.getDefaultBranchName)();
|
|
50
|
-
const projectName = (0, git_utils_1.getCurrentBranchName)();
|
|
51
|
-
if (projectName === defaultBranchName) {
|
|
52
|
-
console.log(`You are on the ${defaultBranchName} branch. Please checkout to a git branch and try again. For example: git branch -b my-new-project`);
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
const projectTask = await (0, prompts_1.input)({
|
|
56
|
-
message: 'Describe the task you want to accomplish with this project:',
|
|
57
|
-
});
|
|
58
|
-
const prompt = await generatePrompt(projectName, projectTask);
|
|
59
|
-
const contextFiles = await gpt.generateText({ prompt });
|
|
60
|
-
// Initialize variables
|
|
61
|
-
const lines = [];
|
|
62
|
-
const files = [];
|
|
63
|
-
// Read each line of the context files
|
|
64
|
-
contextFiles.split('\n').forEach((line) => {
|
|
65
|
-
if (line.trim()) {
|
|
66
|
-
lines.push(line.trim());
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
for (const codeFile of lines) {
|
|
70
|
-
if (await fs_1.promises?.stat(codeFile).then(stat => stat.isFile()).catch(() => false)) {
|
|
71
|
-
files.push(codeFile);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
const projectConfig = {
|
|
75
|
-
name: projectName,
|
|
76
|
-
task: projectTask,
|
|
77
|
-
files
|
|
78
|
-
};
|
|
79
|
-
(0, config_utils_1.saveProjectConfig)(projectName, projectConfig);
|
|
80
|
-
};
|
|
81
|
-
exports.initProject = initProject;
|
|
82
|
-
exports.default = exports.initProject;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.planProject = void 0;
|
|
7
|
-
const fs_1 = require("fs");
|
|
8
|
-
const cloving_gpt_1 = __importDefault(require("../../cloving_gpt"));
|
|
9
|
-
const config_utils_1 = require("../../utils/config_utils");
|
|
10
|
-
const git_utils_1 = require("../../utils/git_utils");
|
|
11
|
-
const parsePlan = (plan) => {
|
|
12
|
-
const lines = plan.split('\n').map(line => line.trim());
|
|
13
|
-
const structured = {};
|
|
14
|
-
let currentTitle = null;
|
|
15
|
-
let currentDetails = [];
|
|
16
|
-
lines.forEach(line => {
|
|
17
|
-
const sectionMatch = line.match(/^#### \d+\. \*\*(.+)\*\*$/);
|
|
18
|
-
const detailMatch = line.match(/^-\s*\*\*(.+)\*\*:?\s*(.+)$/);
|
|
19
|
-
if (sectionMatch) {
|
|
20
|
-
if (currentTitle) {
|
|
21
|
-
structured[currentTitle] = {
|
|
22
|
-
details: currentDetails
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
currentTitle = sectionMatch[1];
|
|
26
|
-
currentDetails = [];
|
|
27
|
-
}
|
|
28
|
-
else if (detailMatch && currentDetails) {
|
|
29
|
-
currentDetails.push(`${detailMatch[1]}: ${detailMatch[2]}`);
|
|
30
|
-
}
|
|
31
|
-
else if (currentDetails && line.startsWith('- ')) {
|
|
32
|
-
currentDetails.push(line.replace(/^- /, ''));
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
if (currentTitle) {
|
|
36
|
-
structured[currentTitle] = {
|
|
37
|
-
details: currentDetails
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
return structured;
|
|
41
|
-
};
|
|
42
|
-
const generatePrompt = async (projectName, projectTask, filesList) => {
|
|
43
|
-
const context = [];
|
|
44
|
-
for (const codeFile of filesList) {
|
|
45
|
-
if (await fs_1.promises?.stat(codeFile).then(stat => stat.isFile()).catch(() => false)) {
|
|
46
|
-
const fileContents = await fs_1.promises.readFile(codeFile, 'utf-8');
|
|
47
|
-
context.push(`### **Contents of ${codeFile}**\n\n${fileContents}\n\n### **End of ${codeFile}**`);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return `==== begin task description ====
|
|
51
|
-
Task name: ${projectName}
|
|
52
|
-
Task description: ${projectTask}
|
|
53
|
-
==== end task description ====
|
|
54
|
-
|
|
55
|
-
${context}
|
|
56
|
-
|
|
57
|
-
Please create a plan to execute this project. Do not include the Implementation Steps. Only include Plan for Project Execution.
|
|
58
|
-
|
|
59
|
-
Here is an example plan. Do not use any of the information from this plan in your response, only use it as a template to create your own plan.
|
|
60
|
-
|
|
61
|
-
==== begin example plan ====
|
|
62
|
-
### Plan for Project Execution
|
|
63
|
-
|
|
64
|
-
#### 1. **Understanding Existing Code**
|
|
65
|
-
- **Review existing command implementations**: Familiarize yourself with the structure and implementation style of existing commands such as project init and project plan.
|
|
66
|
-
- **Identify utility functions**: Note the utility functions being used across the commands, such as those in config_utils, git_utils, and command_utils.
|
|
67
|
-
|
|
68
|
-
#### 2. **Design New Commands**
|
|
69
|
-
- **Define functionalities**: Clearly outline what each new command should accomplish:
|
|
70
|
-
- project build: This command should compile or prepare the project based on the planned actions.
|
|
71
|
-
- project complete: This command should finalize the project, possibly including cleanup, documentation, or deployment steps.
|
|
72
|
-
|
|
73
|
-
#### 3. **Implement project build**
|
|
74
|
-
- **Create build.ts**: Implement the logic for building the project.
|
|
75
|
-
- **Generate prompt**: Create a prompt that describes the build process based on the project configuration.
|
|
76
|
-
- **Invoke AI Model**: Use an AI model to generate the steps or scripts needed to build the project.
|
|
77
|
-
- **Execute Build Steps**: Implement logic to execute the build steps.
|
|
78
|
-
|
|
79
|
-
#### 4. **Implement project complete**
|
|
80
|
-
- **Create complete.ts**: Implement the logic for completing the project.
|
|
81
|
-
- **Generate prompt**: Create a prompt that describes the completion process based on the project configuration.
|
|
82
|
-
- **Invoke AI Model**: Use an AI model to generate the steps or scripts needed to complete the project.
|
|
83
|
-
- **Execute Completion Steps**: Implement logic to execute the completion steps.
|
|
84
|
-
|
|
85
|
-
#### 5. **Integration and Testing**
|
|
86
|
-
- **Integrate new commands**: Ensure the new commands are integrated into the existing command structure.
|
|
87
|
-
- **Unit tests**: Develop unit tests for the new commands to ensure they function correctly.
|
|
88
|
-
- **End-to-end tests**: Run end-to-end tests to validate the entire workflow from project initialization to completion.
|
|
89
|
-
|
|
90
|
-
#### 6. **Documentation and Cleanup**
|
|
91
|
-
- **Update README**: Document the new commands and their usage.
|
|
92
|
-
- **Code cleanup**: Refactor and clean up any redundant code or comments.
|
|
93
|
-
==== end example plan ====`;
|
|
94
|
-
};
|
|
95
|
-
const planProject = async (options) => {
|
|
96
|
-
options.silent = (0, config_utils_1.getConfig)(options).globalSilent || false;
|
|
97
|
-
const gpt = new cloving_gpt_1.default(options);
|
|
98
|
-
const projectName = (0, git_utils_1.getCurrentBranchName)();
|
|
99
|
-
const projectConfig = (0, config_utils_1.getProjectConfig)(projectName);
|
|
100
|
-
const prompt = await generatePrompt(projectName, projectConfig.task, projectConfig.files || []);
|
|
101
|
-
const projectPlan = await gpt.generateText({ prompt });
|
|
102
|
-
const planItems = parsePlan(projectPlan);
|
|
103
|
-
console.log(planItems);
|
|
104
|
-
projectConfig.plan = planItems;
|
|
105
|
-
(0, config_utils_1.saveProjectConfig)(projectName, projectConfig);
|
|
106
|
-
};
|
|
107
|
-
exports.planProject = planProject;
|
|
108
|
-
exports.default = exports.planProject;
|
package/dist/commands/review.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const readline_1 = __importDefault(require("readline"));
|
|
7
|
-
const child_process_1 = require("child_process");
|
|
8
|
-
const git_utils_1 = require("../utils/git_utils");
|
|
9
|
-
const string_utils_1 = require("../utils/string_utils");
|
|
10
|
-
const cloving_gpt_1 = __importDefault(require("../cloving_gpt"));
|
|
11
|
-
const config_utils_1 = require("../utils/config_utils");
|
|
12
|
-
const review = async (options) => {
|
|
13
|
-
options.silent = (0, config_utils_1.getConfig)(options).globalSilent || false;
|
|
14
|
-
const gpt = new cloving_gpt_1.default(options);
|
|
15
|
-
try {
|
|
16
|
-
// Define the prompt for analysis
|
|
17
|
-
const gitDiff = await (0, git_utils_1.getGitDiff)();
|
|
18
|
-
const prompt = `Explain why the change is being made and document a description of these changes.
|
|
19
|
-
Also list any bugs in the new code as well as recommended fixes for those bugs with code examples.
|
|
20
|
-
Format the output of this code review in Markdown format.
|
|
21
|
-
|
|
22
|
-
${gitDiff}`;
|
|
23
|
-
// get the analysis
|
|
24
|
-
const analysis = await gpt.generateText({ prompt });
|
|
25
|
-
const markdown = (0, string_utils_1.extractMarkdown)(analysis);
|
|
26
|
-
// Print the analysis to the console
|
|
27
|
-
console.log(markdown);
|
|
28
|
-
// Prompt the user to copy the analysis to the clipboard
|
|
29
|
-
const rl = readline_1.default.createInterface({
|
|
30
|
-
input: process.stdin,
|
|
31
|
-
output: process.stdout
|
|
32
|
-
});
|
|
33
|
-
rl.question('Do you want to copy the analysis to the clipboard? [Y/n] ', (answer) => {
|
|
34
|
-
if (answer.toLowerCase() === 'y' || answer === '') {
|
|
35
|
-
try {
|
|
36
|
-
(0, child_process_1.execFileSync)('pbcopy', { input: markdown });
|
|
37
|
-
console.log('Analysis copied to clipboard');
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
console.error('Error: pbcopy command not found. Unable to copy to clipboard.');
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
rl.close();
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
console.error('Error during analysis:', error.message);
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
exports.default = review;
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const fs_1 = require("fs");
|
|
7
|
-
const child_process_1 = require("child_process");
|
|
8
|
-
const git_utils_1 = require("../utils/git_utils");
|
|
9
|
-
const cloving_gpt_1 = __importDefault(require("../cloving_gpt"));
|
|
10
|
-
const config_utils_1 = require("../utils/config_utils");
|
|
11
|
-
const extractChangedFiles = (gitDiff) => {
|
|
12
|
-
const fileRegex = /diff --git a\/(.+?) b\/(.+?)\n/g;
|
|
13
|
-
const files = new Set();
|
|
14
|
-
let match;
|
|
15
|
-
while ((match = fileRegex.exec(gitDiff)) !== null) {
|
|
16
|
-
files.add(match[1]);
|
|
17
|
-
}
|
|
18
|
-
return Array.from(files);
|
|
19
|
-
};
|
|
20
|
-
const setupTestingPrompt = async (gpt, config) => {
|
|
21
|
-
const prompt = `I have the following cloving.json configuration file:
|
|
22
|
-
|
|
23
|
-
==== begin cloving.json ====
|
|
24
|
-
${JSON.stringify(config, null, 2)}
|
|
25
|
-
==== end cloving.json ====
|
|
26
|
-
|
|
27
|
-
Please provide instructions on how to set up testing for this project.`;
|
|
28
|
-
const setupInstructions = await gpt.generateText({ prompt });
|
|
29
|
-
console.log(setupInstructions);
|
|
30
|
-
process.exit(0);
|
|
31
|
-
};
|
|
32
|
-
const generatePrompt = (files, srcFiles, testFiles, gitDiff) => {
|
|
33
|
-
const filesList = files.length > 0 ? files.join('\n') : 'No files provided';
|
|
34
|
-
const diffSection = gitDiff ? `Here is my git diff:\n\n==== begin git diff ====\n${gitDiff}\n==== end git diff ====\n` : '';
|
|
35
|
-
return `Here is a list of code files I want to generate unit tests for:
|
|
36
|
-
|
|
37
|
-
==== begin list of files ====
|
|
38
|
-
${filesList}
|
|
39
|
-
==== end list of files ====
|
|
40
|
-
|
|
41
|
-
Here is a list of all my source files:
|
|
42
|
-
|
|
43
|
-
==== begin list of source files ====
|
|
44
|
-
${srcFiles}
|
|
45
|
-
==== end list of source files ====
|
|
46
|
-
|
|
47
|
-
Here is a list of all my test files:
|
|
48
|
-
|
|
49
|
-
==== begin list of test files ====
|
|
50
|
-
${testFiles}
|
|
51
|
-
==== end list of test files ====
|
|
52
|
-
|
|
53
|
-
${diffSection}
|
|
54
|
-
|
|
55
|
-
Please enumerate all the files in the provided list${gitDiff ? ' and git diff' : ''} as well as the file names of anything that these files interact with.
|
|
56
|
-
|
|
57
|
-
Also, list any test files that might be relevant to these files.
|
|
58
|
-
|
|
59
|
-
Give me this output format for your answer:
|
|
60
|
-
|
|
61
|
-
## files
|
|
62
|
-
|
|
63
|
-
app/models/foo.rb
|
|
64
|
-
app/views/baz/bar.html.erb
|
|
65
|
-
|
|
66
|
-
## relevant test files
|
|
67
|
-
|
|
68
|
-
test/models/foo_test.rb
|
|
69
|
-
test/controllers/baz_controller_test.rb`;
|
|
70
|
-
};
|
|
71
|
-
const unitTests = async (options) => {
|
|
72
|
-
const { files } = options;
|
|
73
|
-
const gpt = new cloving_gpt_1.default(options);
|
|
74
|
-
// Read the cloving.json file
|
|
75
|
-
const config = (0, config_utils_1.readClovingConfig)();
|
|
76
|
-
const testingDirectory = config.testingFrameworks?.find((framework) => framework.directory)?.directory;
|
|
77
|
-
if (!testingDirectory) {
|
|
78
|
-
await setupTestingPrompt(gpt, config);
|
|
79
|
-
}
|
|
80
|
-
let allSrcFiles = [];
|
|
81
|
-
// Collect srcFiles for each language with specified directory and extension
|
|
82
|
-
for (const language of config.languages) {
|
|
83
|
-
if (language.directory && language.extension) {
|
|
84
|
-
const srcFiles = (0, child_process_1.execFileSync)('find', [language.directory, '-type', 'f', '-name', `*${language.extension}`]).toString().trim().split('\n');
|
|
85
|
-
allSrcFiles = allSrcFiles.concat(srcFiles);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// Ensure allSrcFiles is unique
|
|
89
|
-
allSrcFiles = Array.from(new Set(allSrcFiles));
|
|
90
|
-
if (allSrcFiles.length === 0 || !testingDirectory) {
|
|
91
|
-
console.error('Could not find any source files to generate unit tests. Please run: cloving init. Then try again.');
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
const testFiles = (0, child_process_1.execFileSync)('find', [testingDirectory, '-type', 'f']).toString().trim();
|
|
95
|
-
let contextFiles;
|
|
96
|
-
if (files) {
|
|
97
|
-
const prompt = generatePrompt(files, allSrcFiles.join('\n'), testFiles);
|
|
98
|
-
contextFiles = await gpt.generateText({ prompt });
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
const gitDiff = await (0, git_utils_1.getGitDiff)();
|
|
102
|
-
const changedFiles = extractChangedFiles(gitDiff);
|
|
103
|
-
const prompt = generatePrompt(changedFiles, allSrcFiles.join('\n'), testFiles, gitDiff);
|
|
104
|
-
contextFiles = await gpt.generateText({ prompt });
|
|
105
|
-
}
|
|
106
|
-
// Initialize variables
|
|
107
|
-
const lines = [];
|
|
108
|
-
const context = [];
|
|
109
|
-
// Read input from temporary file
|
|
110
|
-
contextFiles.split('\n').forEach((line) => {
|
|
111
|
-
if (line.trim()) {
|
|
112
|
-
lines.push(line.trim());
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
for (const codeFile of lines) {
|
|
116
|
-
if (await fs_1.promises?.stat(codeFile).then(stat => stat.isFile()).catch(() => false)) {
|
|
117
|
-
const fileContents = await fs_1.promises.readFile(codeFile, 'utf-8');
|
|
118
|
-
context.push(`### **Contents of ${codeFile}**\n\n${fileContents}\n\n### **End of ${codeFile}**`);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
// Generate the message for unit test creation
|
|
122
|
-
let analysis = '';
|
|
123
|
-
if ((files || []).length > 0) {
|
|
124
|
-
const message = `please create unit tests for these files:
|
|
125
|
-
|
|
126
|
-
## begin list of files
|
|
127
|
-
${(files || []).join('\n')}
|
|
128
|
-
## end list of files
|
|
129
|
-
|
|
130
|
-
## context
|
|
131
|
-
${context.join('\n\n')}`;
|
|
132
|
-
// Get the model and analysis using ClovingGPT
|
|
133
|
-
analysis = await gpt.generateText({ prompt: message });
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
const message = `please create unit tests for these changes:
|
|
137
|
-
|
|
138
|
-
## begin diff
|
|
139
|
-
${await (0, git_utils_1.getGitDiff)()}
|
|
140
|
-
## end diff
|
|
141
|
-
|
|
142
|
-
## context
|
|
143
|
-
|
|
144
|
-
${context.join('\n\n')}`;
|
|
145
|
-
// Get the model and analysis using ClovingGPT
|
|
146
|
-
analysis = await gpt.generateText({ prompt: message });
|
|
147
|
-
}
|
|
148
|
-
console.log(analysis);
|
|
149
|
-
};
|
|
150
|
-
exports.default = unitTests;
|
package/dist/commands/update.js
DELETED
package/dist/file2.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const prompts_1 = require("@inquirer/prompts");
|
|
7
|
-
const colors_1 = __importDefault(require("colors"));
|
|
8
|
-
const cli_highlight_1 = __importDefault(require("cli-highlight"));
|
|
9
|
-
const cloving_gpt_1 = __importDefault(require("../cloving_gpt"));
|
|
10
|
-
const config_utils_1 = require("../utils/config_utils");
|
|
11
|
-
const prompt_utils_1 = require("../utils/prompt_utils");
|
|
12
|
-
const prompts_2 = require("../utils/prompts");
|
|
13
|
-
const string_utils_1 = require("../utils/string_utils");
|
|
14
|
-
/**
|
|
15
|
-
* Manages the generation of documentation for specified files.
|
|
16
|
-
*/
|
|
17
|
-
class DocumentationManager {
|
|
18
|
-
/**
|
|
19
|
-
* Creates a new DocumentationManager instance.
|
|
20
|
-
* @param {ClovingGPTOptions} options - Configuration options for the DocumentationManager.
|
|
21
|
-
*/
|
|
22
|
-
constructor(options) {
|
|
23
|
-
this.options = options;
|
|
24
|
-
this.contextFiles = {};
|
|
25
|
-
this.chatHistory = [];
|
|
26
|
-
this.options.silent = (0, config_utils_1.getConfig)(options).globalSilent || false;
|
|
27
|
-
this.gpt = new cloving_gpt_1.default(options);
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Generates documentation for the specified files.
|
|
31
|
-
* @returns {Promise<void>}
|
|
32
|
-
*/
|
|
33
|
-
async generateDocumentation() {
|
|
34
|
-
try {
|
|
35
|
-
await this.loadContextFiles();
|
|
36
|
-
if (this.chatHistory.length === 0) {
|
|
37
|
-
this.chatHistory.push({ role: 'user', content: prompts_2.CODEGEN_INSTRUCTIONS });
|
|
38
|
-
this.chatHistory.push({ role: 'assistant', content: 'What would you like to do?' });
|
|
39
|
-
}
|
|
40
|
-
const prompt = this.generateDocumentationPrompt();
|
|
41
|
-
this.chatHistory.push({ role: 'user', content: prompt });
|
|
42
|
-
const response = await this.gpt.generateText({ prompt, messages: this.chatHistory });
|
|
43
|
-
this.displayGeneratedDocumentation(response);
|
|
44
|
-
const currentNewBlocks = (0, string_utils_1.extractCurrentNewBlocks)(response);
|
|
45
|
-
if (currentNewBlocks.length > 0) {
|
|
46
|
-
const shouldSave = await (0, prompts_1.confirm)({
|
|
47
|
-
message: 'Do you want to save the generated documentation?',
|
|
48
|
-
default: true,
|
|
49
|
-
});
|
|
50
|
-
if (shouldSave) {
|
|
51
|
-
await (0, string_utils_1.applyAndSaveCurrentNewBlocks)(currentNewBlocks);
|
|
52
|
-
console.log(colors_1.default.green('\nDocumentation has been saved to the respective files.'));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
console.error(colors_1.default.red('Error generating documentation:'), error);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Displays the generated documentation in the console with syntax highlighting.
|
|
62
|
-
* @param {string} rawDocumentationResponse - The raw documentation response from the GPT model.
|
|
63
|
-
*/
|
|
64
|
-
displayGeneratedDocumentation(rawDocumentationResponse) {
|
|
65
|
-
(0, string_utils_1.parseMarkdownInstructions)(rawDocumentationResponse).map((code) => {
|
|
66
|
-
if (code.trim().startsWith('```')) {
|
|
67
|
-
const lines = code.split('\n');
|
|
68
|
-
const language = code.match(/```(\w+)/)?.[1] || 'plaintext';
|
|
69
|
-
console.log(lines[0]);
|
|
70
|
-
try {
|
|
71
|
-
console.log((0, cli_highlight_1.default)(lines.slice(1, -1).join('\n'), { language }));
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
// don't highlight if it fails
|
|
75
|
-
console.log(lines.slice(1, -1).join('\n'));
|
|
76
|
-
}
|
|
77
|
-
console.log(lines.slice(-1)[0]);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
console.log((0, cli_highlight_1.default)(code, { language: 'markdown' }));
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Loads the context files specified in the options.
|
|
86
|
-
* @returns {Promise<void>}
|
|
87
|
-
*/
|
|
88
|
-
async loadContextFiles() {
|
|
89
|
-
if (this.options.files) {
|
|
90
|
-
for (const file of this.options.files) {
|
|
91
|
-
this.contextFiles = await (0, prompt_utils_1.addFileOrDirectoryToContext)(file, this.contextFiles, this.options);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
console.log(colors_1.default.yellow('No files specified. Please provide files using the -f option.'));
|
|
96
|
-
process.exit(1);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Generates the documentation prompt to be sent to the GPT model.
|
|
101
|
-
* @returns {string} The generated documentation prompt.
|
|
102
|
-
*/
|
|
103
|
-
generateDocumentationPrompt() {
|
|
104
|
-
const contextFileContents = Object.entries(this.contextFiles)
|
|
105
|
-
.map(([file, content]) => `### File: ${file}\n\n\`\`\`\n${content}\n\`\`\`\n`)
|
|
106
|
-
.join('\n\n');
|
|
107
|
-
return `Please generate documentation for the following files. Add or update documentation comments for functions, classes, and modules as appropriate. Use the standard documentation format for the respective language (e.g., JSDoc for JavaScript/TypeScript, docstrings for Python, etc.).
|
|
108
|
-
|
|
109
|
-
${contextFileContents}
|
|
110
|
-
|
|
111
|
-
Please provide the updated files with added documentation using the CURRENT/NEW block format. Only include the parts of the files that have changed.`;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
exports.default = DocumentationManager;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
package/dist/newfile.js
DELETED