@eldrforge/kodrdriv 0.0.23 → 0.0.25
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/dist/arguments.js +7 -4
- package/dist/arguments.js.map +1 -1
- package/dist/commands/audio-commit.js +2 -1
- package/dist/commands/audio-commit.js.map +1 -1
- package/dist/commands/audio-review.js +139 -19
- package/dist/commands/audio-review.js.map +1 -1
- package/dist/commands/release.js +5 -3
- package/dist/commands/release.js.map +1 -1
- package/dist/commands/review.js +24 -14
- package/dist/commands/review.js.map +1 -1
- package/dist/constants.js +3 -2
- package/dist/constants.js.map +1 -1
- package/dist/content/issues.js +170 -66
- package/dist/content/issues.js.map +1 -1
- package/dist/prompt/commit.js +2 -2
- package/dist/prompt/commit.js.map +1 -1
- package/dist/prompt/instructions/review.md +26 -9
- package/dist/prompt/release.js +2 -2
- package/dist/prompt/release.js.map +1 -1
- package/dist/prompt/review.js +31 -40
- package/dist/prompt/review.js.map +1 -1
- package/dist/types.js +3 -1
- package/dist/types.js.map +1 -1
- package/dist/util/general.js +55 -1
- package/dist/util/general.js.map +1 -1
- package/dist/util/openai.js +9 -0
- package/dist/util/openai.js.map +1 -1
- package/package.json +3 -3
package/dist/content/issues.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { getLogger } from '../logging.js';
|
|
2
2
|
import { getOpenIssues, createIssue } from '../util/github.js';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import { spawnSync } from 'child_process';
|
|
6
|
+
import fs from 'fs/promises';
|
|
3
7
|
|
|
4
8
|
// Get GitHub issues content
|
|
5
9
|
const get = async (options = {})=>{
|
|
@@ -29,6 +33,13 @@ async function getUserChoice(prompt, choices) {
|
|
|
29
33
|
logger.info(` [${choice.key}] ${choice.label}`);
|
|
30
34
|
});
|
|
31
35
|
logger.info('');
|
|
36
|
+
// Check if stdin is a TTY (terminal) or piped
|
|
37
|
+
if (!process.stdin.isTTY) {
|
|
38
|
+
// STDIN is piped, we can't use interactive prompts
|
|
39
|
+
// This should not happen anymore due to fail-fast check in review.ts
|
|
40
|
+
logger.error('⚠️ Unexpected: STDIN is piped in interactive mode');
|
|
41
|
+
return 's'; // Default to skip
|
|
42
|
+
}
|
|
32
43
|
return new Promise((resolve)=>{
|
|
33
44
|
// Ensure stdin is referenced so the process doesn't exit while waiting for input
|
|
34
45
|
if (typeof process.stdin.ref === 'function') {
|
|
@@ -52,45 +63,134 @@ async function getUserChoice(prompt, choices) {
|
|
|
52
63
|
});
|
|
53
64
|
});
|
|
54
65
|
}
|
|
55
|
-
// Helper function to
|
|
66
|
+
// Helper function to serialize issue to structured text format
|
|
67
|
+
function serializeIssue(issue) {
|
|
68
|
+
const lines = [
|
|
69
|
+
'# Issue Editor',
|
|
70
|
+
'',
|
|
71
|
+
'# Edit the issue details below. Lines starting with "#" are comments and will be ignored.',
|
|
72
|
+
'# Valid priorities: low, medium, high',
|
|
73
|
+
'# Valid categories: ui, content, functionality, accessibility, performance, other',
|
|
74
|
+
'# Suggestions should be one per line, preceded by a "-" or "•"',
|
|
75
|
+
'',
|
|
76
|
+
`Title: ${issue.title}`,
|
|
77
|
+
'',
|
|
78
|
+
`Priority: ${issue.priority}`,
|
|
79
|
+
'',
|
|
80
|
+
`Category: ${issue.category}`,
|
|
81
|
+
'',
|
|
82
|
+
'Description:',
|
|
83
|
+
issue.description,
|
|
84
|
+
'',
|
|
85
|
+
'Suggestions:'
|
|
86
|
+
];
|
|
87
|
+
if (issue.suggestions && issue.suggestions.length > 0) {
|
|
88
|
+
issue.suggestions.forEach((suggestion)=>{
|
|
89
|
+
lines.push(`- ${suggestion}`);
|
|
90
|
+
});
|
|
91
|
+
} else {
|
|
92
|
+
lines.push('# Add suggestions here, one per line with "-" or "•"');
|
|
93
|
+
}
|
|
94
|
+
return lines.join('\n');
|
|
95
|
+
}
|
|
96
|
+
// Helper function to deserialize issue from structured text format
|
|
97
|
+
function deserializeIssue(content) {
|
|
98
|
+
const lines = content.split('\n');
|
|
99
|
+
// Parse the structured format
|
|
100
|
+
let title = '';
|
|
101
|
+
let priority = 'medium';
|
|
102
|
+
let category = 'other';
|
|
103
|
+
let description = '';
|
|
104
|
+
const suggestions = [];
|
|
105
|
+
let currentSection = '';
|
|
106
|
+
let descriptionLines = [];
|
|
107
|
+
for(let i = 0; i < lines.length; i++){
|
|
108
|
+
const line = lines[i].trim();
|
|
109
|
+
// Skip comment lines
|
|
110
|
+
if (line.startsWith('#')) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
// Parse field lines
|
|
114
|
+
if (line.startsWith('Title:')) {
|
|
115
|
+
title = line.substring(6).trim();
|
|
116
|
+
} else if (line.startsWith('Priority:')) {
|
|
117
|
+
const priorityValue = line.substring(9).trim().toLowerCase();
|
|
118
|
+
if (priorityValue === 'low' || priorityValue === 'medium' || priorityValue === 'high') {
|
|
119
|
+
priority = priorityValue;
|
|
120
|
+
}
|
|
121
|
+
} else if (line.startsWith('Category:')) {
|
|
122
|
+
const categoryValue = line.substring(9).trim().toLowerCase();
|
|
123
|
+
if ([
|
|
124
|
+
'ui',
|
|
125
|
+
'content',
|
|
126
|
+
'functionality',
|
|
127
|
+
'accessibility',
|
|
128
|
+
'performance',
|
|
129
|
+
'other'
|
|
130
|
+
].includes(categoryValue)) {
|
|
131
|
+
category = categoryValue;
|
|
132
|
+
}
|
|
133
|
+
} else if (line === 'Description:') {
|
|
134
|
+
currentSection = 'description';
|
|
135
|
+
descriptionLines = [];
|
|
136
|
+
} else if (line === 'Suggestions:') {
|
|
137
|
+
currentSection = 'suggestions';
|
|
138
|
+
// Process accumulated description lines
|
|
139
|
+
description = descriptionLines.join('\n').trim();
|
|
140
|
+
} else if (currentSection === 'description' && line !== '') {
|
|
141
|
+
descriptionLines.push(lines[i]); // Keep original line with spacing
|
|
142
|
+
} else if (currentSection === 'suggestions' && line !== '') {
|
|
143
|
+
// Parse suggestion line
|
|
144
|
+
const suggestionLine = line.replace(/^[-•]\s*/, '').trim();
|
|
145
|
+
if (suggestionLine) {
|
|
146
|
+
suggestions.push(suggestionLine);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// If we didn't encounter suggestions section, description might still be accumulating
|
|
151
|
+
if (currentSection === 'description') {
|
|
152
|
+
description = descriptionLines.join('\n').trim();
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
title: title || 'Untitled Issue',
|
|
156
|
+
priority,
|
|
157
|
+
category,
|
|
158
|
+
description: description || 'No description provided',
|
|
159
|
+
suggestions: suggestions.length > 0 ? suggestions : undefined
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
// Helper function to edit issue using editor
|
|
56
163
|
async function editIssueInteractively(issue) {
|
|
57
164
|
const logger = getLogger();
|
|
58
|
-
const
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
165
|
+
const editor = process.env.EDITOR || process.env.VISUAL || 'vi';
|
|
166
|
+
// Create a temporary file for the user to edit
|
|
167
|
+
const tmpDir = os.tmpdir();
|
|
168
|
+
const tmpFilePath = path.join(tmpDir, `kodrdriv_issue_${Date.now()}.txt`);
|
|
169
|
+
// Serialize the issue to structured text format
|
|
170
|
+
const issueContent = serializeIssue(issue);
|
|
171
|
+
await fs.writeFile(tmpFilePath, issueContent, 'utf8');
|
|
172
|
+
logger.info(`📝 Opening ${editor} to edit issue...`);
|
|
173
|
+
// Open the editor synchronously so execution resumes after the user closes it
|
|
174
|
+
const result = spawnSync(editor, [
|
|
175
|
+
tmpFilePath
|
|
176
|
+
], {
|
|
177
|
+
stdio: 'inherit'
|
|
66
178
|
});
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
rl.question(prompt, resolve);
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
try {
|
|
73
|
-
logger.info('📝 Edit issue details (press Enter to keep current value):');
|
|
74
|
-
const newTitle = await question(`Title [${issue.title}]: `);
|
|
75
|
-
const newDescription = await question(`Description [${issue.description}]: `);
|
|
76
|
-
const newPriority = await question(`Priority (low/medium/high) [${issue.priority}]: `);
|
|
77
|
-
const newCategory = await question(`Category (ui/content/functionality/accessibility/performance/other) [${issue.category}]: `);
|
|
78
|
-
const updatedIssue = {
|
|
79
|
-
title: newTitle.trim() || issue.title,
|
|
80
|
-
description: newDescription.trim() || issue.description,
|
|
81
|
-
priority: newPriority.trim() || issue.priority,
|
|
82
|
-
category: newCategory.trim() || issue.category,
|
|
83
|
-
suggestions: issue.suggestions
|
|
84
|
-
};
|
|
85
|
-
logger.info('✅ Issue updated successfully');
|
|
86
|
-
return updatedIssue;
|
|
87
|
-
} finally{
|
|
88
|
-
rl.close();
|
|
89
|
-
// Detach stdin after interactive edit completes
|
|
90
|
-
if (typeof process.stdin.unref === 'function') {
|
|
91
|
-
process.stdin.unref();
|
|
92
|
-
}
|
|
179
|
+
if (result.error) {
|
|
180
|
+
throw new Error(`Failed to launch editor '${editor}': ${result.error.message}`);
|
|
93
181
|
}
|
|
182
|
+
// Read the file back and deserialize it
|
|
183
|
+
const editedContent = await fs.readFile(tmpFilePath, 'utf8');
|
|
184
|
+
// Clean up the temporary file (best-effort – ignore errors)
|
|
185
|
+
try {
|
|
186
|
+
await fs.unlink(tmpFilePath);
|
|
187
|
+
} catch {
|
|
188
|
+
/* ignore */ }
|
|
189
|
+
// Deserialize the edited content back to an Issue object
|
|
190
|
+
const editedIssue = deserializeIssue(editedContent);
|
|
191
|
+
logger.info('✅ Issue updated successfully');
|
|
192
|
+
logger.debug('Updated issue: %s', JSON.stringify(editedIssue, null, 2));
|
|
193
|
+
return editedIssue;
|
|
94
194
|
}
|
|
95
195
|
// Helper function to format issue body for GitHub
|
|
96
196
|
function formatIssueBody(issue) {
|
|
@@ -185,41 +285,45 @@ const handleIssueCreation = async (result, senditMode = false)=>{
|
|
|
185
285
|
}
|
|
186
286
|
logger.info(`🔍 Found ${result.issues.length} issues to potentially create as GitHub issues`);
|
|
187
287
|
for(let i = 0; i < result.issues.length; i++){
|
|
188
|
-
|
|
288
|
+
let issue = result.issues[i];
|
|
189
289
|
let shouldCreateIssue = senditMode;
|
|
190
290
|
if (!senditMode) {
|
|
191
|
-
// Interactive confirmation for each issue
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
logger.info(`
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
291
|
+
// Interactive confirmation for each issue - keep looping until user decides
|
|
292
|
+
let userChoice = '';
|
|
293
|
+
while(userChoice !== 'c' && userChoice !== 's'){
|
|
294
|
+
// Display issue details
|
|
295
|
+
logger.info(`\n📋 Issue ${i + 1} of ${result.issues.length}:`);
|
|
296
|
+
logger.info(` Title: ${issue.title}`);
|
|
297
|
+
logger.info(` Priority: ${issue.priority} | Category: ${issue.category}`);
|
|
298
|
+
logger.info(` Description: ${issue.description}`);
|
|
299
|
+
if (issue.suggestions && issue.suggestions.length > 0) {
|
|
300
|
+
logger.info(` Suggestions: ${issue.suggestions.join(', ')}`);
|
|
301
|
+
}
|
|
302
|
+
// Get user choice
|
|
303
|
+
userChoice = await getUserChoice('\nWhat would you like to do with this issue?', [
|
|
304
|
+
{
|
|
305
|
+
key: 'c',
|
|
306
|
+
label: 'Create GitHub issue'
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
key: 's',
|
|
310
|
+
label: 'Skip this issue'
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
key: 'e',
|
|
314
|
+
label: 'Edit issue details'
|
|
315
|
+
}
|
|
316
|
+
]);
|
|
317
|
+
if (userChoice === 'c') {
|
|
318
|
+
shouldCreateIssue = true;
|
|
319
|
+
} else if (userChoice === 'e') {
|
|
320
|
+
// Allow user to edit the issue
|
|
321
|
+
issue = await editIssueInteractively(issue);
|
|
322
|
+
result.issues[i] = issue; // Update the issue in the result
|
|
323
|
+
// Continue the loop to show the updated issue and ask again
|
|
212
324
|
}
|
|
213
|
-
|
|
214
|
-
if (choice === 'c') {
|
|
215
|
-
shouldCreateIssue = true;
|
|
216
|
-
} else if (choice === 'e') {
|
|
217
|
-
// Allow user to edit the issue
|
|
218
|
-
const editedIssue = await editIssueInteractively(issue);
|
|
219
|
-
result.issues[i] = editedIssue;
|
|
220
|
-
shouldCreateIssue = true;
|
|
325
|
+
// If choice is 's', loop will exit and shouldCreateIssue remains false
|
|
221
326
|
}
|
|
222
|
-
// If choice is 's', shouldCreateIssue remains false
|
|
223
327
|
}
|
|
224
328
|
if (shouldCreateIssue) {
|
|
225
329
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issues.js","sources":["../../src/content/issues.ts"],"sourcesContent":["import { getLogger } from '../logging';\nimport { getOpenIssues, createIssue } from '../util/github';\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 const logger = getLogger();\n\n logger.info(prompt);\n choices.forEach(choice => {\n logger.info(` [${choice.key}] ${choice.label}`);\n });\n logger.info('');\n\n return new Promise(resolve => {\n // Ensure stdin is referenced so the process doesn't exit while waiting for input\n if (typeof process.stdin.ref === 'function') {\n process.stdin.ref();\n }\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on('data', (key) => {\n const keyStr = key.toString().toLowerCase();\n const choice = choices.find(c => c.key === keyStr);\n if (choice) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n // Detach stdin again now that we're done\n if (typeof process.stdin.unref === 'function') {\n process.stdin.unref();\n }\n logger.info(`Selected: ${choice.label}\\n`);\n resolve(choice.key);\n }\n });\n });\n}\n\n// Helper function to edit issue interactively\nasync function editIssueInteractively(issue: Issue): Promise<Issue> {\n const logger = getLogger();\n const readline = await import('readline');\n\n // Ensure stdin is referenced during readline interaction\n if (typeof process.stdin.ref === 'function') {\n process.stdin.ref();\n }\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n\n const question = (prompt: string): Promise<string> => {\n return new Promise(resolve => {\n rl.question(prompt, resolve);\n });\n };\n\n try {\n logger.info('📝 Edit issue details (press Enter to keep current value):');\n\n const newTitle = await question(`Title [${issue.title}]: `);\n const newDescription = await question(`Description [${issue.description}]: `);\n const newPriority = await question(`Priority (low/medium/high) [${issue.priority}]: `);\n const newCategory = await question(`Category (ui/content/functionality/accessibility/performance/other) [${issue.category}]: `);\n\n const updatedIssue: Issue = {\n title: newTitle.trim() || issue.title,\n description: newDescription.trim() || issue.description,\n priority: (newPriority.trim() as any) || issue.priority,\n category: (newCategory.trim() as any) || issue.category,\n suggestions: issue.suggestions\n };\n\n logger.info('✅ Issue updated successfully');\n return updatedIssue;\n } finally {\n rl.close();\n // Detach stdin after interactive edit completes\n if (typeof process.stdin.unref === 'function') {\n process.stdin.unref();\n }\n }\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 const issue = result.issues[i];\n let shouldCreateIssue = senditMode;\n\n if (!senditMode) {\n // Interactive confirmation for each issue\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 const choice = 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 (choice === 'c') {\n shouldCreateIssue = true;\n } else if (choice === 'e') {\n // Allow user to edit the issue\n const editedIssue = await editIssueInteractively(issue);\n result.issues[i] = editedIssue;\n shouldCreateIssue = true;\n }\n // If choice is 's', shouldCreateIssue remains false\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}; "],"names":["get","options","logger","getLogger","limit","debug","issuesLimit","Math","min","githubIssues","getOpenIssues","trim","length","error","warn","message","getUserChoice","prompt","choices","info","forEach","choice","key","label","Promise","resolve","process","stdin","ref","setRawMode","resume","on","keyStr","toString","toLowerCase","find","c","pause","unref","editIssueInteractively","issue","readline","rl","createInterface","input","output","stdout","question","newTitle","title","newDescription","description","newPriority","priority","newCategory","category","updatedIssue","suggestions","close","formatIssueBody","body","suggestion","formatReviewResultsWithIssues","result","createdIssues","summary","totalIssues","issues","index","priorityEmoji","categoryEmoji","createdIssue","ci","number","githubUrl","formatReviewResults","handleIssueCreation","senditMode","i","shouldCreateIssue","join","editedIssue","issueBody","labels","createIssue","push","html_url"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"issues.js","sources":["../../src/content/issues.ts"],"sourcesContent":["import { getLogger } from '../logging';\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 const logger = getLogger();\n\n logger.info(prompt);\n choices.forEach(choice => {\n logger.info(` [${choice.key}] ${choice.label}`);\n });\n logger.info('');\n\n // Check if stdin is a TTY (terminal) or piped\n if (!process.stdin.isTTY) {\n // STDIN is piped, we can't use interactive prompts\n // This should not happen anymore due to fail-fast check in review.ts\n logger.error('⚠️ Unexpected: STDIN is piped in interactive mode');\n return 's'; // Default to skip\n }\n\n return new Promise(resolve => {\n // Ensure stdin is referenced so the process doesn't exit while waiting for input\n if (typeof process.stdin.ref === 'function') {\n process.stdin.ref();\n }\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on('data', (key) => {\n const keyStr = key.toString().toLowerCase();\n const choice = choices.find(c => c.key === keyStr);\n if (choice) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n // Detach stdin again now that we're done\n if (typeof process.stdin.unref === 'function') {\n process.stdin.unref();\n }\n logger.info(`Selected: ${choice.label}\\n`);\n resolve(choice.key);\n }\n });\n });\n}\n\n// 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 (best-effort – ignore errors)\n try {\n await fs.unlink(tmpFilePath);\n } catch {\n /* ignore */\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}; "],"names":["get","options","logger","getLogger","limit","debug","issuesLimit","Math","min","githubIssues","getOpenIssues","trim","length","error","warn","message","getUserChoice","prompt","choices","info","forEach","choice","key","label","process","stdin","isTTY","Promise","resolve","ref","setRawMode","resume","on","keyStr","toString","toLowerCase","find","c","pause","unref","serializeIssue","issue","lines","title","priority","category","description","suggestions","suggestion","push","join","deserializeIssue","content","split","currentSection","descriptionLines","i","line","startsWith","substring","priorityValue","categoryValue","includes","suggestionLine","replace","undefined","editIssueInteractively","editor","env","EDITOR","VISUAL","tmpDir","os","tmpdir","tmpFilePath","path","Date","now","issueContent","fs","writeFile","result","spawnSync","stdio","Error","editedContent","readFile","unlink","editedIssue","JSON","stringify","formatIssueBody","body","formatReviewResultsWithIssues","createdIssues","output","summary","totalIssues","issues","index","priorityEmoji","categoryEmoji","createdIssue","ci","number","githubUrl","formatReviewResults","handleIssueCreation","senditMode","shouldCreateIssue","userChoice","issueBody","labels","createIssue","html_url"],"mappings":"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"}
|
package/dist/prompt/commit.js
CHANGED
|
@@ -41,7 +41,7 @@ const __dirname = path.dirname(__filename);
|
|
|
41
41
|
}
|
|
42
42
|
if (directories && directories.length > 0) {
|
|
43
43
|
contextItems.push({
|
|
44
|
-
|
|
44
|
+
directories,
|
|
45
45
|
title: 'Directories'
|
|
46
46
|
});
|
|
47
47
|
}
|
|
@@ -49,7 +49,7 @@ const __dirname = path.dirname(__filename);
|
|
|
49
49
|
path: 'personas/you.md'
|
|
50
50
|
}).instructions({
|
|
51
51
|
path: 'instructions/commit.md'
|
|
52
|
-
}).content(...contentItems).context(...contextItems).cook();
|
|
52
|
+
}).overridePaths(_overridePaths !== null && _overridePaths !== void 0 ? _overridePaths : []).overrides(_overrides !== null && _overrides !== void 0 ? _overrides : true).content(...contentItems).context(...contextItems).cook();
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
export { createPrompt };
|
|
@@ -1 +1 @@
|
|
|
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};\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 * @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 }: 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 if (userDirection) {\n contentItems.push({ content: userDirection, title: 'User Direction' });\n }\n if (diffContent) {\n contentItems.push({ content: diffContent, title: 'Diff' });\n }\n\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({
|
|
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};\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 * @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 }: 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 if (userDirection) {\n contentItems.push({ content: userDirection, title: 'User Direction' });\n }\n if (diffContent) {\n contentItems.push({ content: diffContent, title: 'Diff' });\n }\n\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}; "],"names":["__filename","fileURLToPath","url","__dirname","path","dirname","createPrompt","overridePaths","_overridePaths","overrides","_overrides","diffContent","userDirection","logContext","context","directories","basePath","contentItems","contextItems","push","content","title","length","recipe","persona","instructions","cook"],"mappings":";;;;AAIA,MAAMA,UAAAA,GAAaC,aAAAA,CAAc,MAAA,CAAA,IAAA,CAAYC,GAAG,CAAA;AAChD,MAAMC,SAAAA,GAAYC,IAAAA,CAAKC,OAAO,CAACL,UAAAA,CAAAA;AAmB/B;;;;;;IAOO,MAAMM,YAAAA,GAAe,OACxB,EAAEC,aAAAA,EAAeC,cAAc,EAAEC,SAAAA,EAAWC,UAAU,EAAU,EAChE,EAAEC,WAAW,EAAEC,aAAa,EAAW,EACvC,EAAEC,UAAU,EAAEC,OAAO,EAAEC,WAAW,EAAW,GAAG,EAAE,GAAA;AAElD,IAAA,MAAMC,QAAAA,GAAWb,SAAAA;;AAGjB,IAAA,MAAMc,eAAe,EAAE;AACvB,IAAA,MAAMC,eAAe,EAAE;AAEvB,IAAA,IAAIN,aAAAA,EAAe;AACfK,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAASR,aAAAA;YAAeS,KAAAA,EAAO;AAAiB,SAAA,CAAA;AACxE,IAAA;AACA,IAAA,IAAIV,WAAAA,EAAa;AACbM,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAAST,WAAAA;YAAaU,KAAAA,EAAO;AAAO,SAAA,CAAA;AAC5D,IAAA;AAEA,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,CAAYO,MAAM,GAAG,CAAA,EAAG;AACvCJ,QAAAA,YAAAA,CAAaC,IAAI,CAAC;AAAEJ,YAAAA,WAAAA;YAAaM,KAAAA,EAAO;AAAc,SAAA,CAAA;AAC1D,IAAA;IAEA,OAAOE,MAAAA,CAAOP,QAAAA,CAAAA,CACTQ,OAAO,CAAC;QAAEpB,IAAAA,EAAM;AAAkB,KAAA,CAAA,CAClCqB,YAAY,CAAC;QAAErB,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,MACxBU,OAAO,CAAA,GAAIH,cACXH,OAAO,CAAA,GAAII,cACXQ,IAAI,EAAA;AACb;;;;"}
|
|
@@ -66,6 +66,19 @@ You **MUST** respond with valid JSON in this exact format:
|
|
|
66
66
|
* Return `"totalIssues": 0` and `"issues": []`
|
|
67
67
|
* Do NOT generate issues from context alone when no review feedback is provided
|
|
68
68
|
|
|
69
|
+
**Important Philosophy:**
|
|
70
|
+
* **If someone took the time to provide a review, there's likely something valuable in it**
|
|
71
|
+
* **Err on the side of inclusion** — capture suggestions, comments, and observations as issues
|
|
72
|
+
* **Even subjective feedback can be valuable** — preferences and opinions often highlight real user experience concerns
|
|
73
|
+
* **Transform general commentary into actionable items** where possible
|
|
74
|
+
|
|
75
|
+
**Handling Detailed/Lengthy Feedback:**
|
|
76
|
+
* **Long transcripts and reviews are gold mines** — if someone recorded a 10-minute note or wrote extensive feedback, there's substantial value to capture
|
|
77
|
+
* **Don't just summarize — dive deep** — extract the full richness of detailed feedback into comprehensive issue descriptions
|
|
78
|
+
* **Capture context, reasoning, and nuances** — lengthy feedback often contains important context about why something matters
|
|
79
|
+
* **Break down complex feedback** — one long review might generate multiple detailed issues covering different aspects
|
|
80
|
+
* **Preserve the reviewer's voice** — maintain the specific language and examples they provided when possible
|
|
81
|
+
|
|
69
82
|
**Avoiding Duplicate Issues:**
|
|
70
83
|
* **CRITICALLY IMPORTANT**: If the User Context includes open GitHub issues, review them carefully
|
|
71
84
|
* Do NOT create new issues for problems that are already documented in existing issues
|
|
@@ -77,19 +90,21 @@ You **MUST** respond with valid JSON in this exact format:
|
|
|
77
90
|
|
|
78
91
|
## ✅ DO:
|
|
79
92
|
|
|
80
|
-
* **Extract
|
|
93
|
+
* **Extract ALL meaningful feedback** from the review notes, including suggestions and comments
|
|
81
94
|
* **Leverage User Context** to provide informed analysis and avoid duplicates
|
|
82
|
-
* **
|
|
95
|
+
* **Transform general observations into actionable items** whenever possible
|
|
96
|
+
* **Capture subjective preferences** as low-priority issues when they could improve user experience
|
|
83
97
|
* **Use appropriate categories and priorities** based on impact and context
|
|
84
|
-
* **
|
|
98
|
+
* **Include suggestions, comments, and observations** as valid issues
|
|
99
|
+
* **Provide clear, implementable suggestions** for fixes that consider the current project state
|
|
85
100
|
* **Include enough detail** in descriptions for developers to understand the issue
|
|
86
101
|
|
|
87
102
|
## ❌ DO NOT:
|
|
88
103
|
|
|
89
|
-
* ❌
|
|
90
|
-
* ❌
|
|
104
|
+
* ❌ Dismiss feedback as too vague without attempting to make it actionable
|
|
105
|
+
* ❌ Ignore suggestions or comments that could be valuable improvements
|
|
106
|
+
* ❌ Create issues for problems already documented in existing GitHub issues
|
|
91
107
|
* ❌ Ignore the User Context when analyzing review notes
|
|
92
|
-
* ❌ Include commentary that doesn't translate to specific improvements
|
|
93
108
|
* ❌ Use any format other than the required JSON structure
|
|
94
109
|
|
|
95
110
|
---
|
|
@@ -98,11 +113,13 @@ You **MUST** respond with valid JSON in this exact format:
|
|
|
98
113
|
|
|
99
114
|
Prioritize feedback that relates to:
|
|
100
115
|
|
|
101
|
-
* User experience problems
|
|
116
|
+
* User experience problems and suggestions
|
|
102
117
|
* Functional issues or bugs
|
|
103
118
|
* Accessibility concerns
|
|
104
119
|
* Performance problems
|
|
105
120
|
* Content clarity or accuracy
|
|
106
|
-
* Visual design issues
|
|
121
|
+
* Visual design issues and improvements
|
|
122
|
+
* General suggestions for enhancement
|
|
123
|
+
* Subjective preferences that could improve usability
|
|
107
124
|
|
|
108
|
-
Remember: Your goal is to help the development team understand what specific actions they can take to improve the project based on the review feedback, informed by the current project context.
|
|
125
|
+
Remember: Your goal is to help the development team understand what specific actions they can take to improve the project based on ALL the review feedback, informed by the current project context. **If someone provided feedback, there's likely something worth capturing as an issue.**
|
package/dist/prompt/release.js
CHANGED
|
@@ -37,7 +37,7 @@ const __dirname = path.dirname(__filename);
|
|
|
37
37
|
}
|
|
38
38
|
if (directories && directories.length > 0) {
|
|
39
39
|
contextItems.push({
|
|
40
|
-
|
|
40
|
+
directories,
|
|
41
41
|
title: 'Directories'
|
|
42
42
|
});
|
|
43
43
|
}
|
|
@@ -45,7 +45,7 @@ const __dirname = path.dirname(__filename);
|
|
|
45
45
|
path: 'personas/releaser.md'
|
|
46
46
|
}).instructions({
|
|
47
47
|
path: 'instructions/release.md'
|
|
48
|
-
}).content(...contentItems).context(...contextItems).cook();
|
|
48
|
+
}).overridePaths(_overridePaths !== null && _overridePaths !== void 0 ? _overridePaths : []).overrides(_overrides !== null && _overrides !== void 0 ? _overrides : true).content(...contentItems).context(...contextItems).cook();
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
export { createPrompt };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release.js","sources":["../../src/prompt/release.ts"],"sourcesContent":["import { ContentItem, 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 release prompt\nexport type Config = {\n overridePaths?: string[];\n overrides?: boolean;\n}\n\nexport type Content = {\n releaseFocus?: string;\n logContent: string;\n diffContent: string;\n};\n\nexport type Context = {\n context?: string;\n directories?: string[];\n};\n\n/**\n * Build a release prompt using RiotPrompt Recipes.\n */\nexport const createPrompt = async (\n { overrides: _overrides, overridePaths: _overridePaths }: Config,\n { releaseFocus, logContent, diffContent }: Content,\n { context, directories }: Context = {}\n): Promise<Prompt> => {\n const basePath = __dirname;\n\n // Build content items for the prompt\n const contentItems: ContentItem[] = [];\n const contextItems: ContentItem[] = [];\n\n if (diffContent) {\n contentItems.push({ content: diffContent, title: 'Diff' });\n }\n if (logContent) {\n contentItems.push({ content: logContent, title: 'Log Context' });\n }\n if (releaseFocus) {\n contentItems.push({ content: releaseFocus, title: 'Release Focus' });\n }\n\n if (context) {\n contextItems.push({ content: context, title: 'User Context' });\n }\n if (directories && directories.length > 0) {\n contextItems.push({
|
|
1
|
+
{"version":3,"file":"release.js","sources":["../../src/prompt/release.ts"],"sourcesContent":["import { ContentItem, 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 release prompt\nexport type Config = {\n overridePaths?: string[];\n overrides?: boolean;\n}\n\nexport type Content = {\n releaseFocus?: string;\n logContent: string;\n diffContent: string;\n};\n\nexport type Context = {\n context?: string;\n directories?: string[];\n};\n\n/**\n * Build a release prompt using RiotPrompt Recipes.\n */\nexport const createPrompt = async (\n { overrides: _overrides, overridePaths: _overridePaths }: Config,\n { releaseFocus, logContent, diffContent }: Content,\n { context, directories }: Context = {}\n): Promise<Prompt> => {\n const basePath = __dirname;\n\n // Build content items for the prompt\n const contentItems: ContentItem[] = [];\n const contextItems: ContentItem[] = [];\n\n if (diffContent) {\n contentItems.push({ content: diffContent, title: 'Diff' });\n }\n if (logContent) {\n contentItems.push({ content: logContent, title: 'Log Context' });\n }\n if (releaseFocus) {\n contentItems.push({ content: releaseFocus, title: 'Release Focus' });\n }\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\n\n\n return recipe(basePath)\n .persona({ path: 'personas/releaser.md' })\n .instructions({ path: 'instructions/release.md' })\n .overridePaths(_overridePaths ?? [])\n .overrides(_overrides ?? true)\n .content(...contentItems)\n .context(...contextItems)\n .cook();\n}; "],"names":["__filename","fileURLToPath","url","__dirname","path","dirname","createPrompt","overrides","_overrides","overridePaths","_overridePaths","releaseFocus","logContent","diffContent","context","directories","basePath","contentItems","contextItems","push","content","title","length","recipe","persona","instructions","cook"],"mappings":";;;;AAIA,MAAMA,UAAAA,GAAaC,aAAAA,CAAc,MAAA,CAAA,IAAA,CAAYC,GAAG,CAAA;AAChD,MAAMC,SAAAA,GAAYC,IAAAA,CAAKC,OAAO,CAACL,UAAAA,CAAAA;AAmB/B;;IAGO,MAAMM,YAAAA,GAAe,OACxB,EAAEC,SAAAA,EAAWC,UAAU,EAAEC,aAAAA,EAAeC,cAAc,EAAU,EAChE,EAAEC,YAAY,EAAEC,UAAU,EAAEC,WAAW,EAAW,EAClD,EAAEC,OAAO,EAAEC,WAAW,EAAW,GAAG,EAAE,GAAA;AAEtC,IAAA,MAAMC,QAAAA,GAAWb,SAAAA;;AAGjB,IAAA,MAAMc,eAA8B,EAAE;AACtC,IAAA,MAAMC,eAA8B,EAAE;AAEtC,IAAA,IAAIL,WAAAA,EAAa;AACbI,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAASP,WAAAA;YAAaQ,KAAAA,EAAO;AAAO,SAAA,CAAA;AAC5D,IAAA;AACA,IAAA,IAAIT,UAAAA,EAAY;AACZK,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAASR,UAAAA;YAAYS,KAAAA,EAAO;AAAc,SAAA,CAAA;AAClE,IAAA;AACA,IAAA,IAAIV,YAAAA,EAAc;AACdM,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAAST,YAAAA;YAAcU,KAAAA,EAAO;AAAgB,SAAA,CAAA;AACtE,IAAA;AAEA,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,CAAYO,MAAM,GAAG,CAAA,EAAG;AACvCJ,QAAAA,YAAAA,CAAaC,IAAI,CAAC;AAAEJ,YAAAA,WAAAA;YAAaM,KAAAA,EAAO;AAAc,SAAA,CAAA;AAC1D,IAAA;IAKA,OAAOE,MAAAA,CAAOP,QAAAA,CAAAA,CACTQ,OAAO,CAAC;QAAEpB,IAAAA,EAAM;AAAuB,KAAA,CAAA,CACvCqB,YAAY,CAAC;QAAErB,IAAAA,EAAM;AAA0B,KAAA,CAAA,CAC/CK,aAAa,CAACC,cAAAA,KAAAA,IAAAA,IAAAA,4BAAAA,cAAAA,GAAkB,EAAE,EAClCH,SAAS,CAACC,uBAAAA,UAAAA,KAAAA,MAAAA,GAAAA,UAAAA,GAAc,MACxBY,OAAO,CAAA,GAAIH,cACXH,OAAO,CAAA,GAAII,cACXQ,IAAI,EAAA;AACb;;;;"}
|