cloving 0.1.21 → 0.1.23
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/adapters/claude.js +29 -2
- package/dist/cloving_gpt/adapters/gemini.js +34 -4
- package/dist/cloving_gpt/adapters/mistral.js +45 -2
- package/dist/cloving_gpt/adapters/ollama.js +34 -2
- package/dist/cloving_gpt/adapters/openai.js +46 -2
- package/dist/cloving_gpt/index.js +52 -6
- package/dist/commands/chat.js +14 -0
- package/dist/commands/generate/code.js +8 -316
- package/dist/commands/generate/commit.js +2 -20
- package/dist/commands/proxy.js +11 -0
- package/dist/commands/tokens.js +43 -0
- package/dist/index.js +23 -0
- package/dist/managers/ChatManager.js +308 -0
- package/dist/managers/ChunkManager.js +20 -0
- package/dist/managers/CodeManager.js +319 -0
- package/dist/managers/ProxyManager.js +163 -0
- package/dist/managers/src/managers/ProxyManager.js +1 -0
- package/dist/utils/command_utils.js +1 -1
- package/dist/utils/git_utils.js +21 -1
- package/dist/utils/string_utils.js +21 -2
- package/package.json +4 -1
|
@@ -3,328 +3,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const copy_paste_1 = __importDefault(require("copy-paste"));
|
|
7
|
-
const prompts_1 = require("@inquirer/prompts");
|
|
8
|
-
const cli_highlight_1 = __importDefault(require("cli-highlight"));
|
|
9
|
-
const fs_1 = __importDefault(require("fs"));
|
|
10
|
-
const path_1 = __importDefault(require("path"));
|
|
11
|
-
const command_utils_1 = require("../../utils/command_utils");
|
|
12
6
|
const config_utils_1 = require("../../utils/config_utils");
|
|
13
|
-
const
|
|
7
|
+
const config_utils_2 = require("../../utils/config_utils");
|
|
14
8
|
const cloving_gpt_1 = __importDefault(require("../../cloving_gpt"));
|
|
15
|
-
const
|
|
16
|
-
const specialFileContents = (0, command_utils_1.collectSpecialFileContents)();
|
|
17
|
-
const specialFiles = Object.keys(specialFileContents).map((file) => `### Contents of ${file}\n\n${JSON.stringify(specialFileContents[file], null, 2)}\n\n`).join('\n');
|
|
18
|
-
const contextFileContents = Object.keys(contextFiles).map((file) => `### Contents of ${file}\n\n${contextFiles[file]}\n\n`).join('\n');
|
|
19
|
-
let promptText = `### Request
|
|
20
|
-
|
|
21
|
-
Generate code that does the following: ${prompt}
|
|
22
|
-
|
|
23
|
-
### Description of App
|
|
24
|
-
|
|
25
|
-
${JSON.stringify((0, config_utils_1.getClovingConfig)(), null, 2)}
|
|
26
|
-
|
|
27
|
-
${specialFiles}
|
|
28
|
-
|
|
29
|
-
${contextFileContents}
|
|
30
|
-
|
|
31
|
-
### Directory structure
|
|
32
|
-
|
|
33
|
-
${files.join('\n')}
|
|
34
|
-
|
|
35
|
-
`;
|
|
36
|
-
if (previousCode) {
|
|
37
|
-
promptText += `### Previously generated code
|
|
38
|
-
|
|
39
|
-
${previousCode}
|
|
40
|
-
|
|
41
|
-
`;
|
|
42
|
-
}
|
|
43
|
-
promptText += `### Example of a well-structured response
|
|
44
|
-
|
|
45
|
-
Here are the files that I would like to generate:
|
|
46
|
-
|
|
47
|
-
1. **src/commands/generate/shell.ts**
|
|
48
|
-
|
|
49
|
-
\`\`\`typescript
|
|
50
|
-
import inquirer from 'inquirer'
|
|
51
|
-
import highlight from 'cli-highlight'
|
|
52
|
-
import { execSync } from 'child_process'
|
|
53
|
-
import ncp from 'copy-paste'
|
|
54
|
-
import { extractMarkdown } from '../../utils/string_utils'
|
|
55
|
-
import { getConfig } from '../../utils/config_utils'
|
|
56
|
-
import ClovingGPT from '../../cloving_gpt'
|
|
57
|
-
import type { ClovingGPTOptions } from '../../utils/types'
|
|
58
|
-
|
|
59
|
-
const generateShellPrompt = (prompt: string | undefined): string => {
|
|
60
|
-
const shell = execSync('echo $SHELL').toString().trim()
|
|
61
|
-
const os = execSync('echo $OSTYPE').toString().trim()
|
|
62
|
-
return \`Generate an executable \${shell} script that works on \${os}. Try to make it a single line if possible and as simple and straightforward as possible.
|
|
63
|
-
|
|
64
|
-
Do not add any commentary or context to the message other than the commit message itself.
|
|
65
|
-
|
|
66
|
-
An example of the output for this should look like the following:
|
|
67
|
-
\`\`\`
|
|
68
|
-
|
|
69
|
-
### Request
|
|
70
|
-
|
|
71
|
-
Generate code that does the following: ${prompt}
|
|
72
|
-
|
|
73
|
-
Do not use any data from the example response structure, only use the structure. Please generate the code and include filenames with paths to the code files mentioned and do not be lazy and ask me to keep the existing code or show things like previous code remains unchanged, always include existing code in the response.`;
|
|
74
|
-
return promptText;
|
|
75
|
-
};
|
|
76
|
-
const generateExplainCodePrompt = (prompt) => {
|
|
77
|
-
return `${prompt}
|
|
78
|
-
|
|
79
|
-
## Task
|
|
80
|
-
|
|
81
|
-
Please briefly explain how the code works in this.`;
|
|
82
|
-
};
|
|
83
|
-
const generateCode = async (gpt, prompt, allSrcFiles, contextFiles, previousCode) => {
|
|
84
|
-
const codePrompt = generateCodePrompt(prompt, allSrcFiles, contextFiles, previousCode);
|
|
85
|
-
return await gpt.generateText({ prompt: codePrompt });
|
|
86
|
-
};
|
|
87
|
-
const displayGeneratedCode = (rawCodeCommand) => {
|
|
88
|
-
(0, string_utils_1.parseMarkdownInstructions)(rawCodeCommand).map(code => {
|
|
89
|
-
if (code.trim().startsWith('```')) {
|
|
90
|
-
const lines = code.split('\n');
|
|
91
|
-
const language = code.match(/```(\w+)/)?.[1] || 'plaintext';
|
|
92
|
-
console.log(lines[0]);
|
|
93
|
-
try {
|
|
94
|
-
console.log((0, cli_highlight_1.default)(lines.slice(1, -1).join('\n'), { language }));
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
// don't highlight if it fails
|
|
98
|
-
console.log(lines.slice(1, -1).join('\n'));
|
|
99
|
-
}
|
|
100
|
-
console.log(lines.slice(-1)[0]);
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
console.log((0, cli_highlight_1.default)(code, { language: 'markdown' }));
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
};
|
|
107
|
-
const saveGeneratedFiles = async (files, fileContents) => {
|
|
108
|
-
for (const file of files) {
|
|
109
|
-
if (fileContents[file]) {
|
|
110
|
-
const filePath = path_1.default.resolve(file);
|
|
111
|
-
await fs_1.default.promises.mkdir(path_1.default.dirname(filePath), { recursive: true });
|
|
112
|
-
await fs_1.default.promises.writeFile(filePath, fileContents[file]);
|
|
113
|
-
console.log(`${file} has been saved.`);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
console.log(`File content not found for ${file}.`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
const updateContextFiles = async (contextFiles, files, fileContents) => {
|
|
121
|
-
for (const file of files) {
|
|
122
|
-
if (fileContents[file]) {
|
|
123
|
-
contextFiles[file] = fileContents[file];
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
const handleUserAction = async (gpt, rawCodeCommand, prompt, allSrcFiles, contextFiles, options) => {
|
|
128
|
-
const [files, fileContents] = (0, string_utils_1.extractFilesAndContent)(rawCodeCommand);
|
|
129
|
-
if (options.save) {
|
|
130
|
-
await saveGeneratedFiles(files, fileContents);
|
|
131
|
-
await updateContextFiles(contextFiles, files, fileContents);
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
const action = await (0, prompts_1.select)({
|
|
135
|
-
message: 'What would you like to do?',
|
|
136
|
-
choices: [
|
|
137
|
-
{ name: 'Revise', value: 'revise' },
|
|
138
|
-
{ name: 'Explain', value: 'explain' },
|
|
139
|
-
{ name: 'Save a Source Code File', value: 'save' },
|
|
140
|
-
{ name: 'Save All Source Code Files', value: 'saveAll' },
|
|
141
|
-
{ name: 'Copy Source Code to Clipboard', value: 'copySource' },
|
|
142
|
-
{ name: 'Copy Entire Response to Clipboard', value: 'copyAll' },
|
|
143
|
-
{ name: 'Done', value: 'done' },
|
|
144
|
-
],
|
|
145
|
-
});
|
|
146
|
-
switch (action) {
|
|
147
|
-
case 'revise':
|
|
148
|
-
const newPrompt = await (0, prompts_1.input)({
|
|
149
|
-
message: 'How would you like to modify the output:',
|
|
150
|
-
});
|
|
151
|
-
let includeMoreFiles = true;
|
|
152
|
-
while (includeMoreFiles) {
|
|
153
|
-
const contextFile = await (0, prompts_1.input)({
|
|
154
|
-
message: 'Enter the relative path of a file or directory you would like to include as context (or press enter to continue):',
|
|
155
|
-
});
|
|
156
|
-
if (contextFile) {
|
|
157
|
-
contextFiles = await (0, command_utils_1.addFileOrDirectoryToContext)(contextFile, contextFiles, options);
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
includeMoreFiles = false;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
const newRawCodeCommand = await generateCode(gpt, newPrompt, allSrcFiles, contextFiles, rawCodeCommand);
|
|
164
|
-
displayGeneratedCode(newRawCodeCommand);
|
|
165
|
-
await handleUserAction(gpt, newRawCodeCommand, newPrompt, allSrcFiles, contextFiles, options);
|
|
166
|
-
break;
|
|
167
|
-
case 'explain':
|
|
168
|
-
const explainPrompt = generateExplainCodePrompt(rawCodeCommand);
|
|
169
|
-
const explainCodeCommand = await gpt.generateText({ prompt: explainPrompt });
|
|
170
|
-
console.log((0, cli_highlight_1.default)(explainCodeCommand, { language: 'markdown' }));
|
|
171
|
-
break;
|
|
172
|
-
case 'copySource':
|
|
173
|
-
let copyAnother = true;
|
|
174
|
-
while (copyAnother) {
|
|
175
|
-
const fileToCopy = await (0, prompts_1.select)({
|
|
176
|
-
message: 'Which file do you want to copy to the clipboard?',
|
|
177
|
-
choices: files.map(file => ({ name: file, value: file })),
|
|
178
|
-
});
|
|
179
|
-
if (fileContents[fileToCopy]) {
|
|
180
|
-
copy_paste_1.default.copy(fileContents[fileToCopy], () => {
|
|
181
|
-
console.log(`${fileToCopy} copied to clipboard`);
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
console.log('File content not found.');
|
|
186
|
-
}
|
|
187
|
-
const copyMore = await (0, prompts_1.confirm)({
|
|
188
|
-
message: 'Do you want to copy another file?',
|
|
189
|
-
default: true,
|
|
190
|
-
});
|
|
191
|
-
copyAnother = copyMore;
|
|
192
|
-
}
|
|
193
|
-
break;
|
|
194
|
-
case 'copyAll':
|
|
195
|
-
copy_paste_1.default.copy(rawCodeCommand, () => {
|
|
196
|
-
console.log('Entire response copied to clipboard');
|
|
197
|
-
});
|
|
198
|
-
break;
|
|
199
|
-
case 'save':
|
|
200
|
-
let saveAnother = true;
|
|
201
|
-
while (saveAnother) {
|
|
202
|
-
const fileToSave = await (0, prompts_1.select)({
|
|
203
|
-
message: 'Which file do you want to save?',
|
|
204
|
-
choices: files.map(file => ({ name: file, value: file })),
|
|
205
|
-
});
|
|
206
|
-
if (fileContents[fileToSave]) {
|
|
207
|
-
const filePath = path_1.default.resolve(fileToSave);
|
|
208
|
-
await fs_1.default.promises.mkdir(path_1.default.dirname(filePath), { recursive: true });
|
|
209
|
-
await fs_1.default.promises.writeFile(filePath, fileContents[fileToSave]);
|
|
210
|
-
console.log(`${fileToSave} has been saved.`);
|
|
211
|
-
await updateContextFiles(contextFiles, [fileToSave], fileContents);
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
console.log('File content not found.');
|
|
215
|
-
}
|
|
216
|
-
const saveMore = await (0, prompts_1.confirm)({
|
|
217
|
-
message: 'Do you want to save another file?',
|
|
218
|
-
default: true,
|
|
219
|
-
});
|
|
220
|
-
saveAnother = saveMore;
|
|
221
|
-
}
|
|
222
|
-
break;
|
|
223
|
-
case 'saveAll':
|
|
224
|
-
await saveGeneratedFiles(files, fileContents);
|
|
225
|
-
await updateContextFiles(contextFiles, files, fileContents);
|
|
226
|
-
console.log('All files have been saved.');
|
|
227
|
-
break;
|
|
228
|
-
case 'done':
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
231
|
-
};
|
|
9
|
+
const CodeManager_1 = __importDefault(require("../../managers/CodeManager"));
|
|
232
10
|
const code = async (options) => {
|
|
233
|
-
|
|
234
|
-
options.silent = (0, config_utils_1.getConfig)(options).globalSilent || false;
|
|
11
|
+
options.silent = (0, config_utils_2.getConfig)(options).globalSilent || false;
|
|
235
12
|
const gpt = new cloving_gpt_1.default(options);
|
|
236
13
|
const allSrcFiles = await (0, config_utils_1.getAllFiles)(options, false);
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
let expandedFiles = [];
|
|
241
|
-
for (const file of files) {
|
|
242
|
-
const filePath = path_1.default.resolve(file);
|
|
243
|
-
if (await fs_1.default.promises.stat(filePath).then(stat => stat.isDirectory()).catch(() => false)) {
|
|
244
|
-
const dirFiles = await (0, command_utils_1.getAllFilesInDirectory)(filePath);
|
|
245
|
-
expandedFiles = expandedFiles.concat(dirFiles.map(f => path_1.default.relative(process.cwd(), f)));
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
expandedFiles.push(path_1.default.relative(process.cwd(), filePath));
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
files = expandedFiles;
|
|
252
|
-
for (const file of files) {
|
|
253
|
-
const filePath = path_1.default.resolve(file);
|
|
254
|
-
if (await fs_1.default.promises.stat(filePath).then(stat => stat.isFile()).catch(() => false)) {
|
|
255
|
-
const content = await fs_1.default.promises.readFile(filePath, 'utf-8');
|
|
256
|
-
contextFiles[file] = content;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
let includeMoreFiles = true;
|
|
262
|
-
while (includeMoreFiles) {
|
|
263
|
-
const contextFile = await (0, prompts_1.input)({
|
|
264
|
-
message: `Enter the relative path of a file or directory you would like to include as context (or press enter to continue):`,
|
|
265
|
-
});
|
|
266
|
-
if (contextFile) {
|
|
267
|
-
contextFiles = await (0, command_utils_1.addFileOrDirectoryToContext)(contextFile, contextFiles, options);
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
includeMoreFiles = false;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
if (!prompt) {
|
|
275
|
-
const userPrompt = await (0, prompts_1.input)({
|
|
276
|
-
message: 'What would you like the code to do:',
|
|
277
|
-
});
|
|
278
|
-
prompt = userPrompt;
|
|
279
|
-
}
|
|
280
|
-
let rawCodeCommand = await generateCode(gpt, prompt, allSrcFiles, contextFiles);
|
|
281
|
-
displayGeneratedCode(rawCodeCommand);
|
|
282
|
-
if (options.save) {
|
|
283
|
-
const [files, fileContents] = (0, string_utils_1.extractFilesAndContent)(rawCodeCommand);
|
|
284
|
-
await saveGeneratedFiles(files, fileContents);
|
|
285
|
-
await updateContextFiles(contextFiles, files, fileContents);
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
await handleUserAction(gpt, rawCodeCommand, prompt, allSrcFiles, contextFiles, options);
|
|
289
|
-
}
|
|
290
|
-
if (options.interactive) {
|
|
291
|
-
let continueInteractive = true;
|
|
292
|
-
while (continueInteractive) {
|
|
293
|
-
const newPrompt = await (0, prompts_1.input)({
|
|
294
|
-
message: 'Revise the code (or press enter to finish):',
|
|
295
|
-
});
|
|
296
|
-
if (newPrompt.trim() === '') {
|
|
297
|
-
continueInteractive = false;
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
let includeMoreFiles = true;
|
|
301
|
-
while (includeMoreFiles) {
|
|
302
|
-
const contextFile = await (0, prompts_1.input)({
|
|
303
|
-
message: 'Enter the relative path of a file or directory you would like to include as context (or press enter to continue):',
|
|
304
|
-
});
|
|
305
|
-
if (contextFile) {
|
|
306
|
-
contextFiles = await (0, command_utils_1.addFileOrDirectoryToContext)(contextFile, contextFiles, options);
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
includeMoreFiles = false;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
rawCodeCommand = await generateCode(gpt, newPrompt, allSrcFiles, contextFiles, rawCodeCommand);
|
|
313
|
-
displayGeneratedCode(rawCodeCommand);
|
|
314
|
-
if (options.save || options.interactive) {
|
|
315
|
-
const [files, fileContents] = (0, string_utils_1.extractFilesAndContent)(rawCodeCommand);
|
|
316
|
-
await saveGeneratedFiles(files, fileContents);
|
|
317
|
-
await updateContextFiles(contextFiles, files, fileContents);
|
|
318
|
-
}
|
|
319
|
-
else {
|
|
320
|
-
await handleUserAction(gpt, rawCodeCommand, newPrompt, allSrcFiles, contextFiles, options);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
14
|
+
const codeManager = new CodeManager_1.default(gpt, options, allSrcFiles);
|
|
15
|
+
if (options.prompt) {
|
|
16
|
+
await codeManager.processCode(options.prompt);
|
|
325
17
|
}
|
|
326
|
-
|
|
327
|
-
console.error('
|
|
18
|
+
else {
|
|
19
|
+
console.error('No prompt provided.');
|
|
328
20
|
}
|
|
329
21
|
};
|
|
330
22
|
exports.default = code;
|
|
@@ -7,27 +7,9 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const child_process_1 = require("child_process");
|
|
9
9
|
const string_utils_1 = require("../../utils/string_utils");
|
|
10
|
+
const git_utils_1 = require("../../utils/git_utils");
|
|
10
11
|
const config_utils_1 = require("../../utils/config_utils");
|
|
11
12
|
const cloving_gpt_1 = __importDefault(require("../../cloving_gpt"));
|
|
12
|
-
const generateCommitMessagePrompt = (diff) => {
|
|
13
|
-
return `Generate a concise and meaningful commit message based on a diff.
|
|
14
|
-
|
|
15
|
-
Do not add any commentary or context to the message other than the commit message itself.
|
|
16
|
-
|
|
17
|
-
An example of the output for this should look like the following:
|
|
18
|
-
|
|
19
|
-
\`\`\`plaintext
|
|
20
|
-
Update dependencies and package versions
|
|
21
|
-
|
|
22
|
-
- Upgrade Ruby gems including aws-sdk, honeybadger, irb, and rubocop
|
|
23
|
-
- Update Node.js packages including esbuild, tinymce, and trix
|
|
24
|
-
- Bump TypeScript and ESLint related packages to latest versions
|
|
25
|
-
\`\`\`
|
|
26
|
-
|
|
27
|
-
Here is the diff to help you write the commit message:
|
|
28
|
-
|
|
29
|
-
${diff}`;
|
|
30
|
-
};
|
|
31
13
|
const commit = async (options) => {
|
|
32
14
|
options.silent = (0, config_utils_1.getConfig)(options).globalSilent || false;
|
|
33
15
|
const gpt = new cloving_gpt_1.default(options);
|
|
@@ -40,7 +22,7 @@ const commit = async (options) => {
|
|
|
40
22
|
return;
|
|
41
23
|
}
|
|
42
24
|
// Generate the prompt for commit message
|
|
43
|
-
const prompt = generateCommitMessagePrompt(diff);
|
|
25
|
+
const prompt = (0, git_utils_1.generateCommitMessagePrompt)(diff);
|
|
44
26
|
// Instantiate ClovingGPT and get the commit message
|
|
45
27
|
const rawCommitMessage = await gpt.generateText({ prompt });
|
|
46
28
|
// Clean the commit message using extractMarkdown
|
|
@@ -0,0 +1,11 @@
|
|
|
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 ProxyManager_1 = __importDefault(require("../managers/ProxyManager"));
|
|
7
|
+
const proxy = async (options) => {
|
|
8
|
+
const proxyManager = new ProxyManager_1.default(options);
|
|
9
|
+
await proxyManager.initialize();
|
|
10
|
+
};
|
|
11
|
+
exports.default = proxy;
|
|
@@ -0,0 +1,43 @@
|
|
|
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 = __importDefault(require("fs"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const config_utils_1 = require("../utils/config_utils");
|
|
9
|
+
const command_utils_1 = require("../utils/command_utils");
|
|
10
|
+
const tokens = async (options) => {
|
|
11
|
+
let contextFiles = {};
|
|
12
|
+
let files = options.files || '.';
|
|
13
|
+
let prompt = '';
|
|
14
|
+
let expandedFiles = [];
|
|
15
|
+
for (const file of files) {
|
|
16
|
+
const filePath = path_1.default.resolve(file);
|
|
17
|
+
if (await fs_1.default.promises.stat(filePath).then(stat => stat.isDirectory()).catch(() => false)) {
|
|
18
|
+
const dirFiles = await (0, command_utils_1.getAllFilesInDirectory)(filePath);
|
|
19
|
+
expandedFiles = expandedFiles.concat(dirFiles.map(f => path_1.default.relative(process.cwd(), f)));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
expandedFiles.push(path_1.default.relative(process.cwd(), filePath));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
files = expandedFiles;
|
|
26
|
+
for (const file of files) {
|
|
27
|
+
const filePath = path_1.default.resolve(file);
|
|
28
|
+
if (await fs_1.default.promises.stat(filePath).then(stat => stat.isFile()).catch(() => false)) {
|
|
29
|
+
const content = await fs_1.default.promises.readFile(filePath, 'utf-8');
|
|
30
|
+
contextFiles[file] = content;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const contextFileContents = Object.keys(contextFiles).map((file) => `### Contents of ${file}\n\n${contextFiles[file]}\n\n`).join('\n');
|
|
34
|
+
prompt += `
|
|
35
|
+
### Description of App
|
|
36
|
+
|
|
37
|
+
${JSON.stringify((0, config_utils_1.getClovingConfig)(), null, 2)}
|
|
38
|
+
|
|
39
|
+
${contextFileContents}`;
|
|
40
|
+
const tokens = Math.ceil(prompt.length / 4).toLocaleString();
|
|
41
|
+
console.log(`Estimated tokens: ${tokens}`);
|
|
42
|
+
};
|
|
43
|
+
exports.default = tokens;
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,10 @@ const fs_1 = require("fs");
|
|
|
9
9
|
const path_1 = require("path");
|
|
10
10
|
const config_1 = __importDefault(require("./commands/config"));
|
|
11
11
|
const init_1 = __importDefault(require("./commands/init"));
|
|
12
|
+
const proxy_1 = __importDefault(require("./commands/proxy"));
|
|
13
|
+
const tokens_1 = __importDefault(require("./commands/tokens"));
|
|
12
14
|
const models_1 = __importDefault(require("./commands/models"));
|
|
15
|
+
const chat_1 = __importDefault(require("./commands/chat"));
|
|
13
16
|
const shell_1 = __importDefault(require("./commands/generate/shell"));
|
|
14
17
|
const code_1 = __importDefault(require("./commands/generate/code"));
|
|
15
18
|
const commit_1 = __importDefault(require("./commands/generate/commit"));
|
|
@@ -41,11 +44,31 @@ program
|
|
|
41
44
|
.option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
|
|
42
45
|
.option('-m, --model <model>', 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5-sonnet-20240620)')
|
|
43
46
|
.action(init_1.default);
|
|
47
|
+
program
|
|
48
|
+
.command('chat')
|
|
49
|
+
.option('-f, --files <filenames...>', 'Specify filenames of files with context to use for generating code')
|
|
50
|
+
.option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
|
|
51
|
+
.option('-m, --model <model>', 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5:sonnet-20240620)')
|
|
52
|
+
.description('Start an interactive chat with cloving')
|
|
53
|
+
.action(chat_1.default);
|
|
54
|
+
program
|
|
55
|
+
.command('proxy')
|
|
56
|
+
.option('-f, --files <filenames...>', 'Specify filenames of files with context to use for generating code')
|
|
57
|
+
.option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
|
|
58
|
+
.option('-m, --model <model>', 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5:sonnet-20240620)')
|
|
59
|
+
.description('Start a proxy server to use with cloving')
|
|
60
|
+
.action(proxy_1.default);
|
|
44
61
|
program
|
|
45
62
|
.command('models')
|
|
46
63
|
.alias('m')
|
|
47
64
|
.description('List available models')
|
|
48
65
|
.action(models_1.default);
|
|
66
|
+
program
|
|
67
|
+
.command('tokens')
|
|
68
|
+
.alias('t')
|
|
69
|
+
.option('-f, --files <filenames...>', 'Specify filenames of files with context to use for generating code')
|
|
70
|
+
.description('Estimate the number of tokens in the current working directory or specified files')
|
|
71
|
+
.action(tokens_1.default);
|
|
49
72
|
program
|
|
50
73
|
.command('commit')
|
|
51
74
|
.alias('c')
|