claude-gh-ticket-gen 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +406 -0
- package/bin/claude-ticket-gen.js +6 -0
- package/dist/cli/commands/config.d.ts +8 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +84 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +9 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +243 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +8 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +160 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +54 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ui.d.ts +38 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +148 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/core/config-manager.d.ts +48 -0
- package/dist/core/config-manager.d.ts.map +1 -0
- package/dist/core/config-manager.js +165 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/duplicate-detector.d.ts +13 -0
- package/dist/core/duplicate-detector.d.ts.map +1 -0
- package/dist/core/duplicate-detector.js +123 -0
- package/dist/core/duplicate-detector.js.map +1 -0
- package/dist/core/github.d.ts +46 -0
- package/dist/core/github.d.ts.map +1 -0
- package/dist/core/github.js +187 -0
- package/dist/core/github.js.map +1 -0
- package/dist/core/parser.d.ts +17 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +177 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/types.d.ts +89 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +28 -0
- package/dist/core/types.js.map +1 -0
- package/dist/templates/issue-template.d.ts +17 -0
- package/dist/templates/issue-template.d.ts.map +1 -0
- package/dist/templates/issue-template.js +87 -0
- package/dist/templates/issue-template.js.map +1 -0
- package/dist/templates/parsing-prompt.d.ts +5 -0
- package/dist/templates/parsing-prompt.d.ts.map +1 -0
- package/dist/templates/parsing-prompt.js +70 -0
- package/dist/templates/parsing-prompt.js.map +1 -0
- package/dist/utils/logger.d.ts +69 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +136 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validators.d.ts +45 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +80 -0
- package/dist/utils/validators.js.map +1 -0
- package/examples/ROADMAP.example.md +84 -0
- package/examples/config.example.json +22 -0
- package/package.json +54 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub CLI integration wrapper
|
|
3
|
+
*/
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import { generateIssueBody, generateLabels } from '../templates/issue-template.js';
|
|
6
|
+
/**
|
|
7
|
+
* Check if gh CLI is installed
|
|
8
|
+
*/
|
|
9
|
+
export function checkGhInstalled() {
|
|
10
|
+
try {
|
|
11
|
+
execSync('gh --version', { stdio: 'ignore' });
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get current repository from git remote
|
|
20
|
+
*/
|
|
21
|
+
export function getCurrentRepo() {
|
|
22
|
+
try {
|
|
23
|
+
const output = execSync('gh repo view --json nameWithOwner --jq .nameWithOwner', {
|
|
24
|
+
encoding: 'utf-8',
|
|
25
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
26
|
+
});
|
|
27
|
+
return output.trim();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Search for existing issues by keywords
|
|
35
|
+
*/
|
|
36
|
+
export async function searchIssues(keywords, repo) {
|
|
37
|
+
try {
|
|
38
|
+
const query = keywords.split(' ').slice(0, 5).join(' ');
|
|
39
|
+
const command = `gh issue list --repo ${repo} --search "${query}" --json number,title,state --limit 10`;
|
|
40
|
+
const output = execSync(command, {
|
|
41
|
+
encoding: 'utf-8',
|
|
42
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
43
|
+
});
|
|
44
|
+
return JSON.parse(output);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create a new GitHub issue
|
|
52
|
+
*/
|
|
53
|
+
export async function createIssue(task, repo, dryRun = false) {
|
|
54
|
+
try {
|
|
55
|
+
const body = generateIssueBody(task);
|
|
56
|
+
const labels = generateLabels(task);
|
|
57
|
+
if (dryRun) {
|
|
58
|
+
return {
|
|
59
|
+
success: true,
|
|
60
|
+
issueNumber: 0,
|
|
61
|
+
url: `(dry-run) Would create issue: ${task.title}`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Get existing labels to filter out non-existent ones
|
|
65
|
+
const existingLabels = await listLabels(repo);
|
|
66
|
+
const existingLabelNames = new Set(existingLabels.map(l => l.name.toLowerCase()));
|
|
67
|
+
// Filter to only use labels that exist
|
|
68
|
+
const validLabels = labels.filter(label => existingLabelNames.has(label.toLowerCase()));
|
|
69
|
+
// Escape title for shell (single quotes to avoid escaping issues)
|
|
70
|
+
const escapedTitle = task.title.replace(/'/g, "'\\''");
|
|
71
|
+
// Create issue with valid labels only, using stdin for body to preserve newlines
|
|
72
|
+
let command = `gh issue create --repo ${repo} --title '${escapedTitle}' --body-file -`;
|
|
73
|
+
if (validLabels.length > 0) {
|
|
74
|
+
const labelString = validLabels.join(',');
|
|
75
|
+
command += ` --label "${labelString}"`;
|
|
76
|
+
}
|
|
77
|
+
const output = execSync(command, {
|
|
78
|
+
input: body,
|
|
79
|
+
encoding: 'utf-8',
|
|
80
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
81
|
+
});
|
|
82
|
+
// Extract issue URL from output
|
|
83
|
+
const url = output.trim();
|
|
84
|
+
const issueNumber = extractIssueNumber(url);
|
|
85
|
+
return {
|
|
86
|
+
success: true,
|
|
87
|
+
issueNumber,
|
|
88
|
+
url,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return {
|
|
93
|
+
success: false,
|
|
94
|
+
error: error.message,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Extract issue number from GitHub URL
|
|
100
|
+
*/
|
|
101
|
+
function extractIssueNumber(url) {
|
|
102
|
+
const match = url.match(/\/issues\/(\d+)/);
|
|
103
|
+
return match ? parseInt(match[1], 10) : undefined;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create a label if it doesn't exist
|
|
107
|
+
*/
|
|
108
|
+
export async function createLabel(name, color, repo) {
|
|
109
|
+
try {
|
|
110
|
+
// Check if label exists first
|
|
111
|
+
const existingLabels = await listLabels(repo);
|
|
112
|
+
if (existingLabels.some((label) => label.name === name)) {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
// Create label
|
|
116
|
+
execSync(`gh label create "${name}" --color ${color} --repo ${repo}`, {
|
|
117
|
+
stdio: 'ignore',
|
|
118
|
+
});
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* List all repository labels
|
|
127
|
+
*/
|
|
128
|
+
export async function listLabels(repo) {
|
|
129
|
+
try {
|
|
130
|
+
const output = execSync(`gh label list --repo ${repo} --json name,color --limit 100`, {
|
|
131
|
+
encoding: 'utf-8',
|
|
132
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
133
|
+
});
|
|
134
|
+
return JSON.parse(output);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Ensure required labels exist in the repository
|
|
142
|
+
*/
|
|
143
|
+
export async function ensureLabelsExist(repo, labelColors) {
|
|
144
|
+
const labels = [
|
|
145
|
+
{ name: 'priority-critical', color: labelColors['priority-critical'] || 'B60205' },
|
|
146
|
+
{ name: 'priority-high', color: labelColors['priority-high'] || 'D93F0B' },
|
|
147
|
+
{ name: 'priority-medium', color: labelColors['priority-medium'] || 'FBCA04' },
|
|
148
|
+
{ name: 'priority-low', color: labelColors['priority-low'] || '0E8A16' },
|
|
149
|
+
{ name: 'type-feature', color: labelColors['type-feature'] || '0075CA' },
|
|
150
|
+
{ name: 'type-bug', color: labelColors['type-bug'] || 'D73A4A' },
|
|
151
|
+
{ name: 'type-tech-debt', color: labelColors['type-tech-debt'] || 'F9D0C4' },
|
|
152
|
+
{ name: 'type-documentation', color: labelColors['type-documentation'] || '0E8A16' },
|
|
153
|
+
{ name: 'optional', color: labelColors['optional'] || 'E4E669' },
|
|
154
|
+
];
|
|
155
|
+
for (const label of labels) {
|
|
156
|
+
await createLabel(label.name, label.color, repo);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Create custom labels from tasks
|
|
161
|
+
*/
|
|
162
|
+
export async function ensureCustomLabels(tasks, repo, defaultColor = '0E8A16') {
|
|
163
|
+
// Collect all unique custom labels from tasks
|
|
164
|
+
const customLabels = new Set();
|
|
165
|
+
for (const task of tasks) {
|
|
166
|
+
for (const label of task.labels) {
|
|
167
|
+
customLabels.add(label);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Create each custom label
|
|
171
|
+
for (const label of customLabels) {
|
|
172
|
+
await createLabel(label, defaultColor, repo);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Check if user is authenticated with gh CLI
|
|
177
|
+
*/
|
|
178
|
+
export function checkGhAuth() {
|
|
179
|
+
try {
|
|
180
|
+
execSync('gh auth status', { stdio: 'ignore' });
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/core/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI-powered document parser using Claude API
|
|
3
|
+
*/
|
|
4
|
+
import { ParsedTask } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Parse a document file and extract structured tasks
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseDocument(filePath: string): Promise<ParsedTask[]>;
|
|
9
|
+
/**
|
|
10
|
+
* Parse document content and extract structured tasks
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseDocumentContent(content: string): Promise<ParsedTask[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Retry logic for API calls
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseWithRetry(filePath: string, maxRetries?: number): Promise<ParsedTask[]>;
|
|
17
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIxC;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAG3E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAsDjF;AA0GD;;GAEG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAAU,GACrB,OAAO,CAAC,UAAU,EAAE,CAAC,CAuBvB"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI-powered document parser using Claude API
|
|
3
|
+
*/
|
|
4
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
5
|
+
import { readFileSync } from 'fs';
|
|
6
|
+
import { getParsingPrompt } from '../templates/parsing-prompt.js';
|
|
7
|
+
import { loadConfig } from './config-manager.js';
|
|
8
|
+
/**
|
|
9
|
+
* Parse a document file and extract structured tasks
|
|
10
|
+
*/
|
|
11
|
+
export async function parseDocument(filePath) {
|
|
12
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
13
|
+
return parseDocumentContent(content);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parse document content and extract structured tasks
|
|
17
|
+
*/
|
|
18
|
+
export async function parseDocumentContent(content) {
|
|
19
|
+
const config = loadConfig();
|
|
20
|
+
if (!config.anthropicApiKey) {
|
|
21
|
+
throw new Error('Anthropic API key not configured. Set it with: claude-ticket-gen config set anthropicApiKey <key>');
|
|
22
|
+
}
|
|
23
|
+
const client = new Anthropic({
|
|
24
|
+
apiKey: config.anthropicApiKey,
|
|
25
|
+
});
|
|
26
|
+
const prompt = getParsingPrompt(content);
|
|
27
|
+
try {
|
|
28
|
+
const response = await client.messages.create({
|
|
29
|
+
model: 'claude-sonnet-4-20250514',
|
|
30
|
+
max_tokens: 8192,
|
|
31
|
+
messages: [
|
|
32
|
+
{
|
|
33
|
+
role: 'user',
|
|
34
|
+
content: prompt,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
// Extract text from response
|
|
39
|
+
const textContent = response.content.find((block) => block.type === 'text');
|
|
40
|
+
if (!textContent || textContent.type !== 'text') {
|
|
41
|
+
throw new Error('No text content in API response');
|
|
42
|
+
}
|
|
43
|
+
const responseText = textContent.text.trim();
|
|
44
|
+
// Check if response was truncated
|
|
45
|
+
if (response.stop_reason === 'max_tokens') {
|
|
46
|
+
throw new Error('Response was truncated due to length limits. ' +
|
|
47
|
+
'Try: 1) Using --filter-phase to process sections separately, or ' +
|
|
48
|
+
'2) Breaking document into smaller files');
|
|
49
|
+
}
|
|
50
|
+
// Parse JSON response
|
|
51
|
+
const tasks = parseTasksFromResponse(responseText);
|
|
52
|
+
return tasks;
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error instanceof Anthropic.APIError) {
|
|
56
|
+
throw new Error(`Claude API error: ${error.message}`);
|
|
57
|
+
}
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Parse tasks from API response text
|
|
63
|
+
*/
|
|
64
|
+
function parseTasksFromResponse(responseText) {
|
|
65
|
+
let jsonText = responseText.trim();
|
|
66
|
+
// Remove markdown code blocks - find content between ``` markers
|
|
67
|
+
if (jsonText.includes('```')) {
|
|
68
|
+
// Find the first [ and last ] which should be the JSON array
|
|
69
|
+
const firstBracket = jsonText.indexOf('[');
|
|
70
|
+
const lastBracket = jsonText.lastIndexOf(']');
|
|
71
|
+
if (firstBracket !== -1 && lastBracket !== -1 && lastBracket > firstBracket) {
|
|
72
|
+
jsonText = jsonText.substring(firstBracket, lastBracket + 1);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(jsonText);
|
|
77
|
+
// Validate it's an array
|
|
78
|
+
if (!Array.isArray(parsed)) {
|
|
79
|
+
throw new Error('Response is not an array');
|
|
80
|
+
}
|
|
81
|
+
// Validate and sanitize each task
|
|
82
|
+
return parsed.map((task, index) => validateAndSanitizeTask(task, index));
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
// Try to salvage incomplete JSON by finding last complete object
|
|
86
|
+
if (error.message.includes('Unterminated string') ||
|
|
87
|
+
error.message.includes('Unexpected end')) {
|
|
88
|
+
try {
|
|
89
|
+
// Find the last complete object by looking for the last },
|
|
90
|
+
const lastComplete = jsonText.lastIndexOf('},');
|
|
91
|
+
if (lastComplete !== -1) {
|
|
92
|
+
const salvaged = jsonText.substring(0, lastComplete + 1) + '\n]';
|
|
93
|
+
const parsed = JSON.parse(salvaged);
|
|
94
|
+
if (Array.isArray(parsed) && parsed.length > 0) {
|
|
95
|
+
console.warn(`Warning: Response was incomplete. Parsed ${parsed.length} tasks (some may be missing)`);
|
|
96
|
+
return parsed.map((task, index) => validateAndSanitizeTask(task, index));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// Salvage attempt failed, fall through to original error
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Include useful debugging info
|
|
105
|
+
const sample = jsonText.substring(0, 200);
|
|
106
|
+
const ending = jsonText.length > 200 ? jsonText.substring(jsonText.length - 200) : '';
|
|
107
|
+
throw new Error(`Failed to parse tasks from response: ${error.message}\n` +
|
|
108
|
+
`Response length: ${jsonText.length} characters\n` +
|
|
109
|
+
`Start: ${sample}...\n` +
|
|
110
|
+
`End: ...${ending}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Validate and sanitize a task object
|
|
115
|
+
*/
|
|
116
|
+
function validateAndSanitizeTask(task, index) {
|
|
117
|
+
// Required fields
|
|
118
|
+
if (!task.title || typeof task.title !== 'string') {
|
|
119
|
+
throw new Error(`Task ${index}: missing or invalid title`);
|
|
120
|
+
}
|
|
121
|
+
// Ensure all required fields exist with defaults
|
|
122
|
+
return {
|
|
123
|
+
title: task.title.trim(),
|
|
124
|
+
description: (task.description || '').trim(),
|
|
125
|
+
phase: task.phase || null,
|
|
126
|
+
priority: validatePriority(task.priority) ? task.priority : 'P2',
|
|
127
|
+
labels: Array.isArray(task.labels) ? task.labels : [],
|
|
128
|
+
isCompleted: Boolean(task.isCompleted),
|
|
129
|
+
isOptional: Boolean(task.isOptional),
|
|
130
|
+
type: validateType(task.type) ? task.type : 'feature',
|
|
131
|
+
subTasks: Array.isArray(task.subTasks) ? task.subTasks : undefined,
|
|
132
|
+
metadata: {
|
|
133
|
+
milestone: task.metadata?.milestone || undefined,
|
|
134
|
+
target: task.metadata?.target || undefined,
|
|
135
|
+
dependencies: Array.isArray(task.metadata?.dependencies)
|
|
136
|
+
? task.metadata.dependencies
|
|
137
|
+
: undefined,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Validate priority value
|
|
143
|
+
*/
|
|
144
|
+
function validatePriority(priority) {
|
|
145
|
+
return ['P0', 'P1', 'P2', 'P3'].includes(priority);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Validate type value
|
|
149
|
+
*/
|
|
150
|
+
function validateType(type) {
|
|
151
|
+
return ['feature', 'bug', 'tech-debt', 'documentation'].includes(type);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Retry logic for API calls
|
|
155
|
+
*/
|
|
156
|
+
export async function parseWithRetry(filePath, maxRetries = 3) {
|
|
157
|
+
let lastError = null;
|
|
158
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
159
|
+
try {
|
|
160
|
+
return await parseDocument(filePath);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
lastError = error;
|
|
164
|
+
// Don't retry on client errors (invalid API key, etc.)
|
|
165
|
+
if (error instanceof Anthropic.APIError && error.status && error.status < 500) {
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
// Wait before retry (exponential backoff)
|
|
169
|
+
if (attempt < maxRetries) {
|
|
170
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
171
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
throw lastError || new Error('Parse failed after retries');
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for the Claude Ticket Generator
|
|
3
|
+
*/
|
|
4
|
+
export type Priority = 'P0' | 'P1' | 'P2' | 'P3';
|
|
5
|
+
export type TaskType = 'feature' | 'bug' | 'tech-debt' | 'documentation';
|
|
6
|
+
export type TaskStatus = 'todo' | 'in-progress' | 'completed';
|
|
7
|
+
/**
|
|
8
|
+
* Parsed task from document analysis
|
|
9
|
+
*/
|
|
10
|
+
export interface ParsedTask {
|
|
11
|
+
title: string;
|
|
12
|
+
description: string;
|
|
13
|
+
phase?: string;
|
|
14
|
+
priority: Priority;
|
|
15
|
+
labels: string[];
|
|
16
|
+
isCompleted: boolean;
|
|
17
|
+
isOptional: boolean;
|
|
18
|
+
type: TaskType;
|
|
19
|
+
subTasks?: string[];
|
|
20
|
+
metadata: {
|
|
21
|
+
milestone?: string;
|
|
22
|
+
target?: string;
|
|
23
|
+
dependencies?: string[];
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Configuration schema
|
|
28
|
+
*/
|
|
29
|
+
export interface Config {
|
|
30
|
+
anthropicApiKey?: string;
|
|
31
|
+
defaultRepo?: string;
|
|
32
|
+
defaultDocPath?: string;
|
|
33
|
+
preferences: {
|
|
34
|
+
dryRunByDefault: boolean;
|
|
35
|
+
autoCreateLabels: boolean;
|
|
36
|
+
checkDuplicates: boolean;
|
|
37
|
+
duplicateThreshold: number;
|
|
38
|
+
};
|
|
39
|
+
labelColors: {
|
|
40
|
+
[key: string]: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Default configuration values
|
|
45
|
+
*/
|
|
46
|
+
export declare const DEFAULT_CONFIG: Config;
|
|
47
|
+
/**
|
|
48
|
+
* GitHub issue creation result
|
|
49
|
+
*/
|
|
50
|
+
export interface IssueCreationResult {
|
|
51
|
+
success: boolean;
|
|
52
|
+
issueNumber?: number;
|
|
53
|
+
url?: string;
|
|
54
|
+
error?: string;
|
|
55
|
+
isDuplicate?: boolean;
|
|
56
|
+
duplicateIssueNumber?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Duplicate detection result
|
|
60
|
+
*/
|
|
61
|
+
export interface DuplicateCheckResult {
|
|
62
|
+
isDuplicate: boolean;
|
|
63
|
+
existingIssueNumber?: number;
|
|
64
|
+
existingIssueTitle?: string;
|
|
65
|
+
similarityScore?: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Generate command options
|
|
69
|
+
*/
|
|
70
|
+
export interface GenerateOptions {
|
|
71
|
+
repo?: string;
|
|
72
|
+
dryRun?: boolean;
|
|
73
|
+
filterPhase?: string;
|
|
74
|
+
minPriority?: Priority;
|
|
75
|
+
includeOptional?: boolean;
|
|
76
|
+
config?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Summary statistics for generation run
|
|
80
|
+
*/
|
|
81
|
+
export interface GenerationSummary {
|
|
82
|
+
totalTasks: number;
|
|
83
|
+
filteredTasks: number;
|
|
84
|
+
created: number;
|
|
85
|
+
skipped: number;
|
|
86
|
+
duplicates: number;
|
|
87
|
+
errors: number;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACjD,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,WAAW,GAAG,eAAe,CAAC;AACzE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE;QACR,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE;QACX,eAAe,EAAE,OAAO,CAAC;QACzB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,eAAe,EAAE,OAAO,CAAC;QACzB,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,WAAW,EAAE;QACX,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;CACH;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MAoB5B,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for the Claude Ticket Generator
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Default configuration values
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_CONFIG = {
|
|
8
|
+
anthropicApiKey: undefined,
|
|
9
|
+
defaultRepo: undefined,
|
|
10
|
+
defaultDocPath: 'ROADMAP.md',
|
|
11
|
+
preferences: {
|
|
12
|
+
dryRunByDefault: false,
|
|
13
|
+
autoCreateLabels: true,
|
|
14
|
+
checkDuplicates: true,
|
|
15
|
+
duplicateThreshold: 0.8,
|
|
16
|
+
},
|
|
17
|
+
labelColors: {
|
|
18
|
+
'priority-critical': 'B60205',
|
|
19
|
+
'priority-high': 'D93F0B',
|
|
20
|
+
'priority-medium': 'FBCA04',
|
|
21
|
+
'priority-low': '0E8A16',
|
|
22
|
+
'type-feature': '0075CA',
|
|
23
|
+
'type-bug': 'D73A4A',
|
|
24
|
+
'type-tech-debt': 'F9D0C4',
|
|
25
|
+
'type-documentation': '0E8A16',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4CH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAW;IACpC,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,SAAS;IACtB,cAAc,EAAE,YAAY;IAC5B,WAAW,EAAE;QACX,eAAe,EAAE,KAAK;QACtB,gBAAgB,EAAE,IAAI;QACtB,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,GAAG;KACxB;IACD,WAAW,EAAE;QACX,mBAAmB,EAAE,QAAQ;QAC7B,eAAe,EAAE,QAAQ;QACzB,iBAAiB,EAAE,QAAQ;QAC3B,cAAc,EAAE,QAAQ;QACxB,cAAc,EAAE,QAAQ;QACxB,UAAU,EAAE,QAAQ;QACpB,gBAAgB,EAAE,QAAQ;QAC1B,oBAAoB,EAAE,QAAQ;KAC/B;CACF,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub issue body template
|
|
3
|
+
*/
|
|
4
|
+
import { ParsedTask } from '../core/types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate issue body from task
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateIssueBody(task: ParsedTask): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generate title with optional prefix
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateIssueTitle(task: ParsedTask): string;
|
|
13
|
+
/**
|
|
14
|
+
* Generate labels array from task
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateLabels(task: ParsedTask): string[];
|
|
17
|
+
//# sourceMappingURL=issue-template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-template.d.ts","sourceRoot":"","sources":["../../src/templates/issue-template.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAkD1D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAG3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,CAezD"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub issue body template
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Generate issue body from task
|
|
6
|
+
*/
|
|
7
|
+
export function generateIssueBody(task) {
|
|
8
|
+
const sections = [];
|
|
9
|
+
// Description
|
|
10
|
+
if (task.description) {
|
|
11
|
+
sections.push(task.description);
|
|
12
|
+
sections.push('');
|
|
13
|
+
}
|
|
14
|
+
// Metadata section
|
|
15
|
+
const metadata = [];
|
|
16
|
+
if (task.phase) {
|
|
17
|
+
metadata.push(`**Phase:** ${task.phase}`);
|
|
18
|
+
}
|
|
19
|
+
if (task.metadata.milestone) {
|
|
20
|
+
metadata.push(`**Milestone:** ${task.metadata.milestone}`);
|
|
21
|
+
}
|
|
22
|
+
if (task.metadata.target) {
|
|
23
|
+
metadata.push(`**Target:** ${task.metadata.target}`);
|
|
24
|
+
}
|
|
25
|
+
if (task.metadata.dependencies && task.metadata.dependencies.length > 0) {
|
|
26
|
+
metadata.push(`**Dependencies:** ${task.metadata.dependencies.join(', ')}`);
|
|
27
|
+
}
|
|
28
|
+
if (metadata.length > 0) {
|
|
29
|
+
sections.push('## Details');
|
|
30
|
+
sections.push(metadata.join(' \n'));
|
|
31
|
+
sections.push('');
|
|
32
|
+
}
|
|
33
|
+
// Subtasks
|
|
34
|
+
if (task.subTasks && task.subTasks.length > 0) {
|
|
35
|
+
sections.push('## Subtasks');
|
|
36
|
+
sections.push('');
|
|
37
|
+
task.subTasks.forEach((subtask) => {
|
|
38
|
+
sections.push(`- [ ] ${subtask}`);
|
|
39
|
+
});
|
|
40
|
+
sections.push('');
|
|
41
|
+
}
|
|
42
|
+
// Footer
|
|
43
|
+
sections.push('---');
|
|
44
|
+
sections.push('');
|
|
45
|
+
sections.push('_Generated by [claude-ticket-gen](https://github.com/brett-buskirk/claude-ticket-gen)_');
|
|
46
|
+
return sections.join('\n');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Generate title with optional prefix
|
|
50
|
+
*/
|
|
51
|
+
export function generateIssueTitle(task) {
|
|
52
|
+
// Title is already in the task
|
|
53
|
+
return task.title;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Generate labels array from task
|
|
57
|
+
*/
|
|
58
|
+
export function generateLabels(task) {
|
|
59
|
+
const labels = [...task.labels];
|
|
60
|
+
// Add priority label
|
|
61
|
+
labels.push(`priority-${getPriorityLabel(task.priority)}`);
|
|
62
|
+
// Add type label
|
|
63
|
+
labels.push(`type-${task.type}`);
|
|
64
|
+
// Add optional label if applicable
|
|
65
|
+
if (task.isOptional) {
|
|
66
|
+
labels.push('optional');
|
|
67
|
+
}
|
|
68
|
+
return labels;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get priority label name
|
|
72
|
+
*/
|
|
73
|
+
function getPriorityLabel(priority) {
|
|
74
|
+
switch (priority) {
|
|
75
|
+
case 'P0':
|
|
76
|
+
return 'critical';
|
|
77
|
+
case 'P1':
|
|
78
|
+
return 'high';
|
|
79
|
+
case 'P2':
|
|
80
|
+
return 'medium';
|
|
81
|
+
case 'P3':
|
|
82
|
+
return 'low';
|
|
83
|
+
default:
|
|
84
|
+
return 'medium';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=issue-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-template.js","sourceRoot":"","sources":["../../src/templates/issue-template.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsing-prompt.d.ts","sourceRoot":"","sources":["../../src/templates/parsing-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAiEhE"}
|