@eldrforge/kodrdriv 1.2.20 → 1.2.22
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/WORKFLOW-PRECHECK-IMPLEMENTATION.md +239 -0
- package/WORKFLOW-SKIP-SUMMARY.md +121 -0
- package/dist/application.js +6 -2
- package/dist/application.js.map +1 -1
- package/dist/arguments.js +2 -2
- package/dist/arguments.js.map +1 -1
- package/dist/commands/audio-commit.js +15 -6
- package/dist/commands/audio-commit.js.map +1 -1
- package/dist/commands/audio-review.js +31 -15
- package/dist/commands/audio-review.js.map +1 -1
- package/dist/commands/commit.js +31 -20
- package/dist/commands/commit.js.map +1 -1
- package/dist/commands/link.js +27 -27
- package/dist/commands/link.js.map +1 -1
- package/dist/commands/publish.js +87 -34
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/release.js +32 -19
- package/dist/commands/release.js.map +1 -1
- package/dist/commands/review.js +36 -30
- 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 +154 -38
- package/dist/commands/tree.js.map +1 -1
- package/dist/commands/unlink.js +13 -13
- package/dist/commands/unlink.js.map +1 -1
- package/dist/commands/updates.js +21 -0
- package/dist/commands/updates.js.map +1 -1
- package/dist/commands/versions.js +5 -5
- package/dist/commands/versions.js.map +1 -1
- package/dist/constants.js +4 -4
- package/dist/constants.js.map +1 -1
- package/dist/content/files.js +4 -4
- package/dist/content/files.js.map +1 -1
- package/dist/error/CommandErrors.js +1 -65
- package/dist/error/CommandErrors.js.map +1 -1
- package/dist/logging.js +3 -3
- package/dist/logging.js.map +1 -1
- package/dist/util/aiAdapter.js +28 -0
- package/dist/util/aiAdapter.js.map +1 -0
- package/dist/util/general.js +5 -5
- package/dist/util/general.js.map +1 -1
- package/dist/util/interactive.js +6 -437
- package/dist/util/interactive.js.map +1 -1
- package/dist/util/loggerAdapter.js +24 -0
- package/dist/util/loggerAdapter.js.map +1 -0
- package/dist/util/performance.js +4 -4
- 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/dist/util/storageAdapter.js +25 -0
- package/dist/util/storageAdapter.js.map +1 -0
- package/package.json +6 -4
- package/test_output.txt +3 -3
- package/INTEGRATION-SUMMARY.md +0 -232
- package/TEST-STATUS.md +0 -168
- package/dist/content/issues.js +0 -331
- package/dist/content/issues.js.map +0 -1
- package/dist/content/releaseNotes.js +0 -90
- package/dist/content/releaseNotes.js.map +0 -1
- package/dist/prompt/commit.js +0 -76
- package/dist/prompt/commit.js.map +0 -1
- package/dist/prompt/instructions/commit.md +0 -133
- package/dist/prompt/instructions/release.md +0 -188
- package/dist/prompt/instructions/review.md +0 -169
- package/dist/prompt/personas/releaser.md +0 -24
- package/dist/prompt/personas/you.md +0 -55
- package/dist/prompt/release.js +0 -100
- package/dist/prompt/release.js.map +0 -1
- package/dist/prompt/review.js +0 -64
- package/dist/prompt/review.js.map +0 -1
- package/dist/util/github.js +0 -1071
- package/dist/util/github.js.map +0 -1
- package/dist/util/openai.js +0 -365
- package/dist/util/openai.js.map +0 -1
package/dist/content/issues.js
DELETED
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
import { getLogger } from '../logging.js';
|
|
2
|
-
import { getUserChoice as getUserChoice$1 } from '../util/interactive.js';
|
|
3
|
-
import { createIssue, getOpenIssues } from '../util/github.js';
|
|
4
|
-
import path__default from 'path';
|
|
5
|
-
import os__default from 'os';
|
|
6
|
-
import { spawnSync } from 'child_process';
|
|
7
|
-
import fs__default from 'fs/promises';
|
|
8
|
-
|
|
9
|
-
// Get GitHub issues content
|
|
10
|
-
const get = async (options = {})=>{
|
|
11
|
-
const logger = getLogger();
|
|
12
|
-
const { limit = 20 } = options;
|
|
13
|
-
try {
|
|
14
|
-
logger.debug('Fetching open GitHub issues...');
|
|
15
|
-
const issuesLimit = Math.min(limit, 20); // Cap at 20
|
|
16
|
-
const githubIssues = await getOpenIssues(issuesLimit);
|
|
17
|
-
if (githubIssues.trim()) {
|
|
18
|
-
logger.debug('Added GitHub issues to context (%d characters)', githubIssues.length);
|
|
19
|
-
return githubIssues;
|
|
20
|
-
} else {
|
|
21
|
-
logger.debug('No open GitHub issues found');
|
|
22
|
-
return '';
|
|
23
|
-
}
|
|
24
|
-
} catch (error) {
|
|
25
|
-
logger.warn('Failed to fetch GitHub issues: %s', error.message);
|
|
26
|
-
return '';
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
// Helper function to get user choice interactively
|
|
30
|
-
async function getUserChoice(prompt, choices) {
|
|
31
|
-
return await getUserChoice$1(prompt, choices);
|
|
32
|
-
}
|
|
33
|
-
// Helper function to serialize issue to structured text format
|
|
34
|
-
function serializeIssue(issue) {
|
|
35
|
-
const lines = [
|
|
36
|
-
'# Issue Editor',
|
|
37
|
-
'',
|
|
38
|
-
'# Edit the issue details below. Lines starting with "#" are comments and will be ignored.',
|
|
39
|
-
'# Valid priorities: low, medium, high',
|
|
40
|
-
'# Valid categories: ui, content, functionality, accessibility, performance, other',
|
|
41
|
-
'# Suggestions should be one per line, preceded by a "-" or "•"',
|
|
42
|
-
'',
|
|
43
|
-
`Title: ${issue.title}`,
|
|
44
|
-
'',
|
|
45
|
-
`Priority: ${issue.priority}`,
|
|
46
|
-
'',
|
|
47
|
-
`Category: ${issue.category}`,
|
|
48
|
-
'',
|
|
49
|
-
'Description:',
|
|
50
|
-
issue.description,
|
|
51
|
-
'',
|
|
52
|
-
'Suggestions:'
|
|
53
|
-
];
|
|
54
|
-
if (issue.suggestions && issue.suggestions.length > 0) {
|
|
55
|
-
issue.suggestions.forEach((suggestion)=>{
|
|
56
|
-
lines.push(`- ${suggestion}`);
|
|
57
|
-
});
|
|
58
|
-
} else {
|
|
59
|
-
lines.push('# Add suggestions here, one per line with "-" or "•"');
|
|
60
|
-
}
|
|
61
|
-
return lines.join('\n');
|
|
62
|
-
}
|
|
63
|
-
// Helper function to deserialize issue from structured text format
|
|
64
|
-
function deserializeIssue(content) {
|
|
65
|
-
const lines = content.split('\n');
|
|
66
|
-
// Parse the structured format
|
|
67
|
-
let title = '';
|
|
68
|
-
let priority = 'medium';
|
|
69
|
-
let category = 'other';
|
|
70
|
-
let description = '';
|
|
71
|
-
const suggestions = [];
|
|
72
|
-
let currentSection = '';
|
|
73
|
-
let descriptionLines = [];
|
|
74
|
-
for(let i = 0; i < lines.length; i++){
|
|
75
|
-
const line = lines[i].trim();
|
|
76
|
-
// Skip comment lines
|
|
77
|
-
if (line.startsWith('#')) {
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
// Parse field lines
|
|
81
|
-
if (line.startsWith('Title:')) {
|
|
82
|
-
title = line.substring(6).trim();
|
|
83
|
-
} else if (line.startsWith('Priority:')) {
|
|
84
|
-
const priorityValue = line.substring(9).trim().toLowerCase();
|
|
85
|
-
if (priorityValue === 'low' || priorityValue === 'medium' || priorityValue === 'high') {
|
|
86
|
-
priority = priorityValue;
|
|
87
|
-
}
|
|
88
|
-
} else if (line.startsWith('Category:')) {
|
|
89
|
-
const categoryValue = line.substring(9).trim().toLowerCase();
|
|
90
|
-
if ([
|
|
91
|
-
'ui',
|
|
92
|
-
'content',
|
|
93
|
-
'functionality',
|
|
94
|
-
'accessibility',
|
|
95
|
-
'performance',
|
|
96
|
-
'other'
|
|
97
|
-
].includes(categoryValue)) {
|
|
98
|
-
category = categoryValue;
|
|
99
|
-
}
|
|
100
|
-
} else if (line === 'Description:') {
|
|
101
|
-
currentSection = 'description';
|
|
102
|
-
descriptionLines = [];
|
|
103
|
-
} else if (line === 'Suggestions:') {
|
|
104
|
-
currentSection = 'suggestions';
|
|
105
|
-
// Process accumulated description lines
|
|
106
|
-
description = descriptionLines.join('\n').trim();
|
|
107
|
-
} else if (currentSection === 'description' && line !== '') {
|
|
108
|
-
descriptionLines.push(lines[i]); // Keep original line with spacing
|
|
109
|
-
} else if (currentSection === 'suggestions' && line !== '') {
|
|
110
|
-
// Parse suggestion line
|
|
111
|
-
const suggestionLine = line.replace(/^[-•]\s*/, '').trim();
|
|
112
|
-
if (suggestionLine) {
|
|
113
|
-
suggestions.push(suggestionLine);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
// If we didn't encounter suggestions section, description might still be accumulating
|
|
118
|
-
if (currentSection === 'description') {
|
|
119
|
-
description = descriptionLines.join('\n').trim();
|
|
120
|
-
}
|
|
121
|
-
return {
|
|
122
|
-
title: title || 'Untitled Issue',
|
|
123
|
-
priority,
|
|
124
|
-
category,
|
|
125
|
-
description: description || 'No description provided',
|
|
126
|
-
suggestions: suggestions.length > 0 ? suggestions : undefined
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
// Helper function to edit issue using editor
|
|
130
|
-
async function editIssueInteractively(issue) {
|
|
131
|
-
const logger = getLogger();
|
|
132
|
-
const editor = process.env.EDITOR || process.env.VISUAL || 'vi';
|
|
133
|
-
// Create a temporary file for the user to edit
|
|
134
|
-
const tmpDir = os__default.tmpdir();
|
|
135
|
-
const tmpFilePath = path__default.join(tmpDir, `kodrdriv_issue_${Date.now()}.txt`);
|
|
136
|
-
// Serialize the issue to structured text format
|
|
137
|
-
const issueContent = serializeIssue(issue);
|
|
138
|
-
await fs__default.writeFile(tmpFilePath, issueContent, 'utf8');
|
|
139
|
-
logger.info(`📝 Opening ${editor} to edit issue...`);
|
|
140
|
-
// Open the editor synchronously so execution resumes after the user closes it
|
|
141
|
-
const result = spawnSync(editor, [
|
|
142
|
-
tmpFilePath
|
|
143
|
-
], {
|
|
144
|
-
stdio: 'inherit'
|
|
145
|
-
});
|
|
146
|
-
if (result.error) {
|
|
147
|
-
throw new Error(`Failed to launch editor '${editor}': ${result.error.message}`);
|
|
148
|
-
}
|
|
149
|
-
// Read the file back and deserialize it
|
|
150
|
-
const editedContent = await fs__default.readFile(tmpFilePath, 'utf8');
|
|
151
|
-
// Clean up the temporary file with proper error handling
|
|
152
|
-
try {
|
|
153
|
-
await fs__default.unlink(tmpFilePath);
|
|
154
|
-
} catch (error) {
|
|
155
|
-
// Only log if it's not a "file not found" error
|
|
156
|
-
if (error.code !== 'ENOENT') {
|
|
157
|
-
logger.warn(`Failed to cleanup temporary file ${tmpFilePath}: ${error.message}`);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
// Deserialize the edited content back to an Issue object
|
|
161
|
-
const editedIssue = deserializeIssue(editedContent);
|
|
162
|
-
logger.info('✅ Issue updated successfully');
|
|
163
|
-
logger.debug('Updated issue: %s', JSON.stringify(editedIssue, null, 2));
|
|
164
|
-
return editedIssue;
|
|
165
|
-
}
|
|
166
|
-
// Helper function to format issue body for GitHub
|
|
167
|
-
function formatIssueBody(issue) {
|
|
168
|
-
let body = `## Description\n\n${issue.description}\n\n`;
|
|
169
|
-
body += `## Details\n\n`;
|
|
170
|
-
body += `- **Priority:** ${issue.priority}\n`;
|
|
171
|
-
body += `- **Category:** ${issue.category}\n`;
|
|
172
|
-
body += `- **Source:** Review\n\n`;
|
|
173
|
-
if (issue.suggestions && issue.suggestions.length > 0) {
|
|
174
|
-
body += `## Suggestions\n\n`;
|
|
175
|
-
issue.suggestions.forEach((suggestion)=>{
|
|
176
|
-
body += `- ${suggestion}\n`;
|
|
177
|
-
});
|
|
178
|
-
body += '\n';
|
|
179
|
-
}
|
|
180
|
-
body += `---\n\n`;
|
|
181
|
-
body += `*This issue was automatically created from a review session.*`;
|
|
182
|
-
return body;
|
|
183
|
-
}
|
|
184
|
-
// Helper function to format results with created GitHub issues
|
|
185
|
-
function formatReviewResultsWithIssues(result, createdIssues) {
|
|
186
|
-
let output = `📝 Review Results\n\n`;
|
|
187
|
-
output += `📋 Summary: ${result.summary}\n`;
|
|
188
|
-
output += `📊 Total Issues Found: ${result.totalIssues}\n`;
|
|
189
|
-
output += `🚀 GitHub Issues Created: ${createdIssues.length}\n\n`;
|
|
190
|
-
if (result.issues && result.issues.length > 0) {
|
|
191
|
-
output += `📝 Issues Identified:\n\n`;
|
|
192
|
-
result.issues.forEach((issue, index)=>{
|
|
193
|
-
const priorityEmoji = issue.priority === 'high' ? '🔴' : issue.priority === 'medium' ? '🟡' : '🟢';
|
|
194
|
-
const categoryEmoji = issue.category === 'ui' ? '🎨' : issue.category === 'content' ? '📝' : issue.category === 'functionality' ? '⚙️' : issue.category === 'accessibility' ? '♿' : issue.category === 'performance' ? '⚡' : '🔧';
|
|
195
|
-
output += `${index + 1}. ${priorityEmoji} ${issue.title}\n`;
|
|
196
|
-
output += ` ${categoryEmoji} Category: ${issue.category} | Priority: ${issue.priority}\n`;
|
|
197
|
-
output += ` 📖 Description: ${issue.description}\n`;
|
|
198
|
-
// Check if this issue was created as a GitHub issue
|
|
199
|
-
const createdIssue = createdIssues.find((ci)=>ci.issue === issue);
|
|
200
|
-
if (createdIssue) {
|
|
201
|
-
output += ` 🔗 GitHub Issue: #${createdIssue.number} - ${createdIssue.githubUrl}\n`;
|
|
202
|
-
}
|
|
203
|
-
if (issue.suggestions && issue.suggestions.length > 0) {
|
|
204
|
-
output += ` 💡 Suggestions:\n`;
|
|
205
|
-
issue.suggestions.forEach((suggestion)=>{
|
|
206
|
-
output += ` • ${suggestion}\n`;
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
output += `\n`;
|
|
210
|
-
});
|
|
211
|
-
} else {
|
|
212
|
-
output += `✅ No specific issues identified from the review.\n\n`;
|
|
213
|
-
}
|
|
214
|
-
if (createdIssues.length > 0) {
|
|
215
|
-
output += `\n🎯 Created GitHub Issues:\n`;
|
|
216
|
-
createdIssues.forEach((createdIssue)=>{
|
|
217
|
-
output += `• #${createdIssue.number}: ${createdIssue.issue.title} - ${createdIssue.githubUrl}\n`;
|
|
218
|
-
});
|
|
219
|
-
output += `\n`;
|
|
220
|
-
}
|
|
221
|
-
output += `🚀 Next Steps: Review the created GitHub issues and prioritize them in your development workflow.`;
|
|
222
|
-
return output;
|
|
223
|
-
}
|
|
224
|
-
function formatReviewResults(result) {
|
|
225
|
-
let output = `📝 Review Results\n\n`;
|
|
226
|
-
output += `📋 Summary: ${result.summary}\n`;
|
|
227
|
-
output += `📊 Total Issues Found: ${result.totalIssues}\n\n`;
|
|
228
|
-
if (result.issues && result.issues.length > 0) {
|
|
229
|
-
output += `📝 Issues Identified:\n\n`;
|
|
230
|
-
result.issues.forEach((issue, index)=>{
|
|
231
|
-
const priorityEmoji = issue.priority === 'high' ? '🔴' : issue.priority === 'medium' ? '🟡' : '🟢';
|
|
232
|
-
const categoryEmoji = issue.category === 'ui' ? '🎨' : issue.category === 'content' ? '📝' : issue.category === 'functionality' ? '⚙️' : issue.category === 'accessibility' ? '♿' : issue.category === 'performance' ? '⚡' : '🔧';
|
|
233
|
-
output += `${index + 1}. ${priorityEmoji} ${issue.title}\n`;
|
|
234
|
-
output += ` ${categoryEmoji} Category: ${issue.category} | Priority: ${issue.priority}\n`;
|
|
235
|
-
output += ` 📖 Description: ${issue.description}\n`;
|
|
236
|
-
if (issue.suggestions && issue.suggestions.length > 0) {
|
|
237
|
-
output += ` 💡 Suggestions:\n`;
|
|
238
|
-
issue.suggestions.forEach((suggestion)=>{
|
|
239
|
-
output += ` • ${suggestion}\n`;
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
output += `\n`;
|
|
243
|
-
});
|
|
244
|
-
} else {
|
|
245
|
-
output += `✅ No specific issues identified from the review.\n\n`;
|
|
246
|
-
}
|
|
247
|
-
output += `🚀 Next Steps: Review the identified issues and prioritize them for your development workflow.`;
|
|
248
|
-
return output;
|
|
249
|
-
}
|
|
250
|
-
// Handle GitHub issue creation workflow
|
|
251
|
-
const handleIssueCreation = async (result, senditMode = false)=>{
|
|
252
|
-
const logger = getLogger();
|
|
253
|
-
const createdIssues = [];
|
|
254
|
-
if (!result.issues || result.issues.length === 0) {
|
|
255
|
-
return formatReviewResults(result);
|
|
256
|
-
}
|
|
257
|
-
logger.info(`🔍 Found ${result.issues.length} issues to potentially create as GitHub issues`);
|
|
258
|
-
for(let i = 0; i < result.issues.length; i++){
|
|
259
|
-
let issue = result.issues[i];
|
|
260
|
-
let shouldCreateIssue = senditMode;
|
|
261
|
-
if (!senditMode) {
|
|
262
|
-
// Interactive confirmation for each issue - keep looping until user decides
|
|
263
|
-
let userChoice = '';
|
|
264
|
-
while(userChoice !== 'c' && userChoice !== 's'){
|
|
265
|
-
// Display issue details
|
|
266
|
-
logger.info(`\n📋 Issue ${i + 1} of ${result.issues.length}:`);
|
|
267
|
-
logger.info(` Title: ${issue.title}`);
|
|
268
|
-
logger.info(` Priority: ${issue.priority} | Category: ${issue.category}`);
|
|
269
|
-
logger.info(` Description: ${issue.description}`);
|
|
270
|
-
if (issue.suggestions && issue.suggestions.length > 0) {
|
|
271
|
-
logger.info(` Suggestions: ${issue.suggestions.join(', ')}`);
|
|
272
|
-
}
|
|
273
|
-
// Get user choice
|
|
274
|
-
userChoice = await getUserChoice('\nWhat would you like to do with this issue?', [
|
|
275
|
-
{
|
|
276
|
-
key: 'c',
|
|
277
|
-
label: 'Create GitHub issue'
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
key: 's',
|
|
281
|
-
label: 'Skip this issue'
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
key: 'e',
|
|
285
|
-
label: 'Edit issue details'
|
|
286
|
-
}
|
|
287
|
-
]);
|
|
288
|
-
if (userChoice === 'c') {
|
|
289
|
-
shouldCreateIssue = true;
|
|
290
|
-
} else if (userChoice === 'e') {
|
|
291
|
-
// Allow user to edit the issue
|
|
292
|
-
issue = await editIssueInteractively(issue);
|
|
293
|
-
result.issues[i] = issue; // Update the issue in the result
|
|
294
|
-
// Continue the loop to show the updated issue and ask again
|
|
295
|
-
}
|
|
296
|
-
// If choice is 's', loop will exit and shouldCreateIssue remains false
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
if (shouldCreateIssue) {
|
|
300
|
-
try {
|
|
301
|
-
logger.info(`🚀 Creating GitHub issue: "${issue.title}"`);
|
|
302
|
-
// Format issue body with additional details
|
|
303
|
-
const issueBody = formatIssueBody(issue);
|
|
304
|
-
// Create labels based on priority and category
|
|
305
|
-
const labels = [
|
|
306
|
-
`priority-${issue.priority}`,
|
|
307
|
-
`category-${issue.category}`,
|
|
308
|
-
'review'
|
|
309
|
-
];
|
|
310
|
-
const createdIssue = await createIssue(issue.title, issueBody, labels);
|
|
311
|
-
createdIssues.push({
|
|
312
|
-
issue,
|
|
313
|
-
githubUrl: createdIssue.html_url,
|
|
314
|
-
number: createdIssue.number
|
|
315
|
-
});
|
|
316
|
-
logger.info(`✅ Created GitHub issue #${createdIssue.number}: ${createdIssue.html_url}`);
|
|
317
|
-
} catch (error) {
|
|
318
|
-
logger.error(`❌ Failed to create GitHub issue for "${issue.title}": ${error.message}`);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
// Return formatted results
|
|
323
|
-
if (createdIssues.length > 0) {
|
|
324
|
-
return formatReviewResultsWithIssues(result, createdIssues);
|
|
325
|
-
} else {
|
|
326
|
-
return formatReviewResults(result);
|
|
327
|
-
}
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
export { get, handleIssueCreation };
|
|
331
|
-
//# sourceMappingURL=issues.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"issues.js","sources":["../../src/content/issues.ts"],"sourcesContent":["import { getLogger } from '../logging';\nimport { getUserChoice as getUserChoiceInteractive } from '../util/interactive';\nimport { getOpenIssues, createIssue } from '../util/github';\nimport path from 'path';\nimport os from 'os';\nimport { spawnSync } from 'child_process';\nimport fs from 'fs/promises';\n\nexport interface Issue {\n title: string;\n description: string;\n priority: 'low' | 'medium' | 'high';\n category: 'ui' | 'content' | 'functionality' | 'accessibility' | 'performance' | 'other';\n suggestions?: string[];\n}\n\nexport interface ReviewResult {\n summary: string;\n totalIssues: number;\n issues: Issue[];\n}\n\n// Get GitHub issues content\nexport const get = async (options: { limit?: number } = {}): Promise<string> => {\n const logger = getLogger();\n const { limit = 20 } = options;\n\n try {\n logger.debug('Fetching open GitHub issues...');\n const issuesLimit = Math.min(limit, 20); // Cap at 20\n const githubIssues = await getOpenIssues(issuesLimit);\n\n if (githubIssues.trim()) {\n logger.debug('Added GitHub issues to context (%d characters)', githubIssues.length);\n return githubIssues;\n } else {\n logger.debug('No open GitHub issues found');\n return '';\n }\n } catch (error: any) {\n logger.warn('Failed to fetch GitHub issues: %s', error.message);\n return '';\n }\n};\n\n// Helper function to get user choice interactively\nasync function getUserChoice(prompt: string, choices: Array<{ key: string, label: string }>): Promise<string> {\n return await getUserChoiceInteractive(prompt, choices);\n}\n\n// Helper function to serialize issue to structured text format\nfunction serializeIssue(issue: Issue): string {\n const lines = [\n '# Issue Editor',\n '',\n '# Edit the issue details below. Lines starting with \"#\" are comments and will be ignored.',\n '# Valid priorities: low, medium, high',\n '# Valid categories: ui, content, functionality, accessibility, performance, other',\n '# Suggestions should be one per line, preceded by a \"-\" or \"•\"',\n '',\n `Title: ${issue.title}`,\n '',\n `Priority: ${issue.priority}`,\n '',\n `Category: ${issue.category}`,\n '',\n 'Description:',\n issue.description,\n '',\n 'Suggestions:',\n ];\n\n if (issue.suggestions && issue.suggestions.length > 0) {\n issue.suggestions.forEach(suggestion => {\n lines.push(`- ${suggestion}`);\n });\n } else {\n lines.push('# Add suggestions here, one per line with \"-\" or \"•\"');\n }\n\n return lines.join('\\n');\n}\n\n// Helper function to deserialize issue from structured text format\nfunction deserializeIssue(content: string): Issue {\n const lines = content.split('\\n');\n\n // Parse the structured format\n let title = '';\n let priority: 'low' | 'medium' | 'high' = 'medium';\n let category: 'ui' | 'content' | 'functionality' | 'accessibility' | 'performance' | 'other' = 'other';\n let description = '';\n const suggestions: string[] = [];\n\n let currentSection = '';\n let descriptionLines: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // Skip comment lines\n if (line.startsWith('#')) {\n continue;\n }\n\n // Parse field lines\n if (line.startsWith('Title:')) {\n title = line.substring(6).trim();\n } else if (line.startsWith('Priority:')) {\n const priorityValue = line.substring(9).trim().toLowerCase();\n if (priorityValue === 'low' || priorityValue === 'medium' || priorityValue === 'high') {\n priority = priorityValue;\n }\n } else if (line.startsWith('Category:')) {\n const categoryValue = line.substring(9).trim().toLowerCase();\n if (['ui', 'content', 'functionality', 'accessibility', 'performance', 'other'].includes(categoryValue)) {\n category = categoryValue as any;\n }\n } else if (line === 'Description:') {\n currentSection = 'description';\n descriptionLines = [];\n } else if (line === 'Suggestions:') {\n currentSection = 'suggestions';\n // Process accumulated description lines\n description = descriptionLines.join('\\n').trim();\n } else if (currentSection === 'description' && line !== '') {\n descriptionLines.push(lines[i]); // Keep original line with spacing\n } else if (currentSection === 'suggestions' && line !== '') {\n // Parse suggestion line\n const suggestionLine = line.replace(/^[-•]\\s*/, '').trim();\n if (suggestionLine) {\n suggestions.push(suggestionLine);\n }\n }\n }\n\n // If we didn't encounter suggestions section, description might still be accumulating\n if (currentSection === 'description') {\n description = descriptionLines.join('\\n').trim();\n }\n\n return {\n title: title || 'Untitled Issue',\n priority,\n category,\n description: description || 'No description provided',\n suggestions: suggestions.length > 0 ? suggestions : undefined\n };\n}\n\n// Helper function to edit issue using editor\nasync function editIssueInteractively(issue: Issue): Promise<Issue> {\n const logger = getLogger();\n const editor = process.env.EDITOR || process.env.VISUAL || 'vi';\n\n // Create a temporary file for the user to edit\n const tmpDir = os.tmpdir();\n const tmpFilePath = path.join(tmpDir, `kodrdriv_issue_${Date.now()}.txt`);\n\n // Serialize the issue to structured text format\n const issueContent = serializeIssue(issue);\n\n await fs.writeFile(tmpFilePath, issueContent, 'utf8');\n\n logger.info(`📝 Opening ${editor} to edit issue...`);\n\n // Open the editor synchronously so execution resumes after the user closes it\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 and deserialize it\n const editedContent = await fs.readFile(tmpFilePath, 'utf8');\n\n // Clean up the temporary file with proper error handling\n try {\n await fs.unlink(tmpFilePath);\n } catch (error: any) {\n // Only log if it's not a \"file not found\" error\n if (error.code !== 'ENOENT') {\n logger.warn(`Failed to cleanup temporary file ${tmpFilePath}: ${error.message}`);\n }\n }\n\n // Deserialize the edited content back to an Issue object\n const editedIssue = deserializeIssue(editedContent);\n\n logger.info('✅ Issue updated successfully');\n logger.debug('Updated issue: %s', JSON.stringify(editedIssue, null, 2));\n\n return editedIssue;\n}\n\n// Helper function to format issue body for GitHub\nfunction formatIssueBody(issue: Issue): string {\n let body = `## Description\\n\\n${issue.description}\\n\\n`;\n\n body += `## Details\\n\\n`;\n body += `- **Priority:** ${issue.priority}\\n`;\n body += `- **Category:** ${issue.category}\\n`;\n body += `- **Source:** Review\\n\\n`;\n\n if (issue.suggestions && issue.suggestions.length > 0) {\n body += `## Suggestions\\n\\n`;\n issue.suggestions.forEach(suggestion => {\n body += `- ${suggestion}\\n`;\n });\n body += '\\n';\n }\n\n body += `---\\n\\n`;\n body += `*This issue was automatically created from a review session.*`;\n\n return body;\n}\n\n// Helper function to format results with created GitHub issues\nfunction formatReviewResultsWithIssues(\n result: ReviewResult,\n createdIssues: Array<{ issue: Issue, githubUrl: string, number: number }>\n): string {\n let output = `📝 Review Results\\n\\n`;\n output += `📋 Summary: ${result.summary}\\n`;\n output += `📊 Total Issues Found: ${result.totalIssues}\\n`;\n output += `🚀 GitHub Issues Created: ${createdIssues.length}\\n\\n`;\n\n if (result.issues && result.issues.length > 0) {\n output += `📝 Issues Identified:\\n\\n`;\n\n result.issues.forEach((issue, index) => {\n const priorityEmoji = issue.priority === 'high' ? '🔴' :\n issue.priority === 'medium' ? '🟡' : '🟢';\n const categoryEmoji = issue.category === 'ui' ? '🎨' :\n issue.category === 'content' ? '📝' :\n issue.category === 'functionality' ? '⚙️' :\n issue.category === 'accessibility' ? '♿' :\n issue.category === 'performance' ? '⚡' : '🔧';\n\n output += `${index + 1}. ${priorityEmoji} ${issue.title}\\n`;\n output += ` ${categoryEmoji} Category: ${issue.category} | Priority: ${issue.priority}\\n`;\n output += ` 📖 Description: ${issue.description}\\n`;\n\n // Check if this issue was created as a GitHub issue\n const createdIssue = createdIssues.find(ci => ci.issue === issue);\n if (createdIssue) {\n output += ` 🔗 GitHub Issue: #${createdIssue.number} - ${createdIssue.githubUrl}\\n`;\n }\n\n if (issue.suggestions && issue.suggestions.length > 0) {\n output += ` 💡 Suggestions:\\n`;\n issue.suggestions.forEach(suggestion => {\n output += ` • ${suggestion}\\n`;\n });\n }\n output += `\\n`;\n });\n } else {\n output += `✅ No specific issues identified from the review.\\n\\n`;\n }\n\n if (createdIssues.length > 0) {\n output += `\\n🎯 Created GitHub Issues:\\n`;\n createdIssues.forEach(createdIssue => {\n output += `• #${createdIssue.number}: ${createdIssue.issue.title} - ${createdIssue.githubUrl}\\n`;\n });\n output += `\\n`;\n }\n\n output += `🚀 Next Steps: Review the created GitHub issues and prioritize them in your development workflow.`;\n\n return output;\n}\n\nfunction formatReviewResults(result: ReviewResult): string {\n let output = `📝 Review Results\\n\\n`;\n output += `📋 Summary: ${result.summary}\\n`;\n output += `📊 Total Issues Found: ${result.totalIssues}\\n\\n`;\n\n if (result.issues && result.issues.length > 0) {\n output += `📝 Issues Identified:\\n\\n`;\n\n result.issues.forEach((issue, index) => {\n const priorityEmoji = issue.priority === 'high' ? '🔴' :\n issue.priority === 'medium' ? '🟡' : '🟢';\n const categoryEmoji = issue.category === 'ui' ? '🎨' :\n issue.category === 'content' ? '📝' :\n issue.category === 'functionality' ? '⚙️' :\n issue.category === 'accessibility' ? '♿' :\n issue.category === 'performance' ? '⚡' : '🔧';\n\n output += `${index + 1}. ${priorityEmoji} ${issue.title}\\n`;\n output += ` ${categoryEmoji} Category: ${issue.category} | Priority: ${issue.priority}\\n`;\n output += ` 📖 Description: ${issue.description}\\n`;\n\n if (issue.suggestions && issue.suggestions.length > 0) {\n output += ` 💡 Suggestions:\\n`;\n issue.suggestions.forEach(suggestion => {\n output += ` • ${suggestion}\\n`;\n });\n }\n output += `\\n`;\n });\n } else {\n output += `✅ No specific issues identified from the review.\\n\\n`;\n }\n\n output += `🚀 Next Steps: Review the identified issues and prioritize them for your development workflow.`;\n\n return output;\n}\n\n// Handle GitHub issue creation workflow\nexport const handleIssueCreation = async (\n result: ReviewResult,\n senditMode: boolean = false\n): Promise<string> => {\n const logger = getLogger();\n const createdIssues: Array<{ issue: Issue, githubUrl: string, number: number }> = [];\n\n if (!result.issues || result.issues.length === 0) {\n return formatReviewResults(result);\n }\n\n logger.info(`🔍 Found ${result.issues.length} issues to potentially create as GitHub issues`);\n\n for (let i = 0; i < result.issues.length; i++) {\n let issue = result.issues[i];\n let shouldCreateIssue = senditMode;\n\n if (!senditMode) {\n // Interactive confirmation for each issue - keep looping until user decides\n let userChoice = '';\n while (userChoice !== 'c' && userChoice !== 's') {\n // Display issue details\n logger.info(`\\n📋 Issue ${i + 1} of ${result.issues.length}:`);\n logger.info(` Title: ${issue.title}`);\n logger.info(` Priority: ${issue.priority} | Category: ${issue.category}`);\n logger.info(` Description: ${issue.description}`);\n if (issue.suggestions && issue.suggestions.length > 0) {\n logger.info(` Suggestions: ${issue.suggestions.join(', ')}`);\n }\n\n // Get user choice\n userChoice = await getUserChoice('\\nWhat would you like to do with this issue?', [\n { key: 'c', label: 'Create GitHub issue' },\n { key: 's', label: 'Skip this issue' },\n { key: 'e', label: 'Edit issue details' }\n ]);\n\n if (userChoice === 'c') {\n shouldCreateIssue = true;\n } else if (userChoice === 'e') {\n // Allow user to edit the issue\n issue = await editIssueInteractively(issue);\n result.issues[i] = issue; // Update the issue in the result\n // Continue the loop to show the updated issue and ask again\n }\n // If choice is 's', loop will exit and shouldCreateIssue remains false\n }\n }\n\n if (shouldCreateIssue) {\n try {\n logger.info(`🚀 Creating GitHub issue: \"${issue.title}\"`);\n\n // Format issue body with additional details\n const issueBody = formatIssueBody(issue);\n\n // Create labels based on priority and category\n const labels = [\n `priority-${issue.priority}`,\n `category-${issue.category}`,\n 'review'\n ];\n\n const createdIssue = await createIssue(issue.title, issueBody, labels);\n createdIssues.push({\n issue,\n githubUrl: createdIssue.html_url,\n number: createdIssue.number\n });\n\n logger.info(`✅ Created GitHub issue #${createdIssue.number}: ${createdIssue.html_url}`);\n } catch (error: any) {\n logger.error(`❌ Failed to create GitHub issue for \"${issue.title}\": ${error.message}`);\n }\n }\n }\n\n // Return formatted results\n if (createdIssues.length > 0) {\n return formatReviewResultsWithIssues(result, createdIssues);\n } else {\n return formatReviewResults(result);\n }\n};\n"],"names":["get","options","logger","getLogger","limit","debug","issuesLimit","Math","min","githubIssues","getOpenIssues","trim","length","error","warn","message","getUserChoice","prompt","choices","getUserChoiceInteractive","serializeIssue","issue","lines","title","priority","category","description","suggestions","forEach","suggestion","push","join","deserializeIssue","content","split","currentSection","descriptionLines","i","line","startsWith","substring","priorityValue","toLowerCase","categoryValue","includes","suggestionLine","replace","undefined","editIssueInteractively","editor","process","env","EDITOR","VISUAL","tmpDir","os","tmpdir","tmpFilePath","path","Date","now","issueContent","fs","writeFile","info","result","spawnSync","stdio","Error","editedContent","readFile","unlink","code","editedIssue","JSON","stringify","formatIssueBody","body","formatReviewResultsWithIssues","createdIssues","output","summary","totalIssues","issues","index","priorityEmoji","categoryEmoji","createdIssue","find","ci","number","githubUrl","formatReviewResults","handleIssueCreation","senditMode","shouldCreateIssue","userChoice","key","label","issueBody","labels","createIssue","html_url"],"mappings":"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"}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { getLogger } from '../logging.js';
|
|
2
|
-
import { getOctokit, getRepoDetails } from '../util/github.js';
|
|
3
|
-
|
|
4
|
-
// Function to truncate overly large content while preserving structure
|
|
5
|
-
const truncateContent = (content, maxLength = 3000)=>{
|
|
6
|
-
if (content.length <= maxLength) {
|
|
7
|
-
return content;
|
|
8
|
-
}
|
|
9
|
-
const lines = content.split('\n');
|
|
10
|
-
const truncatedLines = [];
|
|
11
|
-
let currentLength = 0;
|
|
12
|
-
for (const line of lines){
|
|
13
|
-
if (currentLength + line.length + 1 > maxLength) {
|
|
14
|
-
break;
|
|
15
|
-
}
|
|
16
|
-
truncatedLines.push(line);
|
|
17
|
-
currentLength += line.length + 1; // +1 for newline
|
|
18
|
-
}
|
|
19
|
-
truncatedLines.push('');
|
|
20
|
-
truncatedLines.push(`... [TRUNCATED: Original content was ${content.length} characters, showing first ${currentLength}] ...`);
|
|
21
|
-
return truncatedLines.join('\n');
|
|
22
|
-
};
|
|
23
|
-
// Function to fetch recent releases from GitHub API
|
|
24
|
-
const findRecentReleaseNotes = async (limit)=>{
|
|
25
|
-
const logger = getLogger();
|
|
26
|
-
const releaseNotes = [];
|
|
27
|
-
if (limit <= 0) {
|
|
28
|
-
return releaseNotes;
|
|
29
|
-
}
|
|
30
|
-
try {
|
|
31
|
-
const octokit = getOctokit();
|
|
32
|
-
const { owner, repo } = await getRepoDetails();
|
|
33
|
-
logger.debug(`Fetching up to ${limit} recent releases from GitHub...`);
|
|
34
|
-
const response = await octokit.repos.listReleases({
|
|
35
|
-
owner,
|
|
36
|
-
repo,
|
|
37
|
-
per_page: Math.min(limit, 100)
|
|
38
|
-
});
|
|
39
|
-
const releases = response.data;
|
|
40
|
-
if (releases.length === 0) {
|
|
41
|
-
logger.debug('No releases found in GitHub repository');
|
|
42
|
-
return releaseNotes;
|
|
43
|
-
}
|
|
44
|
-
for (const release of releases.slice(0, limit)){
|
|
45
|
-
const releaseContent = [
|
|
46
|
-
`# ${release.name || release.tag_name}`,
|
|
47
|
-
`**Tag:** ${release.tag_name}`,
|
|
48
|
-
`**Published:** ${release.published_at}`,
|
|
49
|
-
release.prerelease ? '**Type:** Pre-release' : '**Type:** Release',
|
|
50
|
-
release.draft ? '**Status:** Draft' : '**Status:** Published',
|
|
51
|
-
'',
|
|
52
|
-
release.body || 'No release notes provided'
|
|
53
|
-
].join('\n');
|
|
54
|
-
const truncatedContent = truncateContent(releaseContent);
|
|
55
|
-
releaseNotes.push(`=== GitHub Release: ${release.tag_name} ===\n${truncatedContent}`);
|
|
56
|
-
if (truncatedContent.length < releaseContent.length) {
|
|
57
|
-
logger.debug(`Found release ${release.tag_name} (%d characters, truncated from %d)`, truncatedContent.length, releaseContent.length);
|
|
58
|
-
} else {
|
|
59
|
-
logger.debug(`Found release ${release.tag_name} (%d characters)`, releaseContent.length);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
logger.debug(`Fetched ${releaseNotes.length} releases from GitHub`);
|
|
63
|
-
} catch (error) {
|
|
64
|
-
logger.warn('Error fetching releases from GitHub API: %s', error.message);
|
|
65
|
-
// If we have a GitHub API error, we could fall back to checking for local release notes
|
|
66
|
-
// This maintains some backward compatibility
|
|
67
|
-
logger.debug('Falling back to local RELEASE_NOTES.md file...');
|
|
68
|
-
try {
|
|
69
|
-
const fs = await import('fs/promises');
|
|
70
|
-
const content = await fs.readFile('RELEASE_NOTES.md', 'utf-8');
|
|
71
|
-
if (content.trim()) {
|
|
72
|
-
const truncatedContent = truncateContent(content);
|
|
73
|
-
releaseNotes.push(`=== Local RELEASE_NOTES.md ===\n${truncatedContent}`);
|
|
74
|
-
logger.debug(`Found local release notes (%d characters)`, content.length);
|
|
75
|
-
}
|
|
76
|
-
} catch {
|
|
77
|
-
// No local file either, return empty array
|
|
78
|
-
logger.debug('No local RELEASE_NOTES.md file found either');
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return releaseNotes.slice(0, limit);
|
|
82
|
-
};
|
|
83
|
-
const get = async (options = {})=>{
|
|
84
|
-
const { limit = 3 } = options;
|
|
85
|
-
const releaseNotes = await findRecentReleaseNotes(limit);
|
|
86
|
-
return releaseNotes.join('\n\n');
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
export { findRecentReleaseNotes, get };
|
|
90
|
-
//# sourceMappingURL=releaseNotes.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"releaseNotes.js","sources":["../../src/content/releaseNotes.ts"],"sourcesContent":["import { getLogger } from '../logging';\nimport { getOctokit, getRepoDetails } from '../util/github';\n\n// Function to truncate overly large content while preserving structure\nconst truncateContent = (content: string, maxLength: number = 3000): string => {\n if (content.length <= maxLength) {\n return content;\n }\n\n const lines = content.split('\\n');\n const truncatedLines: string[] = [];\n let currentLength = 0;\n\n for (const line of lines) {\n if (currentLength + line.length + 1 > maxLength) {\n break;\n }\n truncatedLines.push(line);\n currentLength += line.length + 1; // +1 for newline\n }\n\n truncatedLines.push('');\n truncatedLines.push(`... [TRUNCATED: Original content was ${content.length} characters, showing first ${currentLength}] ...`);\n\n return truncatedLines.join('\\n');\n};\n\n// Function to fetch recent releases from GitHub API\nexport const findRecentReleaseNotes = async (limit: number): Promise<string[]> => {\n const logger = getLogger();\n const releaseNotes: string[] = [];\n\n if (limit <= 0) {\n return releaseNotes;\n }\n\n try {\n const octokit = getOctokit();\n const { owner, repo } = await getRepoDetails();\n\n logger.debug(`Fetching up to ${limit} recent releases from GitHub...`);\n\n const response = await octokit.repos.listReleases({\n owner,\n repo,\n per_page: Math.min(limit, 100), // GitHub API limit\n });\n\n const releases = response.data;\n\n if (releases.length === 0) {\n logger.debug('No releases found in GitHub repository');\n return releaseNotes;\n }\n\n for (const release of releases.slice(0, limit)) {\n const releaseContent = [\n `# ${release.name || release.tag_name}`,\n `**Tag:** ${release.tag_name}`,\n `**Published:** ${release.published_at}`,\n release.prerelease ? '**Type:** Pre-release' : '**Type:** Release',\n release.draft ? '**Status:** Draft' : '**Status:** Published',\n '',\n release.body || 'No release notes provided'\n ].join('\\n');\n\n const truncatedContent = truncateContent(releaseContent);\n releaseNotes.push(`=== GitHub Release: ${release.tag_name} ===\\n${truncatedContent}`);\n\n if (truncatedContent.length < releaseContent.length) {\n logger.debug(`Found release ${release.tag_name} (%d characters, truncated from %d)`,\n truncatedContent.length, releaseContent.length);\n } else {\n logger.debug(`Found release ${release.tag_name} (%d characters)`, releaseContent.length);\n }\n }\n\n logger.debug(`Fetched ${releaseNotes.length} releases from GitHub`);\n\n } catch (error: any) {\n logger.warn('Error fetching releases from GitHub API: %s', error.message);\n\n // If we have a GitHub API error, we could fall back to checking for local release notes\n // This maintains some backward compatibility\n logger.debug('Falling back to local RELEASE_NOTES.md file...');\n try {\n const fs = await import('fs/promises');\n const content = await fs.readFile('RELEASE_NOTES.md', 'utf-8');\n if (content.trim()) {\n const truncatedContent = truncateContent(content);\n releaseNotes.push(`=== Local RELEASE_NOTES.md ===\\n${truncatedContent}`);\n logger.debug(`Found local release notes (%d characters)`, content.length);\n }\n } catch {\n // No local file either, return empty array\n logger.debug('No local RELEASE_NOTES.md file found either');\n }\n }\n\n return releaseNotes.slice(0, limit);\n};\n\nexport const get = async (options: { limit?: number } = {}): Promise<string> => {\n const { limit = 3 } = options;\n const releaseNotes = await findRecentReleaseNotes(limit);\n return releaseNotes.join('\\n\\n');\n}; "],"names":["truncateContent","content","maxLength","length","lines","split","truncatedLines","currentLength","line","push","join","findRecentReleaseNotes","limit","logger","getLogger","releaseNotes","octokit","getOctokit","owner","repo","getRepoDetails","debug","response","repos","listReleases","per_page","Math","min","releases","data","release","slice","releaseContent","name","tag_name","published_at","prerelease","draft","body","truncatedContent","error","warn","message","fs","readFile","trim","get","options"],"mappings":"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"}
|
package/dist/prompt/commit.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { recipe } from '@riotprompt/riotprompt';
|
|
2
|
-
import path__default from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
|
|
5
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
-
const __dirname = path__default.dirname(__filename);
|
|
7
|
-
/**
|
|
8
|
-
* Build a commit prompt using RiotPrompt Recipes.
|
|
9
|
-
*
|
|
10
|
-
* This prompt is configured to generate multiline commit messages by default,
|
|
11
|
-
* with separate lines/bullet points for different groups of changes rather
|
|
12
|
-
* than squeezing everything into single lines.
|
|
13
|
-
*
|
|
14
|
-
* @param runConfig The runtime configuration provided by the CLI
|
|
15
|
-
* @param content Mandatory content inputs (e.g. diff)
|
|
16
|
-
* @param ctx Optional contextual inputs configured by the user
|
|
17
|
-
*/ const createPrompt = async ({ overridePaths: _overridePaths, overrides: _overrides }, { diffContent, userDirection, isFileContent, githubIssuesContext }, { logContext, context, directories } = {})=>{
|
|
18
|
-
const basePath = __dirname;
|
|
19
|
-
// Build content items for the prompt
|
|
20
|
-
const contentItems = [];
|
|
21
|
-
const contextItems = [];
|
|
22
|
-
// Developer Note: Direction is injected first as the highest-priority prompt input
|
|
23
|
-
// This ensures user guidance takes precedence over other context sources like
|
|
24
|
-
// GitHub issues or commit history. Direction content is sanitized via sanitizeDirection()
|
|
25
|
-
// to prevent template breakage (newlines converted to spaces, whitespace normalized,
|
|
26
|
-
// length limited to 2000 chars). See tests/util/validation.test.ts for sanitization behavior
|
|
27
|
-
// and src/commands/commit.ts line 446 for debug logging of direction processing.
|
|
28
|
-
if (userDirection) {
|
|
29
|
-
contentItems.push({
|
|
30
|
-
content: userDirection,
|
|
31
|
-
title: 'User Direction'
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
if (diffContent) {
|
|
35
|
-
const contentTitle = isFileContent ? 'Project Files' : 'Diff';
|
|
36
|
-
contentItems.push({
|
|
37
|
-
content: diffContent,
|
|
38
|
-
title: contentTitle
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
if (githubIssuesContext) {
|
|
42
|
-
contentItems.push({
|
|
43
|
-
content: githubIssuesContext,
|
|
44
|
-
title: 'Recent GitHub Issues'
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
// IMPORTANT: Log context provides background but can contaminate output if too large.
|
|
48
|
-
// LLMs tend to pattern-match against recent commits instead of describing the actual diff.
|
|
49
|
-
// Keep messageLimit low (3-5) to minimize contamination. See DEFAULT_MESSAGE_LIMIT in constants.ts
|
|
50
|
-
if (logContext) {
|
|
51
|
-
contextItems.push({
|
|
52
|
-
content: logContext,
|
|
53
|
-
title: 'Log Context'
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
if (context) {
|
|
57
|
-
contextItems.push({
|
|
58
|
-
content: context,
|
|
59
|
-
title: 'User Context'
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
if (directories && directories.length > 0) {
|
|
63
|
-
contextItems.push({
|
|
64
|
-
directories,
|
|
65
|
-
title: 'Directories'
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
return recipe(basePath).persona({
|
|
69
|
-
path: 'personas/you.md'
|
|
70
|
-
}).instructions({
|
|
71
|
-
path: 'instructions/commit.md'
|
|
72
|
-
}).overridePaths(_overridePaths !== null && _overridePaths !== void 0 ? _overridePaths : []).overrides(_overrides !== null && _overrides !== void 0 ? _overrides : true).content(...contentItems).context(...contextItems).cook();
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
export { createPrompt };
|
|
76
|
-
//# sourceMappingURL=commit.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commit.js","sources":["../../src/prompt/commit.ts"],"sourcesContent":["import { Prompt, recipe } from '@riotprompt/riotprompt';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Types for the commit prompt\nexport type Content = {\n diffContent: string;\n userDirection?: string;\n isFileContent?: boolean; // Flag to indicate if diffContent is actually file content\n githubIssuesContext?: string; // GitHub issues related to current version/milestone\n};\n\nexport type Context = {\n logContext?: string;\n context?: string;\n directories?: string[];\n};\n\nexport type Config = {\n overridePaths?: string[];\n overrides?: boolean;\n}\n\n/**\n * Build a commit prompt using RiotPrompt Recipes.\n *\n * This prompt is configured to generate multiline commit messages by default,\n * with separate lines/bullet points for different groups of changes rather\n * than squeezing everything into single lines.\n *\n * @param runConfig The runtime configuration provided by the CLI\n * @param content Mandatory content inputs (e.g. diff)\n * @param ctx Optional contextual inputs configured by the user\n */\nexport const createPrompt = async (\n { overridePaths: _overridePaths, overrides: _overrides }: Config,\n { diffContent, userDirection, isFileContent, githubIssuesContext }: Content,\n { logContext, context, directories }: Context = {}\n): Promise<Prompt> => {\n const basePath = __dirname;\n\n // Build content items for the prompt\n const contentItems = [];\n const contextItems = [];\n\n // Developer Note: Direction is injected first as the highest-priority prompt input\n // This ensures user guidance takes precedence over other context sources like\n // GitHub issues or commit history. Direction content is sanitized via sanitizeDirection()\n // to prevent template breakage (newlines converted to spaces, whitespace normalized,\n // length limited to 2000 chars). See tests/util/validation.test.ts for sanitization behavior\n // and src/commands/commit.ts line 446 for debug logging of direction processing.\n if (userDirection) {\n contentItems.push({ content: userDirection, title: 'User Direction' });\n }\n if (diffContent) {\n const contentTitle = isFileContent ? 'Project Files' : 'Diff';\n contentItems.push({ content: diffContent, title: contentTitle });\n }\n if (githubIssuesContext) {\n contentItems.push({ content: githubIssuesContext, title: 'Recent GitHub Issues' });\n }\n\n // IMPORTANT: Log context provides background but can contaminate output if too large.\n // LLMs tend to pattern-match against recent commits instead of describing the actual diff.\n // Keep messageLimit low (3-5) to minimize contamination. See DEFAULT_MESSAGE_LIMIT in constants.ts\n if (logContext) {\n contextItems.push({ content: logContext, title: 'Log Context' });\n }\n if (context) {\n contextItems.push({ content: context, title: 'User Context' });\n }\n if (directories && directories.length > 0) {\n contextItems.push({ directories, title: 'Directories' });\n }\n\n return recipe(basePath)\n .persona({ path: 'personas/you.md' })\n .instructions({ path: 'instructions/commit.md' })\n .overridePaths(_overridePaths ?? [])\n .overrides(_overrides ?? true)\n .content(...contentItems)\n .context(...contextItems)\n .cook();\n};\n"],"names":["__filename","fileURLToPath","url","__dirname","path","dirname","createPrompt","overridePaths","_overridePaths","overrides","_overrides","diffContent","userDirection","isFileContent","githubIssuesContext","logContext","context","directories","basePath","contentItems","contextItems","push","content","title","contentTitle","length","recipe","persona","instructions","cook"],"mappings":";;;;AAIA,MAAMA,UAAAA,GAAaC,aAAAA,CAAc,MAAA,CAAA,IAAA,CAAYC,GAAG,CAAA;AAChD,MAAMC,SAAAA,GAAYC,aAAAA,CAAKC,OAAO,CAACL,UAAAA,CAAAA;AAqB/B;;;;;;;;;;AAUC,IACM,MAAMM,YAAAA,GAAe,OACxB,EAAEC,aAAAA,EAAeC,cAAc,EAAEC,SAAAA,EAAWC,UAAU,EAAU,EAChE,EAAEC,WAAW,EAAEC,aAAa,EAAEC,aAAa,EAAEC,mBAAmB,EAAW,EAC3E,EAAEC,UAAU,EAAEC,OAAO,EAAEC,WAAW,EAAW,GAAG,EAAE,GAAA;AAElD,IAAA,MAAMC,QAAAA,GAAWf,SAAAA;;AAGjB,IAAA,MAAMgB,eAAe,EAAE;AACvB,IAAA,MAAMC,eAAe,EAAE;;;;;;;AAQvB,IAAA,IAAIR,aAAAA,EAAe;AACfO,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAASV,aAAAA;YAAeW,KAAAA,EAAO;AAAiB,SAAA,CAAA;AACxE,IAAA;AACA,IAAA,IAAIZ,WAAAA,EAAa;QACb,MAAMa,YAAAA,GAAeX,gBAAgB,eAAA,GAAkB,MAAA;AACvDM,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAASX,WAAAA;YAAaY,KAAAA,EAAOC;AAAa,SAAA,CAAA;AAClE,IAAA;AACA,IAAA,IAAIV,mBAAAA,EAAqB;AACrBK,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAASR,mBAAAA;YAAqBS,KAAAA,EAAO;AAAuB,SAAA,CAAA;AACpF,IAAA;;;;AAKA,IAAA,IAAIR,UAAAA,EAAY;AACZK,QAAAA,YAAAA,CAAaC,IAAI,CAAC;YAAEC,OAAAA,EAASP,UAAAA;YAAYQ,KAAAA,EAAO;AAAc,SAAA,CAAA;AAClE,IAAA;AACA,IAAA,IAAIP,OAAAA,EAAS;AACTI,QAAAA,YAAAA,CAAaC,IAAI,CAAC;YAAEC,OAAAA,EAASN,OAAAA;YAASO,KAAAA,EAAO;AAAe,SAAA,CAAA;AAChE,IAAA;AACA,IAAA,IAAIN,WAAAA,IAAeA,WAAAA,CAAYQ,MAAM,GAAG,CAAA,EAAG;AACvCL,QAAAA,YAAAA,CAAaC,IAAI,CAAC;AAAEJ,YAAAA,WAAAA;YAAaM,KAAAA,EAAO;AAAc,SAAA,CAAA;AAC1D,IAAA;IAEA,OAAOG,MAAAA,CAAOR,QAAAA,CAAAA,CACTS,OAAO,CAAC;QAAEvB,IAAAA,EAAM;AAAkB,KAAA,CAAA,CAClCwB,YAAY,CAAC;QAAExB,IAAAA,EAAM;AAAyB,KAAA,CAAA,CAC9CG,aAAa,CAACC,cAAAA,KAAAA,IAAAA,IAAAA,4BAAAA,cAAAA,GAAkB,EAAE,EAClCC,SAAS,CAACC,uBAAAA,UAAAA,KAAAA,MAAAA,GAAAA,UAAAA,GAAc,MACxBY,OAAO,CAAA,GAAIH,cACXH,OAAO,CAAA,GAAII,cACXS,IAAI,EAAA;AACb;;;;"}
|