@eldrforge/kodrdriv 0.0.51 → 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clean.js","sources":["../../src/commands/clean.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { DEFAULT_OUTPUT_DIRECTORY } from '../constants';\nimport { FileOperationError } from '../error/CommandErrors';\nimport { getDryRunLogger, getLogger } from '../logging';\nimport { Config } from '../types';\nimport { create as createStorage } from '../util/storage';\n\nconst executeInternal = async (runConfig: Config): Promise<void> => {\n const isDryRun = runConfig.dryRun || false;\n const logger = getDryRunLogger(isDryRun);\n const storage = createStorage({ log: logger.info });\n\n const outputDirectory = runConfig.outputDirectory || DEFAULT_OUTPUT_DIRECTORY;\n\n if (isDryRun) {\n logger.info(`Would remove output directory: ${outputDirectory}`);\n logger.info(`Would check if output directory exists: ${outputDirectory}`);\n logger.info('Would remove directory if it exists');\n return;\n }\n\n logger.info(`Removing output directory: ${outputDirectory}`);\n\n try {\n if (await storage.exists(outputDirectory)) {\n await storage.removeDirectory(outputDirectory);\n logger.info(`Successfully removed output directory: ${outputDirectory}`);\n } else {\n logger.info(`Output directory does not exist: ${outputDirectory}`);\n }\n } catch (error: any) {\n logger.error(`Failed to clean output directory: ${error.message}`);\n throw new FileOperationError('Failed to remove output directory', outputDirectory, error);\n }\n};\n\nexport const execute = async (runConfig: Config): Promise<void> => {\n try {\n await executeInternal(runConfig);\n } catch (error: any) {\n const logger = getLogger();\n\n if (error instanceof FileOperationError) {\n logger.error(`clean failed: ${error.message}`);\n if (error.cause) {\n logger.debug(`Caused by: ${error.cause.message}`);\n }\n
|
|
1
|
+
{"version":3,"file":"clean.js","sources":["../../src/commands/clean.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { DEFAULT_OUTPUT_DIRECTORY } from '../constants';\nimport { FileOperationError } from '../error/CommandErrors';\nimport { getDryRunLogger, getLogger } from '../logging';\nimport { Config } from '../types';\nimport { create as createStorage } from '../util/storage';\n\nconst executeInternal = async (runConfig: Config): Promise<void> => {\n const isDryRun = runConfig.dryRun || false;\n const logger = getDryRunLogger(isDryRun);\n const storage = createStorage({ log: logger.info });\n\n const outputDirectory = runConfig.outputDirectory || DEFAULT_OUTPUT_DIRECTORY;\n\n if (isDryRun) {\n logger.info(`Would remove output directory: ${outputDirectory}`);\n logger.info(`Would check if output directory exists: ${outputDirectory}`);\n logger.info('Would remove directory if it exists');\n return;\n }\n\n logger.info(`Removing output directory: ${outputDirectory}`);\n\n try {\n if (await storage.exists(outputDirectory)) {\n await storage.removeDirectory(outputDirectory);\n logger.info(`Successfully removed output directory: ${outputDirectory}`);\n } else {\n logger.info(`Output directory does not exist: ${outputDirectory}`);\n }\n } catch (error: any) {\n logger.error(`Failed to clean output directory: ${error.message}`);\n throw new FileOperationError('Failed to remove output directory', outputDirectory, error);\n }\n};\n\nexport const execute = async (runConfig: Config): Promise<void> => {\n try {\n await executeInternal(runConfig);\n } catch (error: any) {\n const logger = getLogger();\n\n if (error instanceof FileOperationError) {\n logger.error(`clean failed: ${error.message}`);\n if (error.cause) {\n logger.debug(`Caused by: ${error.cause.message}`);\n }\n throw error;\n }\n\n // Unexpected errors\n logger.error(`clean encountered unexpected error: ${error.message}`);\n throw error;\n }\n};\n"],"names":["executeInternal","runConfig","isDryRun","dryRun","logger","getDryRunLogger","storage","createStorage","log","info","outputDirectory","DEFAULT_OUTPUT_DIRECTORY","exists","removeDirectory","error","message","FileOperationError","execute","getLogger","cause","debug"],"mappings":"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"}
|
package/dist/commands/commit.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { Formatter } from '@riotprompt/riotprompt';
|
|
3
3
|
import 'dotenv/config';
|
|
4
4
|
import shellescape from 'shell-escape';
|
|
5
|
-
import { DEFAULT_EXCLUDED_PATTERNS, DEFAULT_OUTPUT_DIRECTORY } from '../constants.js';
|
|
6
|
-
import { create, hasStagedChanges } from '../content/diff.js';
|
|
5
|
+
import { DEFAULT_MAX_DIFF_BYTES, DEFAULT_EXCLUDED_PATTERNS, DEFAULT_OUTPUT_DIRECTORY } from '../constants.js';
|
|
6
|
+
import { create, hasCriticalExcludedChanges, getMinimalExcludedPatterns, hasStagedChanges, truncateDiffByFiles } from '../content/diff.js';
|
|
7
7
|
import { create as create$1 } from '../content/log.js';
|
|
8
8
|
import { ValidationError, ExternalDependencyError, CommandError } from '../error/CommandErrors.js';
|
|
9
9
|
import { getDryRunLogger } from '../logging.js';
|
|
@@ -11,19 +11,156 @@ import { createPrompt } from '../prompt/commit.js';
|
|
|
11
11
|
import { run } from '../util/child.js';
|
|
12
12
|
import { validateString } from '../util/validation.js';
|
|
13
13
|
import { stringifyJSON, getOutputPath, getTimestampedResponseFilename, getTimestampedRequestFilename, getTimestampedCommitFilename } from '../util/general.js';
|
|
14
|
-
import {
|
|
14
|
+
import { getModelForCommand, createCompletionWithRetry } from '../util/openai.js';
|
|
15
15
|
import { checkForFileDependencies, logFileDependencyWarning, logFileDependencySuggestions } from '../util/safety.js';
|
|
16
16
|
import { create as create$2 } from '../util/storage.js';
|
|
17
|
+
import { requireTTY, getUserChoice, STANDARD_CHOICES, getLLMFeedbackInEditor, improveContentWithLLM, editContentInEditor } from '../util/interactive.js';
|
|
17
18
|
|
|
19
|
+
// Helper function to edit commit message using editor
|
|
20
|
+
async function editCommitMessageInteractively(commitMessage) {
|
|
21
|
+
const templateLines = [
|
|
22
|
+
'# Edit your commit message below. Lines starting with "#" will be ignored.',
|
|
23
|
+
'# Save and close the editor when you are done.'
|
|
24
|
+
];
|
|
25
|
+
const result = await editContentInEditor(commitMessage, templateLines, '.txt');
|
|
26
|
+
return result.content;
|
|
27
|
+
}
|
|
28
|
+
// Helper function to improve commit message using LLM
|
|
29
|
+
async function improveCommitMessageWithLLM(commitMessage, runConfig, promptConfig, promptContext, outputDirectory, diffContent) {
|
|
30
|
+
// Get user feedback on what to improve using the editor
|
|
31
|
+
const userFeedback = await getLLMFeedbackInEditor('commit message', commitMessage);
|
|
32
|
+
const improvementConfig = {
|
|
33
|
+
contentType: 'commit message',
|
|
34
|
+
createImprovedPrompt: async (promptConfig, currentMessage, promptContext)=>{
|
|
35
|
+
const improvementPromptContent = {
|
|
36
|
+
diffContent: diffContent,
|
|
37
|
+
userDirection: `Please improve this commit message based on the user's feedback: "${userFeedback}".
|
|
38
|
+
|
|
39
|
+
Current commit message: "${currentMessage}"
|
|
40
|
+
|
|
41
|
+
Please revise the commit message according to the user's feedback while maintaining accuracy and following conventional commit standards if appropriate.`
|
|
42
|
+
};
|
|
43
|
+
const prompt = await createPrompt(promptConfig, improvementPromptContent, promptContext);
|
|
44
|
+
// Format the prompt into a proper request with messages
|
|
45
|
+
const modelToUse = getModelForCommand(runConfig, 'commit');
|
|
46
|
+
return Formatter.create({
|
|
47
|
+
logger: getDryRunLogger(false)
|
|
48
|
+
}).formatPrompt(modelToUse, prompt);
|
|
49
|
+
},
|
|
50
|
+
callLLM: async (request, runConfig, outputDirectory)=>{
|
|
51
|
+
const modelToUse = getModelForCommand(runConfig, 'commit');
|
|
52
|
+
return await createCompletionWithRetry(request.messages, {
|
|
53
|
+
model: modelToUse,
|
|
54
|
+
debug: runConfig.debug,
|
|
55
|
+
debugRequestFile: getOutputPath(outputDirectory, getTimestampedRequestFilename('commit-improve')),
|
|
56
|
+
debugResponseFile: getOutputPath(outputDirectory, getTimestampedResponseFilename('commit-improve'))
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return await improveContentWithLLM(commitMessage, runConfig, promptConfig, promptContext, outputDirectory, improvementConfig);
|
|
61
|
+
}
|
|
62
|
+
// Interactive feedback loop for commit message
|
|
63
|
+
async function handleInteractiveCommitFeedback(commitMessage, runConfig, promptConfig, promptContext, outputDirectory, storage, diffContent, hasActualChanges, cached) {
|
|
64
|
+
var _runConfig_commit, _runConfig_commit1;
|
|
65
|
+
const logger = getDryRunLogger(false);
|
|
66
|
+
let currentMessage = commitMessage;
|
|
67
|
+
// Determine what the confirm action will do based on configuration
|
|
68
|
+
const senditEnabled = (_runConfig_commit = runConfig.commit) === null || _runConfig_commit === void 0 ? void 0 : _runConfig_commit.sendit;
|
|
69
|
+
const willActuallyCommit = senditEnabled && hasActualChanges && cached;
|
|
70
|
+
// Create dynamic confirm choice based on configuration
|
|
71
|
+
const isAmendMode = (_runConfig_commit1 = runConfig.commit) === null || _runConfig_commit1 === void 0 ? void 0 : _runConfig_commit1.amend;
|
|
72
|
+
const confirmChoice = willActuallyCommit ? {
|
|
73
|
+
key: 'c',
|
|
74
|
+
label: isAmendMode ? 'Amend last commit with this message (sendit enabled)' : 'Commit changes with this message (sendit enabled)'
|
|
75
|
+
} : {
|
|
76
|
+
key: 'c',
|
|
77
|
+
label: 'Accept message (you will need to commit manually)'
|
|
78
|
+
};
|
|
79
|
+
while(true){
|
|
80
|
+
// Display the current commit message
|
|
81
|
+
logger.info('\n📝 Generated Commit Message:');
|
|
82
|
+
logger.info('─'.repeat(50));
|
|
83
|
+
logger.info(currentMessage);
|
|
84
|
+
logger.info('─'.repeat(50));
|
|
85
|
+
// Show configuration status
|
|
86
|
+
if (senditEnabled) {
|
|
87
|
+
if (willActuallyCommit) {
|
|
88
|
+
logger.info('\n⚙️ SendIt mode is ACTIVE - choosing "Commit" will run git commit automatically');
|
|
89
|
+
} else {
|
|
90
|
+
logger.info('\n⚙️ SendIt mode is configured but no staged changes available for commit');
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
logger.info('\n⚙️ SendIt mode is NOT active - choosing "Accept" will only save the message');
|
|
94
|
+
}
|
|
95
|
+
// Get user choice
|
|
96
|
+
const userChoice = await getUserChoice('\nWhat would you like to do with this commit message?', [
|
|
97
|
+
confirmChoice,
|
|
98
|
+
STANDARD_CHOICES.EDIT,
|
|
99
|
+
STANDARD_CHOICES.SKIP,
|
|
100
|
+
STANDARD_CHOICES.IMPROVE
|
|
101
|
+
], {
|
|
102
|
+
nonTtyErrorSuggestions: [
|
|
103
|
+
'Use --sendit flag to auto-commit without review'
|
|
104
|
+
]
|
|
105
|
+
});
|
|
106
|
+
switch(userChoice){
|
|
107
|
+
case 'c':
|
|
108
|
+
return {
|
|
109
|
+
action: 'commit',
|
|
110
|
+
finalMessage: currentMessage
|
|
111
|
+
};
|
|
112
|
+
case 'e':
|
|
113
|
+
try {
|
|
114
|
+
currentMessage = await editCommitMessageInteractively(currentMessage);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
logger.error(`Failed to edit commit message: ${error.message}`);
|
|
117
|
+
// Continue the loop to show options again
|
|
118
|
+
}
|
|
119
|
+
break;
|
|
120
|
+
case 's':
|
|
121
|
+
return {
|
|
122
|
+
action: 'skip',
|
|
123
|
+
finalMessage: currentMessage
|
|
124
|
+
};
|
|
125
|
+
case 'i':
|
|
126
|
+
try {
|
|
127
|
+
currentMessage = await improveCommitMessageWithLLM(currentMessage, runConfig, promptConfig, promptContext, outputDirectory, diffContent);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
logger.error(`Failed to improve commit message: ${error.message}`);
|
|
130
|
+
// Continue the loop to show options again
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Helper function to check if there are any commits in the repository
|
|
137
|
+
const hasCommits = async ()=>{
|
|
138
|
+
try {
|
|
139
|
+
await run('git rev-parse HEAD');
|
|
140
|
+
return true;
|
|
141
|
+
} catch {
|
|
142
|
+
// No commits found or not a git repository
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
};
|
|
18
146
|
// Simplified cached determination with single check
|
|
19
147
|
const determineCachedState = async (config)=>{
|
|
20
|
-
var _config_commit, _config_commit1;
|
|
148
|
+
var _config_commit, _config_commit1, _config_commit2;
|
|
149
|
+
// If amend is used, we use staged changes (since we're amending the last commit)
|
|
150
|
+
if ((_config_commit = config.commit) === null || _config_commit === void 0 ? void 0 : _config_commit.amend) {
|
|
151
|
+
// For amend mode, check that there's a previous commit to amend
|
|
152
|
+
const hasAnyCommits = await hasCommits();
|
|
153
|
+
if (!hasAnyCommits) {
|
|
154
|
+
throw new ValidationError('Cannot use --amend: no commits found in repository. Create an initial commit first.');
|
|
155
|
+
}
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
21
158
|
// If add is used, we always look at staged changes after add
|
|
22
|
-
if ((
|
|
159
|
+
if ((_config_commit1 = config.commit) === null || _config_commit1 === void 0 ? void 0 : _config_commit1.add) {
|
|
23
160
|
return true;
|
|
24
161
|
}
|
|
25
162
|
// If explicitly set, use that value
|
|
26
|
-
if (((
|
|
163
|
+
if (((_config_commit2 = config.commit) === null || _config_commit2 === void 0 ? void 0 : _config_commit2.cached) !== undefined) {
|
|
27
164
|
return config.commit.cached;
|
|
28
165
|
}
|
|
29
166
|
// Otherwise, check if there are staged changes
|
|
@@ -73,15 +210,18 @@ const saveCommitMessage = async (outputDirectory, summary, storage, logger)=>{
|
|
|
73
210
|
}
|
|
74
211
|
};
|
|
75
212
|
const executeInternal = async (runConfig)=>{
|
|
76
|
-
var _runConfig_commit, _runConfig_commit1, _runConfig_commit2, _runConfig_commit3, _runConfig_commit4, _runConfig_commit5, _runConfig_commit6, _runConfig_commit7, _runConfig_commit8;
|
|
213
|
+
var _runConfig_commit, _runConfig_commit1, _runConfig_commit2, _runConfig_commit3, _runConfig_commit4, _runConfig_commit5, _runConfig_commit6, _runConfig_commit7, _runConfig_commit8, _runConfig_commit9;
|
|
77
214
|
const isDryRun = runConfig.dryRun || false;
|
|
78
215
|
const logger = getDryRunLogger(isDryRun);
|
|
216
|
+
// Track if user explicitly chose to skip in interactive mode
|
|
217
|
+
let userSkippedCommit = false;
|
|
79
218
|
if ((_runConfig_commit = runConfig.commit) === null || _runConfig_commit === void 0 ? void 0 : _runConfig_commit.add) {
|
|
80
219
|
if (isDryRun) {
|
|
81
220
|
logger.info('Would add all changes to the index with: git add -A');
|
|
82
221
|
} else {
|
|
83
|
-
logger.
|
|
222
|
+
logger.info('📁 Adding all changes to the index (git add -A)...');
|
|
84
223
|
await run('git add -A');
|
|
224
|
+
logger.info('✅ Successfully staged all changes');
|
|
85
225
|
}
|
|
86
226
|
}
|
|
87
227
|
// Determine cached state with single, clear logic
|
|
@@ -89,30 +229,71 @@ const executeInternal = async (runConfig)=>{
|
|
|
89
229
|
// Validate sendit state early - now returns boolean instead of throwing
|
|
90
230
|
validateSenditState(runConfig, cached, isDryRun, logger);
|
|
91
231
|
let diffContent = '';
|
|
232
|
+
var _runConfig_commit_maxDiffBytes;
|
|
233
|
+
const maxDiffBytes = (_runConfig_commit_maxDiffBytes = (_runConfig_commit1 = runConfig.commit) === null || _runConfig_commit1 === void 0 ? void 0 : _runConfig_commit1.maxDiffBytes) !== null && _runConfig_commit_maxDiffBytes !== void 0 ? _runConfig_commit_maxDiffBytes : DEFAULT_MAX_DIFF_BYTES;
|
|
92
234
|
var _runConfig_excludedPatterns;
|
|
93
235
|
const options = {
|
|
94
236
|
cached,
|
|
95
|
-
excludedPatterns: (_runConfig_excludedPatterns = runConfig.excludedPatterns) !== null && _runConfig_excludedPatterns !== void 0 ? _runConfig_excludedPatterns : DEFAULT_EXCLUDED_PATTERNS
|
|
237
|
+
excludedPatterns: (_runConfig_excludedPatterns = runConfig.excludedPatterns) !== null && _runConfig_excludedPatterns !== void 0 ? _runConfig_excludedPatterns : DEFAULT_EXCLUDED_PATTERNS,
|
|
238
|
+
maxDiffBytes
|
|
96
239
|
};
|
|
97
240
|
const diff = await create(options);
|
|
98
241
|
diffContent = await diff.get();
|
|
99
242
|
// Check if there are actually any changes in the diff
|
|
100
|
-
|
|
101
|
-
// If
|
|
102
|
-
if (!hasActualChanges && ((_runConfig_commit1 = runConfig.commit) === null || _runConfig_commit1 === void 0 ? void 0 : _runConfig_commit1.sendit) && !isDryRun) {
|
|
103
|
-
logger.warn('No changes detected to commit. Skipping commit operation.');
|
|
104
|
-
return 'No changes to commit.';
|
|
105
|
-
}
|
|
106
|
-
// If there are no changes but we're not in sendit mode, we might still want to generate a message
|
|
107
|
-
// This allows for dry-run scenarios or testing commit message generation
|
|
243
|
+
let hasActualChanges = diffContent.trim().length > 0;
|
|
244
|
+
// If no changes found with current patterns, check for critical excluded files
|
|
108
245
|
if (!hasActualChanges) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
logger.info('
|
|
113
|
-
|
|
246
|
+
const criticalChanges = await hasCriticalExcludedChanges();
|
|
247
|
+
if (criticalChanges.hasChanges) {
|
|
248
|
+
var _runConfig_commit10;
|
|
249
|
+
logger.info('No changes found with current exclusion patterns, but detected changes to critical files: %s', criticalChanges.files.join(', '));
|
|
250
|
+
if (((_runConfig_commit10 = runConfig.commit) === null || _runConfig_commit10 === void 0 ? void 0 : _runConfig_commit10.sendit) && !isDryRun) {
|
|
251
|
+
// In sendit mode, automatically include critical files
|
|
252
|
+
logger.info('SendIt mode: Including critical files in diff...');
|
|
253
|
+
var _runConfig_excludedPatterns1;
|
|
254
|
+
const minimalPatterns = getMinimalExcludedPatterns((_runConfig_excludedPatterns1 = runConfig.excludedPatterns) !== null && _runConfig_excludedPatterns1 !== void 0 ? _runConfig_excludedPatterns1 : DEFAULT_EXCLUDED_PATTERNS);
|
|
255
|
+
const updatedOptions = {
|
|
256
|
+
...options,
|
|
257
|
+
excludedPatterns: minimalPatterns
|
|
258
|
+
};
|
|
259
|
+
const updatedDiff = await create(updatedOptions);
|
|
260
|
+
diffContent = await updatedDiff.get();
|
|
261
|
+
if (diffContent.trim().length > 0) {
|
|
262
|
+
logger.info('Successfully included critical files in diff.');
|
|
263
|
+
// Update hasActualChanges since we now have content after including critical files
|
|
264
|
+
hasActualChanges = true;
|
|
265
|
+
} else {
|
|
266
|
+
logger.warn('No changes detected even after including critical files.');
|
|
267
|
+
return 'No changes to commit.';
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
// In non-sendit mode, suggest including the files
|
|
271
|
+
logger.warn('Consider including these files by using:');
|
|
272
|
+
var _runConfig_excludedPatterns2;
|
|
273
|
+
logger.warn(' kodrdriv commit --excluded-paths %s', ((_runConfig_excludedPatterns2 = runConfig.excludedPatterns) !== null && _runConfig_excludedPatterns2 !== void 0 ? _runConfig_excludedPatterns2 : DEFAULT_EXCLUDED_PATTERNS).filter((p)=>!criticalChanges.files.some((f)=>p.includes(f.split('/').pop() || ''))).map((p)=>`"${p}"`).join(' '));
|
|
274
|
+
logger.warn('Or run with --sendit to automatically include critical files.');
|
|
275
|
+
if (!isDryRun) {
|
|
276
|
+
return 'No changes to commit. Use suggestions above to include critical files.';
|
|
277
|
+
} else {
|
|
278
|
+
logger.info('Generating commit message template for future use...');
|
|
279
|
+
}
|
|
280
|
+
}
|
|
114
281
|
} else {
|
|
115
|
-
|
|
282
|
+
var _runConfig_commit11;
|
|
283
|
+
// No changes at all
|
|
284
|
+
if (((_runConfig_commit11 = runConfig.commit) === null || _runConfig_commit11 === void 0 ? void 0 : _runConfig_commit11.sendit) && !isDryRun) {
|
|
285
|
+
logger.warn('No changes detected to commit. Skipping commit operation.');
|
|
286
|
+
return 'No changes to commit.';
|
|
287
|
+
} else {
|
|
288
|
+
var _runConfig_commit12;
|
|
289
|
+
logger.info('No changes detected in the working directory.');
|
|
290
|
+
if ((_runConfig_commit12 = runConfig.commit) === null || _runConfig_commit12 === void 0 ? void 0 : _runConfig_commit12.sendit) {
|
|
291
|
+
logger.info('Skipping commit operation due to no changes.');
|
|
292
|
+
return 'No changes to commit.';
|
|
293
|
+
} else {
|
|
294
|
+
logger.info('Generating commit message template for future use...');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
116
297
|
}
|
|
117
298
|
}
|
|
118
299
|
const logOptions = {
|
|
@@ -134,28 +315,56 @@ const executeInternal = async (runConfig)=>{
|
|
|
134
315
|
directories: runConfig.contextDirectories
|
|
135
316
|
};
|
|
136
317
|
const prompt = await createPrompt(promptConfig, promptContent, promptContext);
|
|
318
|
+
// Get the appropriate model for the commit command
|
|
319
|
+
const modelToUse = getModelForCommand(runConfig, 'commit');
|
|
137
320
|
// Use consistent model for debug (fix hardcoded model)
|
|
138
321
|
if (runConfig.debug) {
|
|
139
322
|
const formattedPrompt = Formatter.create({
|
|
140
323
|
logger
|
|
141
|
-
}).formatPrompt(
|
|
324
|
+
}).formatPrompt(modelToUse, prompt);
|
|
142
325
|
logger.silly('Formatted Prompt: %s', stringifyJSON(formattedPrompt));
|
|
143
326
|
}
|
|
144
327
|
const request = Formatter.create({
|
|
145
328
|
logger
|
|
146
|
-
}).formatPrompt(
|
|
329
|
+
}).formatPrompt(modelToUse, prompt);
|
|
147
330
|
// Always ensure output directory exists for request/response files
|
|
148
331
|
const outputDirectory = runConfig.outputDirectory || DEFAULT_OUTPUT_DIRECTORY;
|
|
149
332
|
const storage = create$2({
|
|
150
333
|
log: logger.info
|
|
151
334
|
});
|
|
152
335
|
await storage.ensureDirectory(outputDirectory);
|
|
153
|
-
|
|
154
|
-
|
|
336
|
+
// Create retry callback that reduces diff size on token limit errors
|
|
337
|
+
const createRetryCallback = (originalDiffContent)=>async (attempt)=>{
|
|
338
|
+
var _runConfig_commit, _runConfig_commit1;
|
|
339
|
+
logger.info('Retrying with reduced diff size (attempt %d)', attempt);
|
|
340
|
+
// Progressively reduce the diff size on retries
|
|
341
|
+
const reductionFactor = Math.pow(0.5, attempt - 1); // 50% reduction per retry
|
|
342
|
+
const reducedMaxDiffBytes = Math.max(512, Math.floor(maxDiffBytes * reductionFactor));
|
|
343
|
+
logger.debug('Reducing maxDiffBytes from %d to %d for retry', maxDiffBytes, reducedMaxDiffBytes);
|
|
344
|
+
// Re-truncate the diff with smaller limits
|
|
345
|
+
const reducedDiffContent = originalDiffContent.length > reducedMaxDiffBytes ? truncateDiffByFiles(originalDiffContent, reducedMaxDiffBytes) : originalDiffContent;
|
|
346
|
+
// Rebuild the prompt with the reduced diff
|
|
347
|
+
const reducedPromptContent = {
|
|
348
|
+
diffContent: reducedDiffContent,
|
|
349
|
+
userDirection: (_runConfig_commit = runConfig.commit) === null || _runConfig_commit === void 0 ? void 0 : _runConfig_commit.direction
|
|
350
|
+
};
|
|
351
|
+
const reducedPromptContext = {
|
|
352
|
+
logContext,
|
|
353
|
+
context: (_runConfig_commit1 = runConfig.commit) === null || _runConfig_commit1 === void 0 ? void 0 : _runConfig_commit1.context,
|
|
354
|
+
directories: runConfig.contextDirectories
|
|
355
|
+
};
|
|
356
|
+
const retryPrompt = await createPrompt(promptConfig, reducedPromptContent, reducedPromptContext);
|
|
357
|
+
const retryRequest = Formatter.create({
|
|
358
|
+
logger
|
|
359
|
+
}).formatPrompt(modelToUse, retryPrompt);
|
|
360
|
+
return retryRequest.messages;
|
|
361
|
+
};
|
|
362
|
+
const summary = await createCompletionWithRetry(request.messages, {
|
|
363
|
+
model: modelToUse,
|
|
155
364
|
debug: runConfig.debug,
|
|
156
365
|
debugRequestFile: getOutputPath(runConfig.outputDirectory || DEFAULT_OUTPUT_DIRECTORY, getTimestampedRequestFilename('commit')),
|
|
157
366
|
debugResponseFile: getOutputPath(runConfig.outputDirectory || DEFAULT_OUTPUT_DIRECTORY, getTimestampedResponseFilename('commit'))
|
|
158
|
-
});
|
|
367
|
+
}, createRetryCallback(diffContent));
|
|
159
368
|
// Save timestamped copy of commit message with better error handling
|
|
160
369
|
await saveCommitMessage(outputDirectory, summary, storage, logger);
|
|
161
370
|
// 🛡️ Universal Safety Check: Run before ANY commit operation
|
|
@@ -166,7 +375,7 @@ const executeInternal = async (runConfig)=>{
|
|
|
166
375
|
try {
|
|
167
376
|
const fileDependencyIssues = await checkForFileDependencies(storage, process.cwd());
|
|
168
377
|
if (fileDependencyIssues.length > 0) {
|
|
169
|
-
var
|
|
378
|
+
var _runConfig_commit13;
|
|
170
379
|
logger.error('🚫 COMMIT BLOCKED: Found file: dependencies that should not be committed!');
|
|
171
380
|
logger.error('');
|
|
172
381
|
logFileDependencyWarning(fileDependencyIssues, 'commit');
|
|
@@ -174,7 +383,7 @@ const executeInternal = async (runConfig)=>{
|
|
|
174
383
|
logger.error('Generated commit message was:');
|
|
175
384
|
logger.error('%s', summary);
|
|
176
385
|
logger.error('');
|
|
177
|
-
if ((
|
|
386
|
+
if ((_runConfig_commit13 = runConfig.commit) === null || _runConfig_commit13 === void 0 ? void 0 : _runConfig_commit13.sendit) {
|
|
178
387
|
logger.error('To bypass this check, use: kodrdriv commit --skip-file-check --sendit');
|
|
179
388
|
} else {
|
|
180
389
|
logger.error('To bypass this check, add skipFileCheck: true to your commit configuration');
|
|
@@ -189,18 +398,73 @@ const executeInternal = async (runConfig)=>{
|
|
|
189
398
|
} else if (((_runConfig_commit7 = runConfig.commit) === null || _runConfig_commit7 === void 0 ? void 0 : _runConfig_commit7.skipFileCheck) && willCreateCommit) {
|
|
190
399
|
logger.warn('⚠️ Skipping file: dependency check as requested');
|
|
191
400
|
}
|
|
192
|
-
|
|
401
|
+
// Handle interactive mode
|
|
402
|
+
if (((_runConfig_commit8 = runConfig.commit) === null || _runConfig_commit8 === void 0 ? void 0 : _runConfig_commit8.interactive) && !isDryRun) {
|
|
403
|
+
var _runConfig_commit14;
|
|
404
|
+
requireTTY('Interactive mode requires a terminal. Use --sendit or --dry-run instead.');
|
|
405
|
+
const interactiveResult = await handleInteractiveCommitFeedback(summary, runConfig, promptConfig, promptContext, outputDirectory, storage, diffContent, hasActualChanges, cached);
|
|
406
|
+
if (interactiveResult.action === 'skip') {
|
|
407
|
+
logger.info('❌ Commit aborted by user');
|
|
408
|
+
logger.info('💡 No commit will be performed');
|
|
409
|
+
userSkippedCommit = true;
|
|
410
|
+
return interactiveResult.finalMessage;
|
|
411
|
+
}
|
|
412
|
+
// User chose to commit - check if sendit is enabled to determine what action to take
|
|
413
|
+
const senditEnabled = (_runConfig_commit14 = runConfig.commit) === null || _runConfig_commit14 === void 0 ? void 0 : _runConfig_commit14.sendit;
|
|
414
|
+
const willActuallyCommit = senditEnabled && hasActualChanges && cached;
|
|
415
|
+
if (willActuallyCommit) {
|
|
416
|
+
var _runConfig_commit15;
|
|
417
|
+
const commitAction = ((_runConfig_commit15 = runConfig.commit) === null || _runConfig_commit15 === void 0 ? void 0 : _runConfig_commit15.amend) ? 'amending last commit' : 'committing';
|
|
418
|
+
logger.info('🚀 SendIt enabled: %s with final message: \n\n%s\n\n', commitAction.charAt(0).toUpperCase() + commitAction.slice(1), interactiveResult.finalMessage);
|
|
419
|
+
try {
|
|
420
|
+
var _runConfig_commit16;
|
|
421
|
+
const validatedSummary = validateString(interactiveResult.finalMessage, 'commit summary');
|
|
422
|
+
const escapedSummary = shellescape([
|
|
423
|
+
validatedSummary
|
|
424
|
+
]);
|
|
425
|
+
const commitCommand = ((_runConfig_commit16 = runConfig.commit) === null || _runConfig_commit16 === void 0 ? void 0 : _runConfig_commit16.amend) ? `git commit --amend -m ${escapedSummary}` : `git commit -m ${escapedSummary}`;
|
|
426
|
+
await run(commitCommand);
|
|
427
|
+
logger.info('✅ Commit successful!');
|
|
428
|
+
} catch (error) {
|
|
429
|
+
logger.error('Failed to commit:', error);
|
|
430
|
+
throw new ExternalDependencyError('Failed to create commit', 'git', error);
|
|
431
|
+
}
|
|
432
|
+
} else if (senditEnabled && (!hasActualChanges || !cached)) {
|
|
433
|
+
logger.info('📝 SendIt enabled but no staged changes available. Final message saved: \n\n%s\n\n', interactiveResult.finalMessage);
|
|
434
|
+
if (!hasActualChanges) {
|
|
435
|
+
logger.info('💡 No changes detected to commit');
|
|
436
|
+
} else if (!cached) {
|
|
437
|
+
logger.info('💡 No staged changes found. Use "git add" to stage changes or configure add: true in commit settings');
|
|
438
|
+
}
|
|
439
|
+
} else {
|
|
440
|
+
logger.info('📝 Message accepted (SendIt not enabled). Use this commit message manually: \n\n%s\n\n', interactiveResult.finalMessage);
|
|
441
|
+
logger.info('💡 To automatically commit, add sendit: true to your commit configuration');
|
|
442
|
+
}
|
|
443
|
+
return interactiveResult.finalMessage;
|
|
444
|
+
}
|
|
445
|
+
// Safety check: Never commit if user explicitly skipped in interactive mode
|
|
446
|
+
if (userSkippedCommit) {
|
|
447
|
+
logger.debug('Skipping sendit logic because user chose to skip in interactive mode');
|
|
448
|
+
return summary;
|
|
449
|
+
}
|
|
450
|
+
if ((_runConfig_commit9 = runConfig.commit) === null || _runConfig_commit9 === void 0 ? void 0 : _runConfig_commit9.sendit) {
|
|
193
451
|
if (isDryRun) {
|
|
452
|
+
var _runConfig_commit17;
|
|
194
453
|
logger.info('Would commit with message: \n\n%s\n\n', summary);
|
|
195
|
-
|
|
454
|
+
const commitAction = ((_runConfig_commit17 = runConfig.commit) === null || _runConfig_commit17 === void 0 ? void 0 : _runConfig_commit17.amend) ? 'git commit --amend -m <generated-message>' : 'git commit -m <generated-message>';
|
|
455
|
+
logger.info('Would execute: %s', commitAction);
|
|
196
456
|
} else if (hasActualChanges && cached) {
|
|
197
|
-
|
|
457
|
+
var _runConfig_commit18;
|
|
458
|
+
const commitAction = ((_runConfig_commit18 = runConfig.commit) === null || _runConfig_commit18 === void 0 ? void 0 : _runConfig_commit18.amend) ? 'amending commit' : 'committing';
|
|
459
|
+
logger.info('SendIt mode enabled. %s with message: \n\n%s\n\n', commitAction.charAt(0).toUpperCase() + commitAction.slice(1), summary);
|
|
198
460
|
try {
|
|
461
|
+
var _runConfig_commit19;
|
|
199
462
|
const validatedSummary = validateString(summary, 'commit summary');
|
|
200
463
|
const escapedSummary = shellescape([
|
|
201
464
|
validatedSummary
|
|
202
465
|
]);
|
|
203
|
-
|
|
466
|
+
const commitCommand = ((_runConfig_commit19 = runConfig.commit) === null || _runConfig_commit19 === void 0 ? void 0 : _runConfig_commit19.amend) ? `git commit --amend -m ${escapedSummary}` : `git commit -m ${escapedSummary}`;
|
|
467
|
+
await run(commitCommand);
|
|
204
468
|
logger.info('Commit successful!');
|
|
205
469
|
} catch (error) {
|
|
206
470
|
logger.error('Failed to commit:', error);
|
|
@@ -211,6 +475,9 @@ const executeInternal = async (runConfig)=>{
|
|
|
211
475
|
}
|
|
212
476
|
} else if (isDryRun) {
|
|
213
477
|
logger.info('Generated commit message: \n\n%s\n\n', summary);
|
|
478
|
+
} else {
|
|
479
|
+
// Default behavior when neither --interactive nor --sendit is specified
|
|
480
|
+
logger.info('Generated commit message: \n\n%s\n\n', summary);
|
|
214
481
|
}
|
|
215
482
|
return summary;
|
|
216
483
|
};
|
|
@@ -226,12 +493,10 @@ const execute = async (runConfig)=>{
|
|
|
226
493
|
if (error.cause) {
|
|
227
494
|
standardLogger.debug(`Caused by: ${error.cause.message}`);
|
|
228
495
|
}
|
|
229
|
-
process.exit(1);
|
|
230
496
|
throw error;
|
|
231
497
|
}
|
|
232
498
|
// Unexpected errors
|
|
233
499
|
standardLogger.error(`commit encountered unexpected error: ${error.message}`);
|
|
234
|
-
process.exit(1);
|
|
235
500
|
throw error;
|
|
236
501
|
}
|
|
237
502
|
};
|