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