cloving 0.3.19 → 0.3.20

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.
Files changed (95) hide show
  1. package/dist/index.js +2 -0
  2. package/dist/managers/CommitManager.js +30 -16
  3. package/dist/package.json +1 -1
  4. package/package.json +1 -1
  5. package/.DS_Store +0 -0
  6. package/.aider.chat.history.md +0 -16978
  7. package/.aider.input.history +0 -15
  8. package/.aider.tags.cache.v3/cache.db +0 -0
  9. package/.aider.tags.cache.v3/cache.db-shm +0 -0
  10. package/.aider.tags.cache.v3/cache.db-wal +0 -0
  11. package/.cursorrules +0 -77
  12. package/.github/workflows/auto-release.yml +0 -83
  13. package/.github/workflows/ci.yml +0 -32
  14. package/.github/workflows/npm-publish.yml +0 -34
  15. package/.gitignore +0 -67
  16. package/.husky/_/.gitignore +0 -1
  17. package/.husky/_/applypatch-msg +0 -2
  18. package/.husky/_/commit-msg +0 -2
  19. package/.husky/_/h +0 -22
  20. package/.husky/_/husky.sh +0 -9
  21. package/.husky/_/post-applypatch +0 -2
  22. package/.husky/_/post-checkout +0 -2
  23. package/.husky/_/post-commit +0 -2
  24. package/.husky/_/post-merge +0 -2
  25. package/.husky/_/post-rewrite +0 -2
  26. package/.husky/_/pre-applypatch +0 -2
  27. package/.husky/_/pre-auto-gc +0 -2
  28. package/.husky/_/pre-commit +0 -2
  29. package/.husky/_/pre-merge-commit +0 -2
  30. package/.husky/_/pre-push +0 -2
  31. package/.husky/_/pre-rebase +0 -2
  32. package/.husky/_/prepare-commit-msg +0 -2
  33. package/.husky/pre-commit +0 -1
  34. package/.husky/pre-push +0 -1
  35. package/.prettierrc.json +0 -7
  36. package/.tool-versions +0 -2
  37. package/SECURITY.md +0 -15
  38. package/cloving.json +0 -67
  39. package/jest.config.js +0 -11
  40. package/src/cloving_gpt/adapters/azureopenai.ts +0 -83
  41. package/src/cloving_gpt/adapters/claude.ts +0 -140
  42. package/src/cloving_gpt/adapters/gemini.ts +0 -146
  43. package/src/cloving_gpt/adapters/index.ts +0 -43
  44. package/src/cloving_gpt/adapters/mistral.ts +0 -142
  45. package/src/cloving_gpt/adapters/ollama.ts +0 -136
  46. package/src/cloving_gpt/adapters/openai.ts +0 -113
  47. package/src/cloving_gpt/index.ts +0 -229
  48. package/src/commands/chat.ts +0 -12
  49. package/src/commands/config.ts +0 -192
  50. package/src/commands/generate/code.ts +0 -18
  51. package/src/commands/generate/commit.ts +0 -9
  52. package/src/commands/generate/context.ts +0 -93
  53. package/src/commands/generate/docs.ts +0 -9
  54. package/src/commands/generate/review.ts +0 -9
  55. package/src/commands/generate/shell.ts +0 -9
  56. package/src/commands/generate/unit_tests.ts +0 -9
  57. package/src/commands/init.ts +0 -9
  58. package/src/commands/models.ts +0 -21
  59. package/src/commands/proxy.ts +0 -9
  60. package/src/commands/tokens.ts +0 -82
  61. package/src/index.ts +0 -197
  62. package/src/managers/BlockManager.ts +0 -126
  63. package/src/managers/ChatManager.ts +0 -755
  64. package/src/managers/ChunkManager.ts +0 -31
  65. package/src/managers/CodeManager.ts +0 -226
  66. package/src/managers/CommitManager.ts +0 -71
  67. package/src/managers/DocsManager.ts +0 -101
  68. package/src/managers/InitManager.ts +0 -263
  69. package/src/managers/ProxyManager.ts +0 -240
  70. package/src/managers/ReviewManager.ts +0 -154
  71. package/src/managers/ShellManager.ts +0 -172
  72. package/src/managers/StreamManager.ts +0 -353
  73. package/src/managers/UnitTestManager.ts +0 -293
  74. package/src/utils/config_utils.ts +0 -271
  75. package/src/utils/git_utils.ts +0 -230
  76. package/src/utils/model_utils.ts +0 -3
  77. package/src/utils/prompt_utils.ts +0 -375
  78. package/src/utils/prompts/CODEGEN_COULDNT_APPLY.md +0 -5
  79. package/src/utils/prompts/CODEGEN_EXAMPLES.md +0 -82
  80. package/src/utils/prompts/CODEGEN_INSTRUCTIONS.md +0 -43
  81. package/src/utils/prompts/DOCS_INSTRUCTIONS.md +0 -9
  82. package/src/utils/prompts/INIT_INSTRUCTIONS.md +0 -132
  83. package/src/utils/prompts/REVIEW_INSTRUCTIONS.md +0 -49
  84. package/src/utils/prompts/SHELL_INSTRUCTIONS.md +0 -15
  85. package/src/utils/prompts/SPECIAL_FILES.md +0 -66
  86. package/src/utils/prompts/index.ts +0 -37
  87. package/src/utils/string_utils.ts +0 -552
  88. package/src/utils/types.ts +0 -127
  89. package/tests/commands/generate/unit_tests.test.ts +0 -27
  90. package/tests/utils/git_utils.test.ts +0 -116
  91. package/tests/utils/model_utils.test.ts +0 -27
  92. package/tests/utils/prompt_utils.test.ts +0 -33
  93. package/tests/utils/string_utils.test.ts +0 -560
  94. package/tsconfig.json +0 -14
  95. package/yarn.lock +0 -5823
@@ -1,9 +0,0 @@
1
- import ShellManager from '../../managers/ShellManager'
2
- import type { ClovingGPTOptions } from '../../utils/types'
3
-
4
- const shell = async (options: ClovingGPTOptions) => {
5
- const shellManager = new ShellManager(options)
6
- await shellManager.generateAndHandleShell()
7
- }
8
-
9
- export default shell
@@ -1,9 +0,0 @@
1
- import UnitTestManager from '../../managers/UnitTestManager'
2
- import type { ClovingGPTOptions } from '../../utils/types'
3
-
4
- const unitTests = async (options: ClovingGPTOptions) => {
5
- const unitTestManager = new UnitTestManager(options)
6
- await unitTestManager.generateUnitTests()
7
- }
8
-
9
- export default unitTests
@@ -1,9 +0,0 @@
1
- import InitManager from '../managers/InitManager'
2
- import type { ClovingGPTOptions } from '../utils/types'
3
-
4
- export const init = async (options: ClovingGPTOptions) => {
5
- const initManager = new InitManager(options)
6
- await initManager.initialize()
7
- }
8
-
9
- export default init
@@ -1,21 +0,0 @@
1
- import { ClaudeAdapter } from '../cloving_gpt/adapters/claude'
2
- import { OpenAIAdapter } from '../cloving_gpt/adapters/openai'
3
- import { OllamaAdapter } from '../cloving_gpt/adapters/ollama'
4
- import { GeminiAdapter } from '../cloving_gpt/adapters/gemini'
5
- import { MistralAdapter } from '../cloving_gpt/adapters/mistral'
6
- import { AzureOpenAIAdapter } from '../cloving_gpt/adapters/azureopenai'
7
-
8
- const listModels = async () => {
9
- ClaudeAdapter.listSupportedModels()
10
- GeminiAdapter.listSupportedModels()
11
- MistralAdapter.listSupportedModels()
12
- try {
13
- await OllamaAdapter.listSupportedModels()
14
- } catch (error) {
15
- // do nothing, no ollama server running
16
- }
17
- OpenAIAdapter.listSupportedModels()
18
- AzureOpenAIAdapter.listSupportedModels()
19
- }
20
-
21
- export default listModels
@@ -1,9 +0,0 @@
1
- import ProxyManager from '../managers/ProxyManager'
2
- import type { ClovingGPTOptions } from '../utils/types'
3
-
4
- const proxy = async (options: ClovingGPTOptions) => {
5
- const proxyManager = new ProxyManager(options)
6
- await proxyManager.initialize()
7
- }
8
-
9
- export default proxy
@@ -1,82 +0,0 @@
1
- /**
2
- * @module tokens
3
- * This module provides functionality to estimate the number of tokens in the context files
4
- * and project description for GPT processing.
5
- */
6
-
7
- import fs from 'fs'
8
- import path from 'path'
9
- import { getNearestClovingConfig } from '../utils/config_utils'
10
- import { getAllFilesInDirectory } from '../utils/prompt_utils'
11
- import type { ClovingGPTOptions } from '../utils/types'
12
-
13
- /**
14
- * Calculates the estimated number of tokens for the given context files and project description.
15
- * @param {ClovingGPTOptions} options - The options for token calculation, including file paths.
16
- * @returns {Promise<void>} A promise that resolves when the token estimation is complete.
17
- */
18
- const tokens = async (options: ClovingGPTOptions): Promise<void> => {
19
- let contextFiles: Record<string, string> = {}
20
- let files = options.files || '.'
21
-
22
- let prompt = ''
23
-
24
- /**
25
- * Expands the given file paths to include all files in directories.
26
- * @type {string[]}
27
- */
28
- let expandedFiles: string[] = []
29
- for (const file of files) {
30
- const filePath = path.resolve(file)
31
- if (
32
- await fs.promises
33
- .stat(filePath)
34
- .then((stat) => stat.isDirectory())
35
- .catch(() => false)
36
- ) {
37
- const dirFiles = await getAllFilesInDirectory(filePath)
38
- expandedFiles = expandedFiles.concat(dirFiles.map((f) => path.relative(process.cwd(), f)))
39
- } else {
40
- expandedFiles.push(path.relative(process.cwd(), filePath))
41
- }
42
- }
43
- files = expandedFiles
44
-
45
- /**
46
- * Reads the content of each file and stores it in the contextFiles object.
47
- */
48
- for (const file of files) {
49
- const filePath = path.resolve(file)
50
- if (
51
- await fs.promises
52
- .stat(filePath)
53
- .then((stat) => stat.isFile())
54
- .catch(() => false)
55
- ) {
56
- const content = await fs.promises.readFile(filePath, 'utf-8')
57
- contextFiles[file] = content
58
- }
59
- }
60
-
61
- /**
62
- * Generates the prompt content by combining the app description and context file contents.
63
- */
64
- const contextFileContents = Object.keys(contextFiles)
65
- .map((file) => `### Contents of ${file}\n\n${contextFiles[file]}\n\n`)
66
- .join('\n')
67
- prompt += `
68
- ### Description of App
69
-
70
- ${JSON.stringify(getNearestClovingConfig().config, null, 2)}
71
-
72
- ${contextFileContents}`
73
-
74
- /**
75
- * Estimates the number of tokens based on the prompt length.
76
- * This is a rough estimation and may not be exact.
77
- */
78
- const tokens = Math.ceil(prompt.length / 4).toLocaleString()
79
- console.log(`Estimated tokens: ${tokens}`)
80
- }
81
-
82
- export default tokens
package/src/index.ts DELETED
@@ -1,197 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Command } from 'commander'
4
- import config from './commands/config'
5
- import init from './commands/init'
6
- import proxy from './commands/proxy'
7
- import tokens from './commands/tokens'
8
- import models from './commands/models'
9
- import chat from './commands/chat'
10
- import shell from './commands/generate/shell'
11
- import code from './commands/generate/code'
12
- import commit from './commands/generate/commit'
13
- import context from './commands/generate/context'
14
- import unitTests from './commands/generate/unit_tests'
15
- import analyze from './commands/generate/review'
16
- import docs from './commands/generate/docs'
17
- import { getPackageVersion } from './utils/prompt_utils'
18
-
19
- const program = new Command()
20
-
21
- program
22
- .name('cloving')
23
- .description(
24
- 'Integrate AI into your development workflow for generating commit messages, code reviews, and unit tests.',
25
- )
26
- .version(getPackageVersion())
27
-
28
- program
29
- .command('config')
30
- .description('Configure cloving with your API key and models to use')
31
- .action(config)
32
-
33
- program
34
- .command('init')
35
- .description('Setup cloving in the current directory')
36
- .option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
37
- .option(
38
- '-m, --model <model>',
39
- 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5-sonnet-20240620)',
40
- )
41
- .action(init)
42
-
43
- program
44
- .command('chat')
45
- .option(
46
- '-f, --files <filenames...>',
47
- 'Specify filenames of files with context to use for generating code',
48
- )
49
- .option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
50
- .option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
51
- .option(
52
- '-m, --model <model>',
53
- 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5:sonnet-20240620)',
54
- )
55
- .description('Start an interactive chat with cloving')
56
- .action(chat)
57
-
58
- program
59
- .command('proxy')
60
- .option(
61
- '-f, --files <filenames...>',
62
- 'Specify filenames of files with context to use for generating code',
63
- )
64
- .option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
65
- .option(
66
- '-m, --model <model>',
67
- 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5:sonnet-20240620)',
68
- )
69
- .description('Start a proxy server to use with cloving')
70
- .action(proxy)
71
-
72
- program.command('models').alias('m').description('List available models').action(models)
73
-
74
- program
75
- .command('tokens')
76
- .alias('t')
77
- .option(
78
- '-f, --files <filenames...>',
79
- 'Specify filenames of files with context to use for generating code',
80
- )
81
- .description('Estimate the number of tokens in the current working directory or specified files')
82
- .action(tokens)
83
-
84
- program
85
- .command('commit')
86
- .alias('c')
87
- .description('Alias for cloving generate commit')
88
- .option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
89
- .option(
90
- '-m, --model <model>',
91
- 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5-sonnet-20240620)',
92
- )
93
- .action(commit)
94
-
95
- // Generate commands
96
- const generate = program
97
- .command('generate')
98
- .alias('g')
99
- .description('Generate various items like unit-tests and code reviews')
100
-
101
- generate
102
- .command('shell')
103
- .alias('sh')
104
- .description('Generate a shell command based on a prompt')
105
- .option('-e, --exec', 'Automatically execute the generated shell command')
106
- .option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
107
- .option(
108
- '-m, --model <model>',
109
- 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5-sonnet-20240620)',
110
- )
111
- .option('-p, --prompt <prompt>', 'Specify the prompt to use')
112
- .option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
113
- .action(shell)
114
-
115
- generate
116
- .command('code')
117
- .alias('c')
118
- .description('Generate code based on a prompt')
119
- .option('--save', 'Automatically save all files after generating the code')
120
- .option(
121
- '-i, --interactive',
122
- 'Auto-save generated code and then show a new prompt with existing context to revise the code further',
123
- )
124
- .option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
125
- .option(
126
- '-m, --model <model>',
127
- 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5:sonnet-20240620)',
128
- )
129
- .option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
130
- .option('-p, --prompt <prompt>', 'Specify the prompt to use')
131
- .option(
132
- '-f, --files <filenames...>',
133
- 'Specify filenames of files with context to use for generating code',
134
- )
135
- .action(code)
136
-
137
- generate
138
- .command('commit')
139
- .description('Generate a commit message and commit the changes')
140
- .option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
141
- .option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
142
- .option(
143
- '-m, --model <model>',
144
- 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5-sonnet-20240620)',
145
- )
146
- .action(commit)
147
-
148
- generate
149
- .command('context')
150
- .description('Create a context string for generating code')
151
- .option('-f, --files <filenames...>', 'Specify filenames of files with context')
152
- .action(context)
153
-
154
- generate
155
- .command('unit-tests')
156
- .alias('u')
157
- .description(
158
- "Generate unit tests (if you don't specify filenames, it will generate tests for commited changes that differ from the main/master branch)",
159
- )
160
- .option('--save', 'Automatically save all files after generating the unit tests')
161
- .option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
162
- .option('-f, --files <filenames...>', 'Specify filenames for the unit tests')
163
- .option(
164
- '-m, --model <model>',
165
- 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5-sonnet-20240620)',
166
- )
167
- .option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
168
- .action(unitTests)
169
-
170
- generate
171
- .command('review')
172
- .alias('r')
173
- .description('Review the code for commited changes that differ from the main/master branch')
174
- .option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
175
- .option('-f, --files <filenames...>', 'Specify filenames for files you want to review')
176
- .option('-p, --prompt <prompt>', 'Add a prompt to the review')
177
- .option(
178
- '-m, --model <model>',
179
- 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5-sonnet-20240620)',
180
- )
181
- .option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
182
- .action(analyze)
183
-
184
- generate
185
- .command('docs')
186
- .alias('d')
187
- .description('Generate documentation for the project')
188
- .option('-s, --silent', 'Run the command without asking for confirmation of submitting prompts')
189
- .option('-f, --files <filenames...>', 'Specify filenames for files you want to document')
190
- .option(
191
- '-m, --model <model>',
192
- 'Select the model to use (e.g., openai, claude, ollama, ollama:llama3, claude:claude-3-5-sonnet-20240620)',
193
- )
194
- .option('-t, --temperature <temperature>', 'Temperature for the model (default 0.2)')
195
- .action(docs)
196
-
197
- program.parse(process.argv)
@@ -1,126 +0,0 @@
1
- import { EventEmitter } from 'events'
2
- import { extractCurrentNewBlocks } from '../utils/string_utils'
3
- import type { CurrentNewBlock } from '../utils/types'
4
-
5
- // Passes through string chunks, looking for code blocks, when it finds one, it starts buffering until it finds the end of the block
6
- // Then it emits the code block and clears the buffer and continues
7
- class BlockManager extends EventEmitter {
8
- private buffer: string = ''
9
- private codeBuffer: string = ''
10
- private isBufferingCode: boolean = false
11
- private isWaitingForContent: boolean = false
12
-
13
- // add content to the buffer, watching for code blocks along the way
14
- addContent(content: string) {
15
- if (content.includes('`') || content.includes('\n')) {
16
- this.isWaitingForContent = true
17
- this.buffer += content
18
- return
19
- } else if (this.isWaitingForContent) {
20
- content = this.buffer + content
21
- this.buffer = ''
22
- }
23
-
24
- // if content has multiple \n``` in the string, then we need to split it up
25
- const codeBlockRegex = /\n```[\s\S]*?\n```/g
26
- const codeBlocks = content.match(codeBlockRegex)
27
-
28
- if (codeBlocks) {
29
- let lastIndex = 0
30
- for (const block of codeBlocks) {
31
- const index = content.indexOf(block, lastIndex)
32
- this.processCodeBlocks(content.slice(lastIndex, index))
33
- this.processCodeBlocks(block)
34
- lastIndex = index + block.length
35
- }
36
- this.processCodeBlocks(content.slice(lastIndex))
37
- } else {
38
- this.processCodeBlocks(content)
39
- }
40
- }
41
-
42
- private processCodeBlocks(content: string) {
43
- const codeBlockMarker = '\n```'
44
- let markerIndex = content.indexOf(codeBlockMarker)
45
-
46
- if (markerIndex !== -1) {
47
- if (this.isBufferingCode) {
48
- this.codeBuffer += content.slice(0, markerIndex + codeBlockMarker.length)
49
- const rest = content.slice(markerIndex + codeBlockMarker.length)
50
- this.emit('endGeneratingCode')
51
- this.emitCodeBlock()
52
- this.emit('content', rest)
53
- } else {
54
- this.emitBuffer(content.slice(0, markerIndex))
55
- this.codeBuffer = content.slice(markerIndex)
56
- this.emit('startGeneratingCode')
57
- this.isBufferingCode = true
58
- }
59
- } else {
60
- if (this.isBufferingCode) {
61
- this.codeBuffer += content
62
- } else {
63
- this.buffer += content
64
- }
65
- }
66
-
67
- if (!this.isBufferingCode && this.buffer) {
68
- this.emitBuffer()
69
- }
70
- }
71
-
72
- private emitBuffer(additionalContent: string = '') {
73
- const contentToEmit = this.buffer + additionalContent
74
- if (contentToEmit) {
75
- this.emit('content', contentToEmit)
76
- this.clearBuffer()
77
- }
78
- }
79
-
80
- private emitCodeBlock() {
81
- if (this.codeBuffer.length > 0) {
82
- const currentNewBlock = this.parseCodeBuffer()
83
- this.emit('codeBlock', {
84
- currentNewBlock,
85
- raw: this.codeBuffer,
86
- })
87
- this.emit('content', this.buffer)
88
- this.clearBuffer()
89
- }
90
- }
91
-
92
- /**
93
- * Parses a code buffer into its constituent parts.
94
- *
95
- * This function takes a code buffer as a string, splits it into lines, and identifies the language,
96
- * current start index, divider index, and new end index. It then extracts the current code and new code
97
- * from the buffer based on these indices.
98
- *
99
- * @return {CurrentNewBlock | null}
100
- * An object containing the language, current start, new end, current code, and new code.
101
- */
102
- private parseCodeBuffer(): CurrentNewBlock | null {
103
- const results = extractCurrentNewBlocks(this.codeBuffer)
104
-
105
- if (results.length === 0) {
106
- return null
107
- }
108
-
109
- const block = results[0]
110
- if (!block.currentContent || !block.newContent) {
111
- console.warn('Incomplete code block detected. Skipping.')
112
- return null
113
- }
114
-
115
- return block
116
- }
117
-
118
- clearBuffer() {
119
- this.buffer = ''
120
- this.codeBuffer = ''
121
- this.isBufferingCode = false
122
- this.isWaitingForContent = false
123
- }
124
- }
125
-
126
- export default BlockManager