@eldrforge/kodrdriv 0.0.50 → 0.1.0
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/README.md +2 -1
- package/dist/application.js +5 -3
- package/dist/application.js.map +1 -1
- package/dist/arguments.js +97 -70
- package/dist/arguments.js.map +1 -1
- package/dist/commands/audio-commit.js +7 -7
- package/dist/commands/audio-commit.js.map +1 -1
- package/dist/commands/audio-review.js +13 -13
- package/dist/commands/audio-review.js.map +1 -1
- package/dist/commands/clean.js +2 -2
- package/dist/commands/clean.js.map +1 -1
- package/dist/commands/commit.js +301 -36
- package/dist/commands/commit.js.map +1 -1
- package/dist/commands/link.js +7 -7
- package/dist/commands/link.js.map +1 -1
- package/dist/commands/publish.js +285 -306
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/release.js +171 -14
- package/dist/commands/release.js.map +1 -1
- package/dist/commands/review.js +52 -40
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/select-audio.js +4 -4
- package/dist/commands/select-audio.js.map +1 -1
- package/dist/commands/tree.js +347 -34
- package/dist/commands/tree.js.map +1 -1
- package/dist/commands/unlink.js +5 -5
- package/dist/commands/unlink.js.map +1 -1
- package/dist/constants.js +28 -9
- package/dist/constants.js.map +1 -1
- package/dist/content/diff.js +122 -1
- package/dist/content/diff.js.map +1 -1
- package/dist/content/issues.js +17 -46
- package/dist/content/issues.js.map +1 -1
- package/dist/logging.js +3 -3
- package/dist/logging.js.map +1 -1
- package/dist/prompt/commit.js +2 -2
- package/dist/prompt/commit.js.map +1 -1
- package/dist/prompt/release.js +2 -2
- package/dist/prompt/release.js.map +1 -1
- package/dist/prompt/review.js +2 -2
- package/dist/prompt/review.js.map +1 -1
- package/dist/types.js +18 -5
- package/dist/types.js.map +1 -1
- package/dist/util/child.js +60 -4
- package/dist/util/child.js.map +1 -1
- package/dist/util/general.js +149 -13
- package/dist/util/general.js.map +1 -1
- package/dist/util/github.js +12 -8
- package/dist/util/github.js.map +1 -1
- package/dist/util/interactive.js +297 -0
- package/dist/util/interactive.js.map +1 -0
- package/dist/util/openai.js +87 -8
- package/dist/util/openai.js.map +1 -1
- package/dist/util/performance.js +8 -8
- package/dist/util/performance.js.map +1 -1
- package/dist/util/safety.js +4 -4
- package/dist/util/safety.js.map +1 -1
- package/dist/util/storage.js +2 -2
- package/dist/util/storage.js.map +1 -1
- package/package.json +6 -6
- package/test-increment.js +0 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { getDryRunLogger } from '../logging.js';
|
|
3
|
+
import { spawnSync } from 'child_process';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import * as os from 'os';
|
|
6
|
+
import * as fs from 'fs/promises';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Get user choice interactively from terminal input
|
|
10
|
+
* @param prompt The prompt message to display
|
|
11
|
+
* @param choices Array of available choices
|
|
12
|
+
* @param options Additional options for customizing behavior
|
|
13
|
+
* @returns Promise resolving to the selected choice key
|
|
14
|
+
*/ async function getUserChoice(prompt, choices, options = {}) {
|
|
15
|
+
const logger = getDryRunLogger(false);
|
|
16
|
+
logger.info(prompt);
|
|
17
|
+
choices.forEach((choice)=>{
|
|
18
|
+
logger.info(` [${choice.key}] ${choice.label}`);
|
|
19
|
+
});
|
|
20
|
+
logger.info('');
|
|
21
|
+
// Check if stdin is a TTY (terminal) or piped
|
|
22
|
+
if (!process.stdin.isTTY) {
|
|
23
|
+
logger.error('⚠️ STDIN is piped but interactive mode is enabled');
|
|
24
|
+
logger.error(' Interactive prompts cannot be used when input is piped');
|
|
25
|
+
logger.error(' Solutions:');
|
|
26
|
+
logger.error(' • Use terminal input instead of piping');
|
|
27
|
+
// Add any additional suggestions
|
|
28
|
+
if (options.nonTtyErrorSuggestions) {
|
|
29
|
+
options.nonTtyErrorSuggestions.forEach((suggestion)=>{
|
|
30
|
+
logger.error(` • ${suggestion}`);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return 's'; // Default to skip
|
|
34
|
+
}
|
|
35
|
+
return new Promise((resolve)=>{
|
|
36
|
+
// Ensure stdin is referenced so the process doesn't exit while waiting for input
|
|
37
|
+
if (typeof process.stdin.ref === 'function') {
|
|
38
|
+
process.stdin.ref();
|
|
39
|
+
}
|
|
40
|
+
process.stdin.setRawMode(true);
|
|
41
|
+
process.stdin.resume();
|
|
42
|
+
process.stdin.on('data', (key)=>{
|
|
43
|
+
const keyStr = key.toString().toLowerCase();
|
|
44
|
+
const choice = choices.find((c)=>c.key === keyStr);
|
|
45
|
+
if (choice) {
|
|
46
|
+
process.stdin.setRawMode(false);
|
|
47
|
+
process.stdin.pause();
|
|
48
|
+
// Detach stdin again now that we're done
|
|
49
|
+
if (typeof process.stdin.unref === 'function') {
|
|
50
|
+
process.stdin.unref();
|
|
51
|
+
}
|
|
52
|
+
logger.info(`Selected: ${choice.label}\n`);
|
|
53
|
+
resolve(choice.key);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Create a secure temporary file for editing with proper permissions
|
|
60
|
+
* @param prefix Prefix for the temporary filename
|
|
61
|
+
* @param extension File extension (e.g., '.txt', '.md')
|
|
62
|
+
* @returns Promise resolving to the temporary file path
|
|
63
|
+
*/ async function createSecureTempFile(prefix = 'kodrdriv', extension = '.txt') {
|
|
64
|
+
const tmpDir = os.tmpdir();
|
|
65
|
+
const tmpFilePath = path.join(tmpDir, `${prefix}_${Date.now()}_${Math.random().toString(36).substring(7)}${extension}`);
|
|
66
|
+
// Create file with restrictive permissions (owner read/write only)
|
|
67
|
+
const fd = await fs.open(tmpFilePath, 'w', 0o600);
|
|
68
|
+
await fd.close();
|
|
69
|
+
return tmpFilePath;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Clean up a temporary file
|
|
73
|
+
* @param filePath Path to the temporary file to clean up
|
|
74
|
+
*/ async function cleanupTempFile(filePath) {
|
|
75
|
+
try {
|
|
76
|
+
await fs.unlink(filePath);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
// Only ignore ENOENT (file not found) errors
|
|
79
|
+
if (error.code !== 'ENOENT') {
|
|
80
|
+
const logger = getDryRunLogger(false);
|
|
81
|
+
logger.warn(`Failed to cleanup temp file ${filePath}: ${error.message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Open content in user's editor for editing
|
|
87
|
+
* @param content Initial content to edit
|
|
88
|
+
* @param templateLines Additional template lines to include (will be filtered out)
|
|
89
|
+
* @param fileExtension File extension for syntax highlighting
|
|
90
|
+
* @returns Promise resolving to the edited content
|
|
91
|
+
*/ async function editContentInEditor(content, templateLines = [], fileExtension = '.txt') {
|
|
92
|
+
const logger = getDryRunLogger(false);
|
|
93
|
+
const editor = process.env.EDITOR || process.env.VISUAL || 'vi';
|
|
94
|
+
let tmpFilePath = null;
|
|
95
|
+
try {
|
|
96
|
+
// Create secure temporary file
|
|
97
|
+
tmpFilePath = await createSecureTempFile('kodrdriv_edit', fileExtension);
|
|
98
|
+
// Build template content
|
|
99
|
+
const templateContent = [
|
|
100
|
+
...templateLines,
|
|
101
|
+
...templateLines.length > 0 ? [
|
|
102
|
+
''
|
|
103
|
+
] : [],
|
|
104
|
+
content,
|
|
105
|
+
''
|
|
106
|
+
].join('\n');
|
|
107
|
+
await fs.writeFile(tmpFilePath, templateContent, 'utf8');
|
|
108
|
+
logger.info(`📝 Opening ${editor} to edit content...`);
|
|
109
|
+
// Open the editor synchronously
|
|
110
|
+
const result = spawnSync(editor, [
|
|
111
|
+
tmpFilePath
|
|
112
|
+
], {
|
|
113
|
+
stdio: 'inherit'
|
|
114
|
+
});
|
|
115
|
+
if (result.error) {
|
|
116
|
+
throw new Error(`Failed to launch editor '${editor}': ${result.error.message}`);
|
|
117
|
+
}
|
|
118
|
+
// Read the file back in, stripping comment lines
|
|
119
|
+
const fileContent = (await fs.readFile(tmpFilePath, 'utf8')).split('\n').filter((line)=>!line.trim().startsWith('#')).join('\n').trim();
|
|
120
|
+
if (!fileContent) {
|
|
121
|
+
throw new Error('Content is empty after editing');
|
|
122
|
+
}
|
|
123
|
+
logger.info('✅ Content updated successfully');
|
|
124
|
+
return {
|
|
125
|
+
content: fileContent,
|
|
126
|
+
wasEdited: fileContent !== content.trim()
|
|
127
|
+
};
|
|
128
|
+
} finally{
|
|
129
|
+
// Always clean up the temp file
|
|
130
|
+
if (tmpFilePath) {
|
|
131
|
+
await cleanupTempFile(tmpFilePath);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Standard choices for interactive feedback loops
|
|
137
|
+
*/ const STANDARD_CHOICES = {
|
|
138
|
+
CONFIRM: {
|
|
139
|
+
key: 'c',
|
|
140
|
+
label: 'Confirm and proceed'
|
|
141
|
+
},
|
|
142
|
+
EDIT: {
|
|
143
|
+
key: 'e',
|
|
144
|
+
label: 'Edit in editor'
|
|
145
|
+
},
|
|
146
|
+
SKIP: {
|
|
147
|
+
key: 's',
|
|
148
|
+
label: 'Skip and abort'
|
|
149
|
+
},
|
|
150
|
+
IMPROVE: {
|
|
151
|
+
key: 'i',
|
|
152
|
+
label: 'Improve with LLM feedback'
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Get text input from the user
|
|
157
|
+
* @param prompt The prompt message to display
|
|
158
|
+
* @param options Additional options for customizing behavior
|
|
159
|
+
* @returns Promise resolving to the user's text input
|
|
160
|
+
*/ async function getUserTextInput(prompt, options = {}) {
|
|
161
|
+
const logger = getDryRunLogger(false);
|
|
162
|
+
// Check if stdin is a TTY (terminal) or piped
|
|
163
|
+
if (!process.stdin.isTTY) {
|
|
164
|
+
logger.error('⚠️ STDIN is piped but interactive text input is required');
|
|
165
|
+
logger.error(' Interactive text input cannot be used when input is piped');
|
|
166
|
+
logger.error(' Solutions:');
|
|
167
|
+
logger.error(' • Use terminal input instead of piping');
|
|
168
|
+
// Add any additional suggestions
|
|
169
|
+
if (options.nonTtyErrorSuggestions) {
|
|
170
|
+
options.nonTtyErrorSuggestions.forEach((suggestion)=>{
|
|
171
|
+
logger.error(` • ${suggestion}`);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
throw new Error('Interactive text input requires a terminal');
|
|
175
|
+
}
|
|
176
|
+
logger.info(prompt);
|
|
177
|
+
logger.info('(Press Enter when done, or type Ctrl+C to cancel)');
|
|
178
|
+
logger.info('');
|
|
179
|
+
return new Promise((resolve, reject)=>{
|
|
180
|
+
let inputBuffer = '';
|
|
181
|
+
// Ensure stdin is referenced so the process doesn't exit while waiting for input
|
|
182
|
+
if (typeof process.stdin.ref === 'function') {
|
|
183
|
+
process.stdin.ref();
|
|
184
|
+
}
|
|
185
|
+
process.stdin.setEncoding('utf8');
|
|
186
|
+
process.stdin.resume();
|
|
187
|
+
const onData = (chunk)=>{
|
|
188
|
+
inputBuffer += chunk;
|
|
189
|
+
// Check if user pressed Enter (newline character)
|
|
190
|
+
if (inputBuffer.includes('\n')) {
|
|
191
|
+
cleanup();
|
|
192
|
+
const userInput = inputBuffer.replace(/\n$/, '').trim();
|
|
193
|
+
if (userInput === '') {
|
|
194
|
+
logger.warn('Empty input received. Please provide feedback text.');
|
|
195
|
+
reject(new Error('Empty input received'));
|
|
196
|
+
} else {
|
|
197
|
+
logger.info(`✅ Received feedback: "${userInput}"\n`);
|
|
198
|
+
resolve(userInput);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
const onError = (error)=>{
|
|
203
|
+
cleanup();
|
|
204
|
+
reject(error);
|
|
205
|
+
};
|
|
206
|
+
const cleanup = ()=>{
|
|
207
|
+
process.stdin.pause();
|
|
208
|
+
process.stdin.removeListener('data', onData);
|
|
209
|
+
process.stdin.removeListener('error', onError);
|
|
210
|
+
// Detach stdin again now that we're done
|
|
211
|
+
if (typeof process.stdin.unref === 'function') {
|
|
212
|
+
process.stdin.unref();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
process.stdin.on('data', onData);
|
|
216
|
+
process.stdin.on('error', onError);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get LLM improvement feedback from the user using the editor
|
|
221
|
+
* @param contentType Type of content being improved (e.g., 'commit message', 'release notes')
|
|
222
|
+
* @param currentContent The current content to be improved
|
|
223
|
+
* @returns Promise resolving to the user's feedback text
|
|
224
|
+
*/ async function getLLMFeedbackInEditor(contentType, currentContent) {
|
|
225
|
+
const templateLines = [
|
|
226
|
+
'# Provide Your Instructions and Guidance for a Revision Here',
|
|
227
|
+
'#',
|
|
228
|
+
'# Type your guidance above this line. Be specific about what you want changed,',
|
|
229
|
+
'# added, or improved. You can also edit the original content below directly',
|
|
230
|
+
'# to provide examples or show desired changes.',
|
|
231
|
+
'#',
|
|
232
|
+
'# Lines starting with "#" will be ignored.',
|
|
233
|
+
'',
|
|
234
|
+
'### YOUR FEEDBACK AND GUIDANCE:',
|
|
235
|
+
'',
|
|
236
|
+
'# (Type your improvement instructions here)',
|
|
237
|
+
'',
|
|
238
|
+
`### ORIGINAL ${contentType.toUpperCase()}:`,
|
|
239
|
+
''
|
|
240
|
+
];
|
|
241
|
+
const result = await editContentInEditor(currentContent, templateLines, '.md');
|
|
242
|
+
// Extract just the feedback section (everything before the original content)
|
|
243
|
+
const lines = result.content.split('\n');
|
|
244
|
+
const originalSectionIndex = lines.findIndex((line)=>line.trim().toLowerCase().startsWith('### original'));
|
|
245
|
+
let feedback;
|
|
246
|
+
if (originalSectionIndex >= 0) {
|
|
247
|
+
// Take everything before the "### ORIGINAL" section
|
|
248
|
+
feedback = lines.slice(0, originalSectionIndex).join('\n').trim();
|
|
249
|
+
} else {
|
|
250
|
+
// If no original section found, take everything
|
|
251
|
+
feedback = result.content.trim();
|
|
252
|
+
}
|
|
253
|
+
// Remove the feedback header if it exists
|
|
254
|
+
feedback = feedback.replace(/^### YOUR FEEDBACK AND GUIDANCE:\s*/i, '').trim();
|
|
255
|
+
if (!feedback) {
|
|
256
|
+
throw new Error('No feedback provided. Please provide improvement instructions.');
|
|
257
|
+
}
|
|
258
|
+
return feedback;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Check if interactive mode is available (TTY check)
|
|
262
|
+
* @param errorMessage Custom error message to throw if TTY not available
|
|
263
|
+
* @throws Error if not in TTY environment
|
|
264
|
+
*/ function requireTTY(errorMessage = 'Interactive mode requires a terminal. Use --dry-run instead.') {
|
|
265
|
+
if (!process.stdin.isTTY) {
|
|
266
|
+
const logger = getDryRunLogger(false);
|
|
267
|
+
logger.error('❌ Interactive mode requires a terminal (TTY)');
|
|
268
|
+
logger.error(' Solutions:');
|
|
269
|
+
logger.error(' • Run without piping input');
|
|
270
|
+
logger.error(' • Use --dry-run to see the generated content');
|
|
271
|
+
throw new Error(errorMessage);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Generic LLM improvement function that can be configured for different content types
|
|
276
|
+
* @param currentContent The current content to improve
|
|
277
|
+
* @param runConfig Runtime configuration
|
|
278
|
+
* @param promptConfig Prompt configuration
|
|
279
|
+
* @param promptContext Prompt context
|
|
280
|
+
* @param outputDirectory Output directory for debug files
|
|
281
|
+
* @param improvementConfig Configuration for this specific improvement type
|
|
282
|
+
* @returns Promise resolving to the improved content
|
|
283
|
+
*/ async function improveContentWithLLM(currentContent, runConfig, promptConfig, promptContext, outputDirectory, improvementConfig) {
|
|
284
|
+
const logger = getDryRunLogger(false);
|
|
285
|
+
logger.info(`🤖 Requesting LLM to improve the ${improvementConfig.contentType}...`);
|
|
286
|
+
// Create the improved prompt using the provided function
|
|
287
|
+
const improvedPromptResult = await improvementConfig.createImprovedPrompt(promptConfig, currentContent, promptContext);
|
|
288
|
+
// Call the LLM with the improved prompt
|
|
289
|
+
const improvedResponse = await improvementConfig.callLLM(improvedPromptResult, runConfig, outputDirectory);
|
|
290
|
+
// Process the response if a processor is provided
|
|
291
|
+
const finalResult = improvementConfig.processResponse ? improvementConfig.processResponse(improvedResponse) : improvedResponse;
|
|
292
|
+
logger.info(`✅ LLM has provided improved ${improvementConfig.contentType}`);
|
|
293
|
+
return finalResult;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export { STANDARD_CHOICES, cleanupTempFile, createSecureTempFile, editContentInEditor, getLLMFeedbackInEditor, getUserChoice, getUserTextInput, improveContentWithLLM, requireTTY };
|
|
297
|
+
//# sourceMappingURL=interactive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.js","sources":["../../src/util/interactive.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { getDryRunLogger } from '../logging';\nimport { spawnSync } from 'child_process';\nimport * as path from 'path';\nimport * as os from 'os';\nimport * as fs from 'fs/promises';\n\nexport interface Choice {\n key: string;\n label: string;\n}\n\nexport interface InteractiveOptions {\n /** Additional error message suggestions for non-TTY scenarios */\n nonTtyErrorSuggestions?: string[];\n}\n\n/**\n * Get user choice interactively from terminal input\n * @param prompt The prompt message to display\n * @param choices Array of available choices\n * @param options Additional options for customizing behavior\n * @returns Promise resolving to the selected choice key\n */\nexport async function getUserChoice(\n prompt: string,\n choices: Choice[],\n options: InteractiveOptions = {}\n): Promise<string> {\n const logger = getDryRunLogger(false);\n\n logger.info(prompt);\n choices.forEach(choice => {\n logger.info(` [${choice.key}] ${choice.label}`);\n });\n logger.info('');\n\n // Check if stdin is a TTY (terminal) or piped\n if (!process.stdin.isTTY) {\n logger.error('⚠️ STDIN is piped but interactive mode is enabled');\n logger.error(' Interactive prompts cannot be used when input is piped');\n logger.error(' Solutions:');\n logger.error(' • Use terminal input instead of piping');\n\n // Add any additional suggestions\n if (options.nonTtyErrorSuggestions) {\n options.nonTtyErrorSuggestions.forEach(suggestion => {\n logger.error(` • ${suggestion}`);\n });\n }\n\n return 's'; // Default to skip\n }\n\n return new Promise(resolve => {\n // Ensure stdin is referenced so the process doesn't exit while waiting for input\n if (typeof process.stdin.ref === 'function') {\n process.stdin.ref();\n }\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on('data', (key) => {\n const keyStr = key.toString().toLowerCase();\n const choice = choices.find(c => c.key === keyStr);\n if (choice) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n // Detach stdin again now that we're done\n if (typeof process.stdin.unref === 'function') {\n process.stdin.unref();\n }\n logger.info(`Selected: ${choice.label}\\n`);\n resolve(choice.key);\n }\n });\n });\n}\n\n/**\n * Create a secure temporary file for editing with proper permissions\n * @param prefix Prefix for the temporary filename\n * @param extension File extension (e.g., '.txt', '.md')\n * @returns Promise resolving to the temporary file path\n */\nexport async function createSecureTempFile(prefix: string = 'kodrdriv', extension: string = '.txt'): Promise<string> {\n const tmpDir = os.tmpdir();\n const tmpFilePath = path.join(tmpDir, `${prefix}_${Date.now()}_${Math.random().toString(36).substring(7)}${extension}`);\n\n // Create file with restrictive permissions (owner read/write only)\n const fd = await fs.open(tmpFilePath, 'w', 0o600);\n await fd.close();\n return tmpFilePath;\n}\n\n/**\n * Clean up a temporary file\n * @param filePath Path to the temporary file to clean up\n */\nexport async function cleanupTempFile(filePath: string): Promise<void> {\n try {\n await fs.unlink(filePath);\n } catch (error: any) {\n // Only ignore ENOENT (file not found) errors\n if (error.code !== 'ENOENT') {\n const logger = getDryRunLogger(false);\n logger.warn(`Failed to cleanup temp file ${filePath}: ${error.message}`);\n }\n }\n}\n\nexport interface EditorResult {\n content: string;\n wasEdited: boolean;\n}\n\n/**\n * Open content in user's editor for editing\n * @param content Initial content to edit\n * @param templateLines Additional template lines to include (will be filtered out)\n * @param fileExtension File extension for syntax highlighting\n * @returns Promise resolving to the edited content\n */\nexport async function editContentInEditor(\n content: string,\n templateLines: string[] = [],\n fileExtension: string = '.txt'\n): Promise<EditorResult> {\n const logger = getDryRunLogger(false);\n const editor = process.env.EDITOR || process.env.VISUAL || 'vi';\n\n let tmpFilePath: string | null = null;\n try {\n // Create secure temporary file\n tmpFilePath = await createSecureTempFile('kodrdriv_edit', fileExtension);\n\n // Build template content\n const templateContent = [\n ...templateLines,\n ...(templateLines.length > 0 ? [''] : []), // Add separator if we have template lines\n content,\n '',\n ].join('\\n');\n\n await fs.writeFile(tmpFilePath, templateContent, 'utf8');\n\n logger.info(`📝 Opening ${editor} to edit content...`);\n\n // Open the editor synchronously\n const result = spawnSync(editor, [tmpFilePath], { stdio: 'inherit' });\n\n if (result.error) {\n throw new Error(`Failed to launch editor '${editor}': ${result.error.message}`);\n }\n\n // Read the file back in, stripping comment lines\n const fileContent = (await fs.readFile(tmpFilePath, 'utf8'))\n .split('\\n')\n .filter(line => !line.trim().startsWith('#'))\n .join('\\n')\n .trim();\n\n if (!fileContent) {\n throw new Error('Content is empty after editing');\n }\n\n logger.info('✅ Content updated successfully');\n\n return {\n content: fileContent,\n wasEdited: fileContent !== content.trim()\n };\n\n } finally {\n // Always clean up the temp file\n if (tmpFilePath) {\n await cleanupTempFile(tmpFilePath);\n }\n }\n}\n\n/**\n * Standard choices for interactive feedback loops\n */\nexport const STANDARD_CHOICES = {\n CONFIRM: { key: 'c', label: 'Confirm and proceed' },\n EDIT: { key: 'e', label: 'Edit in editor' },\n SKIP: { key: 's', label: 'Skip and abort' },\n IMPROVE: { key: 'i', label: 'Improve with LLM feedback' }\n} as const;\n\n/**\n * Get text input from the user\n * @param prompt The prompt message to display\n * @param options Additional options for customizing behavior\n * @returns Promise resolving to the user's text input\n */\nexport async function getUserTextInput(\n prompt: string,\n options: InteractiveOptions = {}\n): Promise<string> {\n const logger = getDryRunLogger(false);\n\n // Check if stdin is a TTY (terminal) or piped\n if (!process.stdin.isTTY) {\n logger.error('⚠️ STDIN is piped but interactive text input is required');\n logger.error(' Interactive text input cannot be used when input is piped');\n logger.error(' Solutions:');\n logger.error(' • Use terminal input instead of piping');\n\n // Add any additional suggestions\n if (options.nonTtyErrorSuggestions) {\n options.nonTtyErrorSuggestions.forEach(suggestion => {\n logger.error(` • ${suggestion}`);\n });\n }\n\n throw new Error('Interactive text input requires a terminal');\n }\n\n logger.info(prompt);\n logger.info('(Press Enter when done, or type Ctrl+C to cancel)');\n logger.info('');\n\n return new Promise((resolve, reject) => {\n let inputBuffer = '';\n\n // Ensure stdin is referenced so the process doesn't exit while waiting for input\n if (typeof process.stdin.ref === 'function') {\n process.stdin.ref();\n }\n\n process.stdin.setEncoding('utf8');\n process.stdin.resume();\n\n const onData = (chunk: string) => {\n inputBuffer += chunk;\n\n // Check if user pressed Enter (newline character)\n if (inputBuffer.includes('\\n')) {\n cleanup();\n const userInput = inputBuffer.replace(/\\n$/, '').trim();\n\n if (userInput === '') {\n logger.warn('Empty input received. Please provide feedback text.');\n reject(new Error('Empty input received'));\n } else {\n logger.info(`✅ Received feedback: \"${userInput}\"\\n`);\n resolve(userInput);\n }\n }\n };\n\n const onError = (error: Error) => {\n cleanup();\n reject(error);\n };\n\n const cleanup = () => {\n process.stdin.pause();\n process.stdin.removeListener('data', onData);\n process.stdin.removeListener('error', onError);\n\n // Detach stdin again now that we're done\n if (typeof process.stdin.unref === 'function') {\n process.stdin.unref();\n }\n };\n\n process.stdin.on('data', onData);\n process.stdin.on('error', onError);\n });\n}\n\n/**\n * Get LLM improvement feedback from the user using the editor\n * @param contentType Type of content being improved (e.g., 'commit message', 'release notes')\n * @param currentContent The current content to be improved\n * @returns Promise resolving to the user's feedback text\n */\nexport async function getLLMFeedbackInEditor(\n contentType: string,\n currentContent: string\n): Promise<string> {\n const templateLines = [\n '# Provide Your Instructions and Guidance for a Revision Here',\n '#',\n '# Type your guidance above this line. Be specific about what you want changed,',\n '# added, or improved. You can also edit the original content below directly',\n '# to provide examples or show desired changes.',\n '#',\n '# Lines starting with \"#\" will be ignored.',\n '',\n '### YOUR FEEDBACK AND GUIDANCE:',\n '',\n '# (Type your improvement instructions here)',\n '',\n `### ORIGINAL ${contentType.toUpperCase()}:`,\n ''\n ];\n\n const result = await editContentInEditor(\n currentContent,\n templateLines,\n '.md'\n );\n\n // Extract just the feedback section (everything before the original content)\n const lines = result.content.split('\\n');\n const originalSectionIndex = lines.findIndex(line =>\n line.trim().toLowerCase().startsWith('### original')\n );\n\n let feedback: string;\n if (originalSectionIndex >= 0) {\n // Take everything before the \"### ORIGINAL\" section\n feedback = lines.slice(0, originalSectionIndex).join('\\n').trim();\n } else {\n // If no original section found, take everything\n feedback = result.content.trim();\n }\n\n // Remove the feedback header if it exists\n feedback = feedback.replace(/^### YOUR FEEDBACK AND GUIDANCE:\\s*/i, '').trim();\n\n if (!feedback) {\n throw new Error('No feedback provided. Please provide improvement instructions.');\n }\n\n return feedback;\n}\n\n/**\n * Check if interactive mode is available (TTY check)\n * @param errorMessage Custom error message to throw if TTY not available\n * @throws Error if not in TTY environment\n */\nexport function requireTTY(errorMessage: string = 'Interactive mode requires a terminal. Use --dry-run instead.'): void {\n if (!process.stdin.isTTY) {\n const logger = getDryRunLogger(false);\n logger.error('❌ Interactive mode requires a terminal (TTY)');\n logger.error(' Solutions:');\n logger.error(' • Run without piping input');\n logger.error(' • Use --dry-run to see the generated content');\n throw new Error(errorMessage);\n }\n}\n\nexport interface LLMImprovementConfig {\n /** The type of content being improved (for filenames and logging) */\n contentType: string;\n /** Function that creates a prompt for improvement */\n createImprovedPrompt: (\n promptConfig: any,\n improvementContent: any,\n promptContext: any\n ) => Promise<any>;\n /** Function that calls LLM with the improved prompt */\n callLLM: (\n request: any,\n runConfig: any,\n outputDirectory: string\n ) => Promise<any>;\n /** Function that validates/processes the LLM response */\n processResponse?: (response: any) => any;\n}\n\n/**\n * Generic LLM improvement function that can be configured for different content types\n * @param currentContent The current content to improve\n * @param runConfig Runtime configuration\n * @param promptConfig Prompt configuration\n * @param promptContext Prompt context\n * @param outputDirectory Output directory for debug files\n * @param improvementConfig Configuration for this specific improvement type\n * @returns Promise resolving to the improved content\n */\nexport async function improveContentWithLLM<T>(\n currentContent: T,\n runConfig: any,\n promptConfig: any,\n promptContext: any,\n outputDirectory: string,\n improvementConfig: LLMImprovementConfig\n): Promise<T> {\n const logger = getDryRunLogger(false);\n\n logger.info(`🤖 Requesting LLM to improve the ${improvementConfig.contentType}...`);\n\n // Create the improved prompt using the provided function\n const improvedPromptResult = await improvementConfig.createImprovedPrompt(\n promptConfig,\n currentContent,\n promptContext\n );\n\n // Call the LLM with the improved prompt\n const improvedResponse = await improvementConfig.callLLM(improvedPromptResult, runConfig, outputDirectory);\n\n // Process the response if a processor is provided\n const finalResult = improvementConfig.processResponse\n ? improvementConfig.processResponse(improvedResponse)\n : improvedResponse;\n\n logger.info(`✅ LLM has provided improved ${improvementConfig.contentType}`);\n return finalResult;\n}\n"],"names":["getUserChoice","prompt","choices","options","logger","getDryRunLogger","info","forEach","choice","key","label","process","stdin","isTTY","error","nonTtyErrorSuggestions","suggestion","Promise","resolve","ref","setRawMode","resume","on","keyStr","toString","toLowerCase","find","c","pause","unref","createSecureTempFile","prefix","extension","tmpDir","os","tmpdir","tmpFilePath","path","join","Date","now","Math","random","substring","fd","fs","open","close","cleanupTempFile","filePath","unlink","code","warn","message","editContentInEditor","content","templateLines","fileExtension","editor","env","EDITOR","VISUAL","templateContent","length","writeFile","result","spawnSync","stdio","Error","fileContent","readFile","split","filter","line","trim","startsWith","wasEdited","STANDARD_CHOICES","CONFIRM","EDIT","SKIP","IMPROVE","getUserTextInput","reject","inputBuffer","setEncoding","onData","chunk","includes","cleanup","userInput","replace","onError","removeListener","getLLMFeedbackInEditor","contentType","currentContent","toUpperCase","lines","originalSectionIndex","findIndex","feedback","slice","requireTTY","errorMessage","improveContentWithLLM","runConfig","promptConfig","promptContext","outputDirectory","improvementConfig","improvedPromptResult","createImprovedPrompt","improvedResponse","callLLM","finalResult","processResponse"],"mappings":"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AAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,C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"}
|
package/dist/util/openai.js
CHANGED
|
@@ -3,12 +3,55 @@ import { create } from './storage.js';
|
|
|
3
3
|
import { getLogger } from '../logging.js';
|
|
4
4
|
import { archiveAudio } from './general.js';
|
|
5
5
|
|
|
6
|
+
function _define_property(obj, key, value) {
|
|
7
|
+
if (key in obj) {
|
|
8
|
+
Object.defineProperty(obj, key, {
|
|
9
|
+
value: value,
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
writable: true
|
|
13
|
+
});
|
|
14
|
+
} else {
|
|
15
|
+
obj[key] = value;
|
|
16
|
+
}
|
|
17
|
+
return obj;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get the appropriate model to use based on command-specific configuration
|
|
21
|
+
* Command-specific model overrides the global model setting
|
|
22
|
+
*/ function getModelForCommand(config, commandName) {
|
|
23
|
+
let commandModel;
|
|
24
|
+
switch(commandName){
|
|
25
|
+
case 'commit':
|
|
26
|
+
case 'audio-commit':
|
|
27
|
+
var _config_commit;
|
|
28
|
+
commandModel = (_config_commit = config.commit) === null || _config_commit === void 0 ? void 0 : _config_commit.model;
|
|
29
|
+
break;
|
|
30
|
+
case 'release':
|
|
31
|
+
var _config_release;
|
|
32
|
+
commandModel = (_config_release = config.release) === null || _config_release === void 0 ? void 0 : _config_release.model;
|
|
33
|
+
break;
|
|
34
|
+
case 'review':
|
|
35
|
+
case 'audio-review':
|
|
36
|
+
var _config_review;
|
|
37
|
+
commandModel = (_config_review = config.review) === null || _config_review === void 0 ? void 0 : _config_review.model;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
// Return command-specific model if available, otherwise global model
|
|
41
|
+
return commandModel || config.model || 'gpt-4o-mini';
|
|
42
|
+
}
|
|
6
43
|
class OpenAIError extends Error {
|
|
7
|
-
constructor(message){
|
|
8
|
-
super(message);
|
|
44
|
+
constructor(message, isTokenLimitError = false){
|
|
45
|
+
super(message), _define_property(this, "isTokenLimitError", void 0), this.isTokenLimitError = isTokenLimitError;
|
|
9
46
|
this.name = 'OpenAIError';
|
|
10
47
|
}
|
|
11
48
|
}
|
|
49
|
+
// Check if an error is a token limit exceeded error
|
|
50
|
+
function isTokenLimitError(error) {
|
|
51
|
+
if (!(error === null || error === void 0 ? void 0 : error.message)) return false;
|
|
52
|
+
const message = error.message.toLowerCase();
|
|
53
|
+
return message.includes('maximum context length') || message.includes('context_length_exceeded') || message.includes('token limit') || message.includes('too many tokens') || message.includes('reduce the length');
|
|
54
|
+
}
|
|
12
55
|
async function createCompletion(messages, options = {
|
|
13
56
|
model: "gpt-4o-mini"
|
|
14
57
|
}) {
|
|
@@ -24,17 +67,20 @@ async function createCompletion(messages, options = {
|
|
|
24
67
|
throw new OpenAIError('OPENAI_API_KEY environment variable is not set');
|
|
25
68
|
}
|
|
26
69
|
// Create the client which we'll close in the finally block.
|
|
70
|
+
const timeoutMs = parseInt(process.env.OPENAI_TIMEOUT_MS || '300000'); // Default to 5 minutes
|
|
27
71
|
openai = new OpenAI({
|
|
28
72
|
apiKey: apiKey,
|
|
29
|
-
timeout:
|
|
73
|
+
timeout: timeoutMs
|
|
30
74
|
});
|
|
75
|
+
const modelToUse = options.model || "gpt-4o-mini";
|
|
76
|
+
logger.info('🤖 Making request to OpenAI using model: %s', modelToUse);
|
|
31
77
|
logger.debug('Sending prompt to OpenAI: %j', messages);
|
|
32
78
|
// Use provided maxTokens or default to 10000
|
|
33
79
|
const maxCompletionTokens = options.maxTokens || 10000;
|
|
34
80
|
// Save request debug file if enabled
|
|
35
81
|
if (options.debug && (options.debugRequestFile || options.debugFile)) {
|
|
36
82
|
const requestData = {
|
|
37
|
-
model:
|
|
83
|
+
model: modelToUse,
|
|
38
84
|
messages,
|
|
39
85
|
max_completion_tokens: maxCompletionTokens,
|
|
40
86
|
response_format: options.responseFormat
|
|
@@ -45,13 +91,14 @@ async function createCompletion(messages, options = {
|
|
|
45
91
|
}
|
|
46
92
|
// Add timeout wrapper to the OpenAI API call
|
|
47
93
|
const completionPromise = openai.chat.completions.create({
|
|
48
|
-
model:
|
|
94
|
+
model: modelToUse,
|
|
49
95
|
messages,
|
|
50
96
|
max_completion_tokens: maxCompletionTokens,
|
|
51
97
|
response_format: options.responseFormat
|
|
52
98
|
});
|
|
53
99
|
const timeoutPromise = new Promise((_, reject)=>{
|
|
54
|
-
|
|
100
|
+
const timeoutMs = parseInt(process.env.OPENAI_TIMEOUT_MS || '300000'); // Default to 5 minutes
|
|
101
|
+
setTimeout(()=>reject(new OpenAIError(`OpenAI API call timed out after ${timeoutMs / 1000} seconds`)), timeoutMs);
|
|
55
102
|
});
|
|
56
103
|
const completion = await Promise.race([
|
|
57
104
|
completionPromise,
|
|
@@ -75,12 +122,44 @@ async function createCompletion(messages, options = {
|
|
|
75
122
|
}
|
|
76
123
|
} catch (error) {
|
|
77
124
|
logger.error('Error calling OpenAI API: %s %s', error.message, error.stack);
|
|
78
|
-
|
|
125
|
+
const isTokenError = isTokenLimitError(error);
|
|
126
|
+
throw new OpenAIError(`Failed to create completion: ${error.message}`, isTokenError);
|
|
79
127
|
} finally{
|
|
80
128
|
// OpenAI client cleanup is handled automatically by the library
|
|
81
129
|
// No manual cleanup needed for newer versions
|
|
82
130
|
}
|
|
83
131
|
}
|
|
132
|
+
// Create completion with automatic retry on token limit errors
|
|
133
|
+
async function createCompletionWithRetry(messages, options = {
|
|
134
|
+
model: "gpt-4o-mini"
|
|
135
|
+
}, retryCallback) {
|
|
136
|
+
const logger = getLogger();
|
|
137
|
+
const maxRetries = 3;
|
|
138
|
+
for(let attempt = 1; attempt <= maxRetries; attempt++){
|
|
139
|
+
try {
|
|
140
|
+
const messagesToSend = attempt === 1 ? messages : retryCallback ? await retryCallback(attempt) : messages;
|
|
141
|
+
return await createCompletion(messagesToSend, options);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
var _error_message;
|
|
144
|
+
if (error instanceof OpenAIError && error.isTokenLimitError && attempt < maxRetries && retryCallback) {
|
|
145
|
+
logger.warn('Token limit exceeded on attempt %d/%d, retrying with reduced content...', attempt, maxRetries);
|
|
146
|
+
// Add exponential backoff for token limit errors
|
|
147
|
+
const backoffMs = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
|
|
148
|
+
await new Promise((resolve)=>setTimeout(resolve, backoffMs));
|
|
149
|
+
continue;
|
|
150
|
+
} else if (((_error_message = error.message) === null || _error_message === void 0 ? void 0 : _error_message.includes('rate limit')) && attempt < maxRetries) {
|
|
151
|
+
// Handle rate limiting with exponential backoff
|
|
152
|
+
const backoffMs = Math.min(5000 * Math.pow(2, attempt - 1), 30000);
|
|
153
|
+
logger.warn(`Rate limit hit on attempt ${attempt}/${maxRetries}, waiting ${backoffMs}ms before retry...`);
|
|
154
|
+
await new Promise((resolve)=>setTimeout(resolve, backoffMs));
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// This should never be reached, but TypeScript requires it
|
|
161
|
+
throw new OpenAIError('Max retries exceeded');
|
|
162
|
+
}
|
|
84
163
|
async function transcribeAudio(filePath, options = {
|
|
85
164
|
model: "whisper-1"
|
|
86
165
|
}) {
|
|
@@ -153,5 +232,5 @@ async function transcribeAudio(filePath, options = {
|
|
|
153
232
|
}
|
|
154
233
|
}
|
|
155
234
|
|
|
156
|
-
export { OpenAIError, createCompletion, transcribeAudio };
|
|
235
|
+
export { OpenAIError, createCompletion, createCompletionWithRetry, getModelForCommand, isTokenLimitError, transcribeAudio };
|
|
157
236
|
//# sourceMappingURL=openai.js.map
|