cloving 0.3.10 → 0.3.11

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.
@@ -16,7 +16,7 @@ class AzureOpenAIAdapter {
16
16
  }
17
17
  getHeaders(apiKey) {
18
18
  return {
19
- 'api-key': apiKey,
19
+ Authorization: `Bearer ${apiKey}`,
20
20
  'Content-Type': 'application/json',
21
21
  };
22
22
  }
@@ -5,6 +5,11 @@ const config_utils_1 = require("../utils/config_utils");
5
5
  const prompt_utils_1 = require("../utils/prompt_utils");
6
6
  // Add this type definition at the top of the file
7
7
  const prompts_1 = require("@inquirer/prompts");
8
+ /**
9
+ * Configures the AI models by prompting the user for various settings.
10
+ *
11
+ * @returns {Promise<void>} A promise that resolves when the configuration is complete.
12
+ */
8
13
  const config = async () => {
9
14
  let currentConfig = (0, config_utils_1.getConfig)({});
10
15
  // Ensure models are initialized properly
@@ -19,23 +24,35 @@ const config = async () => {
19
24
  let continueConfig = true;
20
25
  while (continueConfig) {
21
26
  const providers = [...new Set(models.map((model) => model.split(':')[0]))];
27
+ /**
28
+ * Prompts the user to select a provider from the available models.
29
+ */
22
30
  const selectedProvider = await (0, prompts_1.select)({
23
31
  message: 'Select a provider:',
24
32
  choices: providers.map((provider) => ({ name: provider, value: provider })),
25
33
  });
26
34
  const providerModels = models.filter((model) => model.startsWith(selectedProvider));
27
35
  const modelCategories = [...new Set(providerModels.map((model) => model.split(':')[1]))];
36
+ /**
37
+ * Prompts the user to select a category from the selected provider's models.
38
+ */
28
39
  const selectedCategory = await (0, prompts_1.select)({
29
40
  message: 'Select a category:',
30
41
  choices: modelCategories.map((category) => ({ name: category, value: category })),
31
42
  });
32
43
  const specificModels = providerModels.filter((model) => model.split(':')[1] === selectedCategory);
44
+ /**
45
+ * Prompts the user to select a specific model from the selected category.
46
+ */
33
47
  const modelIndex = await (0, prompts_1.select)({
34
48
  message: "Select an AI model you'd like to use:",
35
49
  choices: specificModels.map((model, index) => ({ name: model, value: index })),
36
50
  pageSize: specificModels.length,
37
51
  });
38
52
  const selectedModel = specificModels[modelIndex];
53
+ /**
54
+ * Prompts the user to enter the API key for the selected model.
55
+ */
39
56
  const apiKey = await (0, prompts_1.input)({
40
57
  message: `Enter your API key for ${selectedModel}: `,
41
58
  });
@@ -44,10 +61,18 @@ const config = async () => {
44
61
  if (!currentConfig.models[provider]) {
45
62
  currentConfig.models[provider] = {};
46
63
  }
64
+ /**
65
+ * Prompts the user to set the selected model as the primary model.
66
+ */
47
67
  const primary = await (0, prompts_1.confirm)({
48
68
  message: 'Set this model as the primary? Primary models are used by default if your prompt fits within its context window. You can configure backup models for larger prompts.',
49
69
  default: true,
50
70
  });
71
+ /**
72
+ * Prompts the user to enter the priority for the selected model.
73
+ *
74
+ * @returns {string} The priority value as a string.
75
+ */
51
76
  const priority = await (0, prompts_1.input)({
52
77
  message: 'Enter the priority for this model (0-100). Higher priority AI APIs are chosen as long as the prompt fits its context window:',
53
78
  default: primary ? '100' : '0',
@@ -59,14 +84,25 @@ const config = async () => {
59
84
  return true;
60
85
  },
61
86
  });
87
+ /**
88
+ * Prompts the user to decide if they want to review all prompts before they are sent to the selected model.
89
+ */
62
90
  const review = await (0, prompts_1.confirm)({
63
91
  message: `Do you want to review all prompts before they are sent to ${selectedModel}?`,
64
92
  default: true,
65
93
  });
94
+ /**
95
+ * Prompts the user to decide if they trust the selected model with sensitive information.
96
+ */
66
97
  const trust = await (0, prompts_1.confirm)({
67
98
  message: `Do you trust ${selectedModel} with sensitive information?`,
68
99
  default: false,
69
100
  });
101
+ /**
102
+ * Prompts the user to enter the temperature setting for the selected model.
103
+ *
104
+ * @returns {string} The temperature value as a string.
105
+ */
70
106
  const temperature = await (0, prompts_1.input)({
71
107
  message: `Enter the temperature for ${selectedModel} (0.0 - 1.0): [0.2]`,
72
108
  default: '0.2',
@@ -79,6 +115,9 @@ const config = async () => {
79
115
  },
80
116
  });
81
117
  const parsedTemperature = parseFloat(temperature);
118
+ /**
119
+ * Constructs the model configuration object.
120
+ */
82
121
  let modelConfig = {
83
122
  apiKey,
84
123
  primary,
@@ -88,6 +127,9 @@ const config = async () => {
88
127
  temperature: parsedTemperature,
89
128
  };
90
129
  if (provider === 'azureopenai') {
130
+ /**
131
+ * Prompts the user to enter the Azure OpenAI endpoint URL.
132
+ */
91
133
  const endpoint = await (0, prompts_1.input)({
92
134
  message: 'Enter the Azure OpenAI endpoint URL:',
93
135
  validate: (value) => {
@@ -110,6 +152,9 @@ const config = async () => {
110
152
  }
111
153
  }
112
154
  }
155
+ /**
156
+ * Prompts the user to decide if they want to configure another model.
157
+ */
113
158
  const anotherModel = await (0, prompts_1.confirm)({
114
159
  message: 'Do you want to configure another model?',
115
160
  default: true,
@@ -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 DocumentationManager_1 = __importDefault(require("../../managers/DocumentationManager"));
7
+ const documentation = async (options) => {
8
+ const documentationManager = new DocumentationManager_1.default(options);
9
+ await documentationManager.generateDocumentation();
10
+ };
11
+ exports.default = documentation;
package/dist/index.js CHANGED
@@ -17,6 +17,7 @@ const commit_1 = __importDefault(require("./commands/generate/commit"));
17
17
  const context_1 = __importDefault(require("./commands/generate/context"));
18
18
  const unit_tests_1 = __importDefault(require("./commands/generate/unit_tests"));
19
19
  const review_1 = __importDefault(require("./commands/generate/review"));
20
+ const documentation_1 = __importDefault(require("./commands/generate/documentation"));
20
21
  const prompt_utils_1 = require("./utils/prompt_utils");
21
22
  const program = new commander_1.Command();
22
23
  program
@@ -121,4 +122,13 @@ generate
121
122
  .option('-m, --model <model>', 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5-sonnet-20240620)')
122
123
  .option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
123
124
  .action(review_1.default);
125
+ generate
126
+ .command('documentation')
127
+ .alias('d')
128
+ .description('Generate documentation for the project')
129
+ .option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
130
+ .option('-f, --files <filenames...>', 'Specify filenames for files you want to document')
131
+ .option('-m, --model <model>', 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5-sonnet-20240620)')
132
+ .option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
133
+ .action(documentation_1.default);
124
134
  program.parse(process.argv);
@@ -0,0 +1,113 @@
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 string_utils_1 = require("../utils/string_utils");
13
+ /**
14
+ * Manages the generation of documentation for specified files.
15
+ */
16
+ class DocumentationManager {
17
+ /**
18
+ * Creates a new DocumentationManager instance.
19
+ * @param {ClovingGPTOptions} options - Configuration options for the DocumentationManager.
20
+ */
21
+ constructor(options) {
22
+ this.options = options;
23
+ this.contextFiles = {};
24
+ this.chatHistory = [];
25
+ this.options.silent = (0, config_utils_1.getConfig)(options).globalSilent || false;
26
+ this.gpt = new cloving_gpt_1.default(options);
27
+ }
28
+ /**
29
+ * Generates documentation for the specified files.
30
+ * @returns {Promise<void>}
31
+ */
32
+ async generateDocumentation() {
33
+ try {
34
+ await this.loadContextFiles();
35
+ if (this.chatHistory.length === 0) {
36
+ this.chatHistory.push({ role: 'user', content: prompt_utils_1.CODEGEN_INSTRUCTIONS });
37
+ this.chatHistory.push({ role: 'assistant', content: 'What would you like to do?' });
38
+ }
39
+ const prompt = this.generateDocumentationPrompt();
40
+ this.chatHistory.push({ role: 'user', content: prompt });
41
+ const response = await this.gpt.generateText({ prompt, messages: this.chatHistory });
42
+ this.displayGeneratedDocumentation(response);
43
+ const currentNewBlocks = (0, string_utils_1.extractCurrentNewBlocks)(response);
44
+ if (currentNewBlocks.length > 0) {
45
+ const shouldSave = await (0, prompts_1.confirm)({
46
+ message: 'Do you want to save the generated documentation?',
47
+ default: true,
48
+ });
49
+ if (shouldSave) {
50
+ await (0, string_utils_1.applyAndSaveCurrentNewBlocks)(currentNewBlocks);
51
+ console.log(colors_1.default.green('\nDocumentation has been saved to the respective files.'));
52
+ }
53
+ }
54
+ }
55
+ catch (error) {
56
+ console.error(colors_1.default.red('Error generating documentation:'), error);
57
+ }
58
+ }
59
+ /**
60
+ * Displays the generated documentation in the console with syntax highlighting.
61
+ * @param {string} rawDocumentationResponse - The raw documentation response from the GPT model.
62
+ */
63
+ displayGeneratedDocumentation(rawDocumentationResponse) {
64
+ (0, string_utils_1.parseMarkdownInstructions)(rawDocumentationResponse).map((code) => {
65
+ if (code.trim().startsWith('```')) {
66
+ const lines = code.split('\n');
67
+ const language = code.match(/```(\w+)/)?.[1] || 'plaintext';
68
+ console.log(lines[0]);
69
+ try {
70
+ console.log((0, cli_highlight_1.default)(lines.slice(1, -1).join('\n'), { language }));
71
+ }
72
+ catch (error) {
73
+ // don't highlight if it fails
74
+ console.log(lines.slice(1, -1).join('\n'));
75
+ }
76
+ console.log(lines.slice(-1)[0]);
77
+ }
78
+ else {
79
+ console.log((0, cli_highlight_1.default)(code, { language: 'markdown' }));
80
+ }
81
+ });
82
+ }
83
+ /**
84
+ * Loads the context files specified in the options.
85
+ * @returns {Promise<void>}
86
+ */
87
+ async loadContextFiles() {
88
+ if (this.options.files) {
89
+ for (const file of this.options.files) {
90
+ this.contextFiles = await (0, prompt_utils_1.addFileOrDirectoryToContext)(file, this.contextFiles, this.options);
91
+ }
92
+ }
93
+ else {
94
+ console.log(colors_1.default.yellow('No files specified. Please provide files using the -f option.'));
95
+ process.exit(1);
96
+ }
97
+ }
98
+ /**
99
+ * Generates the documentation prompt to be sent to the GPT model.
100
+ * @returns {string} The generated documentation prompt.
101
+ */
102
+ generateDocumentationPrompt() {
103
+ const contextFileContents = Object.entries(this.contextFiles)
104
+ .map(([file, content]) => `### File: ${file}\n\n\`\`\`\n${content}\n\`\`\`\n`)
105
+ .join('\n\n');
106
+ 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.).
107
+
108
+ ${contextFileContents}
109
+
110
+ Please provide the updated files with added documentation using the CURRENT/NEW block format. Only include the parts of the files that have changed.`;
111
+ }
112
+ }
113
+ exports.default = DocumentationManager;
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloving",
3
- "version": "0.3.10",
3
+ "version": "0.3.11",
4
4
  "packageManager": "yarn@1.22.22",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloving",
3
- "version": "0.3.10",
3
+ "version": "0.3.11",
4
4
  "packageManager": "yarn@1.22.22",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",