@ariso-ai/ivan 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/README.md +412 -0
- package/dist/agent.d.ts +11 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +48 -0
- package/dist/agent.js.map +1 -0
- package/dist/config/config.d.ts +20 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +187 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config.d.ts +46 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +414 -0
- package/dist/config.js.map +1 -0
- package/dist/database/database.d.ts +12 -0
- package/dist/database/database.d.ts.map +1 -0
- package/dist/database/database.js +45 -0
- package/dist/database/database.js.map +1 -0
- package/dist/database/migration.d.ts +11 -0
- package/dist/database/migration.d.ts.map +1 -0
- package/dist/database/migration.js +64 -0
- package/dist/database/migration.js.map +1 -0
- package/dist/database/migrations/001_create_jobs_table.d.ts +3 -0
- package/dist/database/migrations/001_create_jobs_table.d.ts.map +1 -0
- package/dist/database/migrations/001_create_jobs_table.js +14 -0
- package/dist/database/migrations/001_create_jobs_table.js.map +1 -0
- package/dist/database/migrations/001_initial_schema.d.ts +3 -0
- package/dist/database/migrations/001_initial_schema.d.ts.map +1 -0
- package/dist/database/migrations/001_initial_schema.js +66 -0
- package/dist/database/migrations/001_initial_schema.js.map +1 -0
- package/dist/database/migrations/002_create_tasks_table.d.ts +3 -0
- package/dist/database/migrations/002_create_tasks_table.d.ts.map +1 -0
- package/dist/database/migrations/002_create_tasks_table.js +16 -0
- package/dist/database/migrations/002_create_tasks_table.js.map +1 -0
- package/dist/database/migrations/003_add_log_to_tasks.d.ts +3 -0
- package/dist/database/migrations/003_add_log_to_tasks.d.ts.map +1 -0
- package/dist/database/migrations/003_add_log_to_tasks.js +11 -0
- package/dist/database/migrations/003_add_log_to_tasks.js.map +1 -0
- package/dist/database/migrations/004_add_branch_to_tasks.d.ts +3 -0
- package/dist/database/migrations/004_add_branch_to_tasks.d.ts.map +1 -0
- package/dist/database/migrations/004_add_branch_to_tasks.js +11 -0
- package/dist/database/migrations/004_add_branch_to_tasks.js.map +1 -0
- package/dist/database/migrations/005_add_type_to_tasks.d.ts +3 -0
- package/dist/database/migrations/005_add_type_to_tasks.d.ts.map +1 -0
- package/dist/database/migrations/005_add_type_to_tasks.js +11 -0
- package/dist/database/migrations/005_add_type_to_tasks.js.map +1 -0
- package/dist/database/migrations/006_add_comment_url_and_commit_to_tasks.d.ts +3 -0
- package/dist/database/migrations/006_add_comment_url_and_commit_to_tasks.d.ts.map +1 -0
- package/dist/database/migrations/006_add_comment_url_and_commit_to_tasks.js +15 -0
- package/dist/database/migrations/006_add_comment_url_and_commit_to_tasks.js.map +1 -0
- package/dist/database/migrations/006_add_comment_url_to_tasks.d.ts +3 -0
- package/dist/database/migrations/006_add_comment_url_to_tasks.d.ts.map +1 -0
- package/dist/database/migrations/006_add_comment_url_to_tasks.js +14 -0
- package/dist/database/migrations/006_add_comment_url_to_tasks.js.map +1 -0
- package/dist/database/migrations/007_add_commit_to_tasks.d.ts +3 -0
- package/dist/database/migrations/007_add_commit_to_tasks.d.ts.map +1 -0
- package/dist/database/migrations/007_add_commit_to_tasks.js +13 -0
- package/dist/database/migrations/007_add_commit_to_tasks.js.map +1 -0
- package/dist/database/migrations/008_add_lint_and_test_task_type.d.ts +3 -0
- package/dist/database/migrations/008_add_lint_and_test_task_type.d.ts.map +1 -0
- package/dist/database/migrations/008_add_lint_and_test_task_type.js +42 -0
- package/dist/database/migrations/008_add_lint_and_test_task_type.js.map +1 -0
- package/dist/database/migrations/index.d.ts +3 -0
- package/dist/database/migrations/index.d.ts.map +1 -0
- package/dist/database/migrations/index.js +19 -0
- package/dist/database/migrations/index.js.map +1 -0
- package/dist/database/types.d.ts +34 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +2 -0
- package/dist/database/types.js.map +1 -0
- package/dist/database.d.ts +13 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +32 -0
- package/dist/database.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +285 -0
- package/dist/index.js.map +1 -0
- package/dist/scripts/task-executor.d.ts +3 -0
- package/dist/scripts/task-executor.d.ts.map +1 -0
- package/dist/scripts/task-executor.js +139 -0
- package/dist/scripts/task-executor.js.map +1 -0
- package/dist/scripts/task-planner.d.ts +3 -0
- package/dist/scripts/task-planner.d.ts.map +1 -0
- package/dist/scripts/task-planner.js +81 -0
- package/dist/scripts/task-planner.js.map +1 -0
- package/dist/services/address-executor.d.ts +13 -0
- package/dist/services/address-executor.d.ts.map +1 -0
- package/dist/services/address-executor.js +202 -0
- package/dist/services/address-executor.js.map +1 -0
- package/dist/services/address-task-executor.d.ts +19 -0
- package/dist/services/address-task-executor.d.ts.map +1 -0
- package/dist/services/address-task-executor.js +736 -0
- package/dist/services/address-task-executor.js.map +1 -0
- package/dist/services/claude-cli-executor.d.ts +14 -0
- package/dist/services/claude-cli-executor.d.ts.map +1 -0
- package/dist/services/claude-cli-executor.js +241 -0
- package/dist/services/claude-cli-executor.js.map +1 -0
- package/dist/services/claude-executor.d.ts +14 -0
- package/dist/services/claude-executor.d.ts.map +1 -0
- package/dist/services/claude-executor.js +274 -0
- package/dist/services/claude-executor.js.map +1 -0
- package/dist/services/claude-planner.d.ts +15 -0
- package/dist/services/claude-planner.d.ts.map +1 -0
- package/dist/services/claude-planner.js +107 -0
- package/dist/services/claude-planner.js.map +1 -0
- package/dist/services/docker-orchestrator.d.ts +11 -0
- package/dist/services/docker-orchestrator.d.ts.map +1 -0
- package/dist/services/docker-orchestrator.js +85 -0
- package/dist/services/docker-orchestrator.js.map +1 -0
- package/dist/services/executor-factory.d.ts +14 -0
- package/dist/services/executor-factory.d.ts.map +1 -0
- package/dist/services/executor-factory.js +14 -0
- package/dist/services/executor-factory.js.map +1 -0
- package/dist/services/git-manager.d.ts +36 -0
- package/dist/services/git-manager.d.ts.map +1 -0
- package/dist/services/git-manager.js +728 -0
- package/dist/services/git-manager.js.map +1 -0
- package/dist/services/index.d.ts +9 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +9 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/job-manager.d.ts +30 -0
- package/dist/services/job-manager.d.ts.map +1 -0
- package/dist/services/job-manager.js +337 -0
- package/dist/services/job-manager.js.map +1 -0
- package/dist/services/openai-service.d.ts +14 -0
- package/dist/services/openai-service.d.ts.map +1 -0
- package/dist/services/openai-service.js +186 -0
- package/dist/services/openai-service.js.map +1 -0
- package/dist/services/pr-service.d.ts +31 -0
- package/dist/services/pr-service.d.ts.map +1 -0
- package/dist/services/pr-service.js +291 -0
- package/dist/services/pr-service.js.map +1 -0
- package/dist/services/repository-manager.d.ts +12 -0
- package/dist/services/repository-manager.d.ts.map +1 -0
- package/dist/services/repository-manager.js +101 -0
- package/dist/services/repository-manager.js.map +1 -0
- package/dist/services/task-executor.d.ts +20 -0
- package/dist/services/task-executor.d.ts.map +1 -0
- package/dist/services/task-executor.js +717 -0
- package/dist/services/task-executor.js.map +1 -0
- package/dist/types/non-interactive-config.d.ts +28 -0
- package/dist/types/non-interactive-config.d.ts.map +1 -0
- package/dist/types/non-interactive-config.js +2 -0
- package/dist/types/non-interactive-config.js.map +1 -0
- package/dist/web-server.d.ts +16 -0
- package/dist/web-server.d.ts.map +1 -0
- package/dist/web-server.js +488 -0
- package/dist/web-server.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { ConfigManager } from '../config.js';
|
|
3
|
+
export class OpenAIService {
|
|
4
|
+
openai = null;
|
|
5
|
+
configManager;
|
|
6
|
+
constructor() {
|
|
7
|
+
this.configManager = new ConfigManager();
|
|
8
|
+
}
|
|
9
|
+
async ensureInitialized() {
|
|
10
|
+
if (this.openai)
|
|
11
|
+
return;
|
|
12
|
+
let config = this.configManager.getConfig();
|
|
13
|
+
if (!config?.openaiApiKey || config.openaiApiKey === '') {
|
|
14
|
+
// Prompt for the API key
|
|
15
|
+
await this.configManager.promptForMissingConfig('openaiApiKey');
|
|
16
|
+
config = this.configManager.getConfig();
|
|
17
|
+
}
|
|
18
|
+
if (!config?.openaiApiKey) {
|
|
19
|
+
throw new Error('Failed to obtain OpenAI API key');
|
|
20
|
+
}
|
|
21
|
+
this.openai = new OpenAI({
|
|
22
|
+
apiKey: config.openaiApiKey
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
async getClient() {
|
|
26
|
+
await this.ensureInitialized();
|
|
27
|
+
if (!this.openai) {
|
|
28
|
+
throw new Error('OpenAI client not initialized');
|
|
29
|
+
}
|
|
30
|
+
return this.openai;
|
|
31
|
+
}
|
|
32
|
+
async generateCommitMessage(diff, changedFiles) {
|
|
33
|
+
await this.ensureInitialized();
|
|
34
|
+
const prompt = `
|
|
35
|
+
Generate a concise git commit message for the following changes.
|
|
36
|
+
|
|
37
|
+
Changed files:
|
|
38
|
+
${changedFiles.map(file => `- ${file}`).join('\n')}
|
|
39
|
+
|
|
40
|
+
Git diff:
|
|
41
|
+
\`\`\`
|
|
42
|
+
${diff}
|
|
43
|
+
\`\`\`
|
|
44
|
+
|
|
45
|
+
Rules:
|
|
46
|
+
- Use conventional commit format (feat:, fix:, refactor:, etc.)
|
|
47
|
+
- Keep it under 50 characters for the subject line
|
|
48
|
+
- Focus on what was changed and why
|
|
49
|
+
- Be specific and clear
|
|
50
|
+
|
|
51
|
+
Return only the commit message, nothing else.`;
|
|
52
|
+
try {
|
|
53
|
+
if (!this.openai) {
|
|
54
|
+
throw new Error('OpenAI client not initialized');
|
|
55
|
+
}
|
|
56
|
+
const response = await this.openai.chat.completions.create({
|
|
57
|
+
model: 'gpt-4o-mini',
|
|
58
|
+
messages: [
|
|
59
|
+
{
|
|
60
|
+
role: 'user',
|
|
61
|
+
content: prompt
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
max_tokens: 100,
|
|
65
|
+
temperature: 0.3
|
|
66
|
+
});
|
|
67
|
+
const message = response.choices[0]?.message?.content?.trim();
|
|
68
|
+
if (!message) {
|
|
69
|
+
throw new Error('No commit message generated');
|
|
70
|
+
}
|
|
71
|
+
return message;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error('Failed to generate commit message:', error);
|
|
75
|
+
return 'chore: update code via Ivan';
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async generatePullRequestDescription(taskDescription, diff, changedFiles) {
|
|
79
|
+
await this.ensureInitialized();
|
|
80
|
+
// Truncate diff if it's too large (keep under 30K characters for the prompt)
|
|
81
|
+
// This leaves room for the response and other parts of the prompt
|
|
82
|
+
const MAX_DIFF_LENGTH = 30000;
|
|
83
|
+
let truncatedDiff = diff;
|
|
84
|
+
let diffWasTruncated = false;
|
|
85
|
+
if (diff.length > MAX_DIFF_LENGTH) {
|
|
86
|
+
// Take first and last portions of the diff to show context
|
|
87
|
+
const firstPart = diff.substring(0, MAX_DIFF_LENGTH / 2);
|
|
88
|
+
const lastPart = diff.substring(diff.length - MAX_DIFF_LENGTH / 2);
|
|
89
|
+
truncatedDiff = `${firstPart}\n\n... (diff truncated - ${diff.length} total characters) ...\n\n${lastPart}`;
|
|
90
|
+
diffWasTruncated = true;
|
|
91
|
+
}
|
|
92
|
+
const prompt = `
|
|
93
|
+
Generate a pull request title and description for the following task and changes.
|
|
94
|
+
|
|
95
|
+
Task: ${taskDescription}
|
|
96
|
+
|
|
97
|
+
Changed files:
|
|
98
|
+
${changedFiles.map(file => `- ${file}`).join('\n')}
|
|
99
|
+
|
|
100
|
+
Git diff${diffWasTruncated ? ' (truncated for brevity)' : ''}:
|
|
101
|
+
\`\`\`
|
|
102
|
+
${truncatedDiff}
|
|
103
|
+
\`\`\`
|
|
104
|
+
|
|
105
|
+
Generate:
|
|
106
|
+
1. A concise PR title (MUST be under 250 characters to fit GitHub's 256 character limit)
|
|
107
|
+
2. A concise PR description (MUST be under 10000 characters) with:
|
|
108
|
+
- Brief summary of changes (2-3 sentences)
|
|
109
|
+
- List of main changes (bullet points)
|
|
110
|
+
- Any important notes
|
|
111
|
+
|
|
112
|
+
Keep the description focused and concise. Do NOT include the full diff in the description.`;
|
|
113
|
+
try {
|
|
114
|
+
if (!this.openai) {
|
|
115
|
+
throw new Error('OpenAI client not initialized');
|
|
116
|
+
}
|
|
117
|
+
const response = await this.openai.chat.completions.create({
|
|
118
|
+
model: 'gpt-4o-mini',
|
|
119
|
+
messages: [
|
|
120
|
+
{
|
|
121
|
+
role: 'user',
|
|
122
|
+
content: prompt
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
response_format: {
|
|
126
|
+
type: 'json_schema',
|
|
127
|
+
json_schema: {
|
|
128
|
+
name: 'pull_request',
|
|
129
|
+
strict: true,
|
|
130
|
+
schema: {
|
|
131
|
+
type: 'object',
|
|
132
|
+
properties: {
|
|
133
|
+
title: {
|
|
134
|
+
type: 'string',
|
|
135
|
+
description: 'The PR title (must be under 250 characters)'
|
|
136
|
+
},
|
|
137
|
+
body: {
|
|
138
|
+
type: 'string',
|
|
139
|
+
description: 'The PR description'
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
required: ['title', 'body'],
|
|
143
|
+
additionalProperties: false
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
max_tokens: 1000,
|
|
148
|
+
temperature: 0.3
|
|
149
|
+
});
|
|
150
|
+
const content = response.choices[0]?.message?.content?.trim();
|
|
151
|
+
if (!content) {
|
|
152
|
+
throw new Error('No PR description generated');
|
|
153
|
+
}
|
|
154
|
+
const parsed = JSON.parse(content);
|
|
155
|
+
// Ensure title doesn't exceed GitHub's 256 character limit
|
|
156
|
+
let title = `Ivan: ${parsed.title || taskDescription}`;
|
|
157
|
+
if (title.length > 256) {
|
|
158
|
+
title = title.substring(0, 253) + '...';
|
|
159
|
+
}
|
|
160
|
+
// Ensure the PR body doesn't exceed GitHub's limit (65536 characters)
|
|
161
|
+
// Leave some room for the attribution footer that GitManager will add
|
|
162
|
+
const MAX_BODY_LENGTH = 65000;
|
|
163
|
+
let body = parsed.body || `Implemented: ${taskDescription}\n\n🤖 Generated with Ivan`;
|
|
164
|
+
if (body.length > MAX_BODY_LENGTH) {
|
|
165
|
+
body = body.substring(0, MAX_BODY_LENGTH) + '\n\n... (description truncated)';
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
title,
|
|
169
|
+
body
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
console.error('Failed to generate PR description:', error);
|
|
174
|
+
// Ensure fallback title doesn't exceed GitHub's 256 character limit
|
|
175
|
+
let fallbackTitle = `Ivan: ${taskDescription}`;
|
|
176
|
+
if (fallbackTitle.length > 256) {
|
|
177
|
+
fallbackTitle = fallbackTitle.substring(0, 253) + '...';
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
title: fallbackTitle,
|
|
181
|
+
body: `Implemented: ${taskDescription}\n\nChanged files:\n${changedFiles.map(file => `- ${file}`).join('\n')}\n\n🤖 Generated with Ivan`
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=openai-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-service.js","sourceRoot":"","sources":["../../src/services/openai-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface PullRequest {
|
|
2
|
+
number: number;
|
|
3
|
+
title: string;
|
|
4
|
+
branch: string;
|
|
5
|
+
url: string;
|
|
6
|
+
hasUnaddressedComments: boolean;
|
|
7
|
+
hasFailingChecks: boolean;
|
|
8
|
+
unaddressedComments: PRComment[];
|
|
9
|
+
failingChecks: string[];
|
|
10
|
+
hasTestOrLintFailures: boolean;
|
|
11
|
+
testOrLintFailures: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface PRComment {
|
|
14
|
+
id: string;
|
|
15
|
+
author: string;
|
|
16
|
+
body: string;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
path?: string;
|
|
19
|
+
line?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare class PRService {
|
|
22
|
+
private workingDir;
|
|
23
|
+
constructor(workingDir: string);
|
|
24
|
+
getSpecificPRWithIssues(prNumber: number): Promise<PullRequest[]>;
|
|
25
|
+
getOpenPRsWithIssues(fromUser?: string): Promise<PullRequest[]>;
|
|
26
|
+
getUnaddressedComments(prNumber: number): Promise<PRComment[]>;
|
|
27
|
+
private getFailingChecks;
|
|
28
|
+
checkoutPRBranch(prNumber: number): Promise<void>;
|
|
29
|
+
getFailingActionLogs(prNumber: number): Promise<string>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=pr-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-service.d.ts","sourceRoot":"","sources":["../../src/services/pr-service.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,sBAAsB,EAAE,OAAO,CAAC;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mBAAmB,EAAE,SAAS,EAAE,CAAC;IACjC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,UAAU,CAAS;gBAEf,UAAU,EAAE,MAAM;IAIxB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAgEjE,oBAAoB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA6D/D,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YA0FtD,gBAAgB;IAkDxB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjD,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAwD9D"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
export class PRService {
|
|
4
|
+
workingDir;
|
|
5
|
+
constructor(workingDir) {
|
|
6
|
+
this.workingDir = workingDir;
|
|
7
|
+
}
|
|
8
|
+
async getSpecificPRWithIssues(prNumber) {
|
|
9
|
+
try {
|
|
10
|
+
// Get specific PR
|
|
11
|
+
const prJson = execSync(`gh pr view ${prNumber} --json number,title,headRefName,url,state`, {
|
|
12
|
+
cwd: this.workingDir,
|
|
13
|
+
encoding: 'utf-8'
|
|
14
|
+
});
|
|
15
|
+
const pr = JSON.parse(prJson);
|
|
16
|
+
// Check if PR is open
|
|
17
|
+
if (pr.state !== 'OPEN') {
|
|
18
|
+
console.log(chalk.yellow(`⚠️ PR #${prNumber} is not open (status: ${pr.state})`));
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
const pullRequest = {
|
|
22
|
+
number: pr.number,
|
|
23
|
+
title: pr.title,
|
|
24
|
+
branch: pr.headRefName,
|
|
25
|
+
url: pr.url,
|
|
26
|
+
hasUnaddressedComments: false,
|
|
27
|
+
hasFailingChecks: false,
|
|
28
|
+
unaddressedComments: [],
|
|
29
|
+
failingChecks: [],
|
|
30
|
+
hasTestOrLintFailures: false,
|
|
31
|
+
testOrLintFailures: []
|
|
32
|
+
};
|
|
33
|
+
// Check for unaddressed comments
|
|
34
|
+
const comments = await this.getUnaddressedComments(pr.number);
|
|
35
|
+
if (comments.length > 0) {
|
|
36
|
+
pullRequest.hasUnaddressedComments = true;
|
|
37
|
+
pullRequest.unaddressedComments = comments;
|
|
38
|
+
}
|
|
39
|
+
// Check for failing checks
|
|
40
|
+
const { allFailures, testOrLintFailures } = await this.getFailingChecks(pr.number);
|
|
41
|
+
if (allFailures.length > 0) {
|
|
42
|
+
pullRequest.hasFailingChecks = true;
|
|
43
|
+
pullRequest.failingChecks = allFailures;
|
|
44
|
+
}
|
|
45
|
+
if (testOrLintFailures.length > 0) {
|
|
46
|
+
pullRequest.hasTestOrLintFailures = true;
|
|
47
|
+
pullRequest.testOrLintFailures = testOrLintFailures;
|
|
48
|
+
}
|
|
49
|
+
// Only include PR if it has issues
|
|
50
|
+
if (pullRequest.hasUnaddressedComments || pullRequest.hasFailingChecks) {
|
|
51
|
+
return [pullRequest];
|
|
52
|
+
}
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
57
|
+
if (errorMessage.includes('no pull requests found')) {
|
|
58
|
+
console.error(chalk.red(`❌ PR #${prNumber} not found`));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.error(chalk.red(`Error fetching PR #${prNumber}:`), error);
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async getOpenPRsWithIssues(fromUser) {
|
|
67
|
+
try {
|
|
68
|
+
// Get all open PRs, optionally filtered by author
|
|
69
|
+
let command = 'gh pr list --state open --json number,title,headRefName,url,author';
|
|
70
|
+
if (fromUser) {
|
|
71
|
+
command += ` --author ${fromUser}`;
|
|
72
|
+
}
|
|
73
|
+
const prsJson = execSync(command, {
|
|
74
|
+
cwd: this.workingDir,
|
|
75
|
+
encoding: 'utf-8'
|
|
76
|
+
});
|
|
77
|
+
const prs = JSON.parse(prsJson);
|
|
78
|
+
const pullRequests = [];
|
|
79
|
+
for (const pr of prs) {
|
|
80
|
+
const pullRequest = {
|
|
81
|
+
number: pr.number,
|
|
82
|
+
title: pr.title,
|
|
83
|
+
branch: pr.headRefName,
|
|
84
|
+
url: pr.url,
|
|
85
|
+
hasUnaddressedComments: false,
|
|
86
|
+
hasFailingChecks: false,
|
|
87
|
+
unaddressedComments: [],
|
|
88
|
+
failingChecks: [],
|
|
89
|
+
hasTestOrLintFailures: false,
|
|
90
|
+
testOrLintFailures: []
|
|
91
|
+
};
|
|
92
|
+
// Check for unaddressed comments
|
|
93
|
+
const comments = await this.getUnaddressedComments(pr.number);
|
|
94
|
+
if (comments.length > 0) {
|
|
95
|
+
pullRequest.hasUnaddressedComments = true;
|
|
96
|
+
pullRequest.unaddressedComments = comments;
|
|
97
|
+
}
|
|
98
|
+
// Check for failing checks
|
|
99
|
+
const { allFailures, testOrLintFailures } = await this.getFailingChecks(pr.number);
|
|
100
|
+
if (allFailures.length > 0) {
|
|
101
|
+
pullRequest.hasFailingChecks = true;
|
|
102
|
+
pullRequest.failingChecks = allFailures;
|
|
103
|
+
}
|
|
104
|
+
if (testOrLintFailures.length > 0) {
|
|
105
|
+
pullRequest.hasTestOrLintFailures = true;
|
|
106
|
+
pullRequest.testOrLintFailures = testOrLintFailures;
|
|
107
|
+
}
|
|
108
|
+
// Only include PRs that have issues
|
|
109
|
+
if (pullRequest.hasUnaddressedComments || pullRequest.hasFailingChecks) {
|
|
110
|
+
pullRequests.push(pullRequest);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return pullRequests;
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
console.error(chalk.red('Error fetching PRs:'), error);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async getUnaddressedComments(prNumber) {
|
|
121
|
+
try {
|
|
122
|
+
// Get PR owner and repo name
|
|
123
|
+
const repoInfo = execSync('gh repo view --json owner,name', {
|
|
124
|
+
cwd: this.workingDir,
|
|
125
|
+
encoding: 'utf-8'
|
|
126
|
+
});
|
|
127
|
+
const { owner, name: repoName } = JSON.parse(repoInfo);
|
|
128
|
+
// Use GraphQL to get review threads with resolved status
|
|
129
|
+
const graphqlQuery = `
|
|
130
|
+
query {
|
|
131
|
+
repository(owner: "${owner.login}", name: "${repoName}") {
|
|
132
|
+
pullRequest(number: ${prNumber}) {
|
|
133
|
+
reviewThreads(first: 100) {
|
|
134
|
+
nodes {
|
|
135
|
+
isResolved
|
|
136
|
+
comments(first: 100) {
|
|
137
|
+
nodes {
|
|
138
|
+
id
|
|
139
|
+
databaseId
|
|
140
|
+
body
|
|
141
|
+
author {
|
|
142
|
+
login
|
|
143
|
+
}
|
|
144
|
+
createdAt
|
|
145
|
+
path
|
|
146
|
+
line
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
`;
|
|
155
|
+
const graphqlResult = execSync(`gh api graphql -f query='${graphqlQuery}'`, {
|
|
156
|
+
cwd: this.workingDir,
|
|
157
|
+
encoding: 'utf-8'
|
|
158
|
+
});
|
|
159
|
+
const result = JSON.parse(graphqlResult);
|
|
160
|
+
const threads = result.data?.repository?.pullRequest?.reviewThreads?.nodes || [];
|
|
161
|
+
const unaddressedComments = [];
|
|
162
|
+
// Process each thread
|
|
163
|
+
for (const thread of threads) {
|
|
164
|
+
// Skip resolved threads
|
|
165
|
+
if (thread.isResolved) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const comments = thread.comments?.nodes || [];
|
|
169
|
+
if (comments.length === 0) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
// Get the first comment (the main review comment)
|
|
173
|
+
const firstComment = comments[0];
|
|
174
|
+
// Check if there are replies (more than one comment in thread)
|
|
175
|
+
const hasReplies = comments.length > 1;
|
|
176
|
+
if (!hasReplies && firstComment.path) {
|
|
177
|
+
// Only include if it's an inline code comment (has a path) and has no replies
|
|
178
|
+
unaddressedComments.push({
|
|
179
|
+
id: firstComment.databaseId ? firstComment.databaseId.toString() : firstComment.id,
|
|
180
|
+
author: firstComment.author.login,
|
|
181
|
+
body: firstComment.body,
|
|
182
|
+
createdAt: firstComment.createdAt,
|
|
183
|
+
path: firstComment.path,
|
|
184
|
+
line: firstComment.line
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return unaddressedComments;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// If there's an error fetching comments, return empty array
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async getFailingChecks(prNumber) {
|
|
196
|
+
try {
|
|
197
|
+
const checksJson = execSync(`gh pr checks ${prNumber} --json name,state`, {
|
|
198
|
+
cwd: this.workingDir,
|
|
199
|
+
encoding: 'utf-8'
|
|
200
|
+
});
|
|
201
|
+
const checks = JSON.parse(checksJson);
|
|
202
|
+
const failingChecks = [];
|
|
203
|
+
const testOrLintFailures = [];
|
|
204
|
+
for (const check of checks) {
|
|
205
|
+
if (check.state === 'FAILURE' || check.state === 'ERROR') {
|
|
206
|
+
failingChecks.push(check.name);
|
|
207
|
+
// Check if this is a test or lint failure
|
|
208
|
+
const checkNameLower = check.name.toLowerCase();
|
|
209
|
+
if (checkNameLower.includes('test') ||
|
|
210
|
+
checkNameLower.includes('lint') ||
|
|
211
|
+
checkNameLower.includes('eslint') ||
|
|
212
|
+
checkNameLower.includes('prettier') ||
|
|
213
|
+
checkNameLower.includes('jest') ||
|
|
214
|
+
checkNameLower.includes('mocha') ||
|
|
215
|
+
checkNameLower.includes('pytest') ||
|
|
216
|
+
checkNameLower.includes('ruff') ||
|
|
217
|
+
checkNameLower.includes('black') ||
|
|
218
|
+
checkNameLower.includes('flake8') ||
|
|
219
|
+
checkNameLower.includes('mypy') ||
|
|
220
|
+
checkNameLower.includes('typecheck') ||
|
|
221
|
+
checkNameLower.includes('type-check') ||
|
|
222
|
+
checkNameLower.includes('tsc') ||
|
|
223
|
+
checkNameLower.includes('clippy') ||
|
|
224
|
+
checkNameLower.includes('rustfmt')) {
|
|
225
|
+
testOrLintFailures.push(check.name);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return { allFailures: failingChecks, testOrLintFailures };
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// If there's an error fetching checks, return empty arrays
|
|
233
|
+
return { allFailures: [], testOrLintFailures: [] };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async checkoutPRBranch(prNumber) {
|
|
237
|
+
execSync(`gh pr checkout ${prNumber}`, {
|
|
238
|
+
cwd: this.workingDir,
|
|
239
|
+
stdio: 'inherit'
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
async getFailingActionLogs(prNumber) {
|
|
243
|
+
try {
|
|
244
|
+
// Get the checks with their workflow information
|
|
245
|
+
const checksJson = execSync(`gh pr checks ${prNumber} --json name,state,link,workflow`, {
|
|
246
|
+
cwd: this.workingDir,
|
|
247
|
+
encoding: 'utf-8'
|
|
248
|
+
});
|
|
249
|
+
const checks = JSON.parse(checksJson);
|
|
250
|
+
let failingLogs = '';
|
|
251
|
+
for (const check of checks) {
|
|
252
|
+
if (check.state === 'FAILURE' || check.state === 'ERROR') {
|
|
253
|
+
// Extract run ID from the link (format: https://github.com/owner/repo/actions/runs/123456789/job/987654321)
|
|
254
|
+
const runIdMatch = check.link?.match(/\/runs\/(\d+)/);
|
|
255
|
+
if (runIdMatch) {
|
|
256
|
+
const runId = runIdMatch[1];
|
|
257
|
+
try {
|
|
258
|
+
// Get the failed logs for this run
|
|
259
|
+
const logs = execSync(`gh run view ${runId} --log-failed`, {
|
|
260
|
+
cwd: this.workingDir,
|
|
261
|
+
encoding: 'utf-8',
|
|
262
|
+
maxBuffer: 10 * 1024 * 1024 // 10MB buffer for large logs
|
|
263
|
+
});
|
|
264
|
+
if (logs) {
|
|
265
|
+
failingLogs += `\n\n=== Failed logs for ${check.name} ===\n`;
|
|
266
|
+
// Truncate logs if too large (keep last 5000 chars per check)
|
|
267
|
+
if (logs.length > 5000) {
|
|
268
|
+
failingLogs += '... (truncated) ...\n';
|
|
269
|
+
failingLogs += logs.substring(logs.length - 5000);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
failingLogs += logs;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
// If we can't get logs for this specific run, continue with others
|
|
278
|
+
console.error(`Failed to get logs for run ${runId}:`, error);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return failingLogs;
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
console.error('Error fetching action logs:', error);
|
|
287
|
+
return '';
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=pr-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-service.js","sourceRoot":"","sources":["../../src/services/pr-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,MAAM,OAAO,CAAC;AAwB1B,MAAM,OAAO,SAAS;IACZ,UAAU,CAAS;IAE3B,YAAY,UAAkB;QAC5B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,QAAgB;QAC5C,IAAI,CAAC;YACH,kBAAkB;YAClB,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,QAAQ,4CAA4C,EAAE;gBAC1F,GAAG,EAAE,IAAI,CAAC,UAAU;gBACpB,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YAEH,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAE9B,sBAAsB;YACtB,IAAI,EAAE,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,QAAQ,yBAAyB,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;gBACnF,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,WAAW,GAAgB;gBAC/B,MAAM,EAAE,EAAE,CAAC,MAAM;gBACjB,KAAK,EAAE,EAAE,CAAC,KAAK;gBACf,MAAM,EAAE,EAAE,CAAC,WAAW;gBACtB,GAAG,EAAE,EAAE,CAAC,GAAG;gBACX,sBAAsB,EAAE,KAAK;gBAC7B,gBAAgB,EAAE,KAAK;gBACvB,mBAAmB,EAAE,EAAE;gBACvB,aAAa,EAAE,EAAE;gBACjB,qBAAqB,EAAE,KAAK;gBAC5B,kBAAkB,EAAE,EAAE;aACvB,CAAC;YAEF,iCAAiC;YACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAC9D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,WAAW,CAAC,sBAAsB,GAAG,IAAI,CAAC;gBAC1C,WAAW,CAAC,mBAAmB,GAAG,QAAQ,CAAC;YAC7C,CAAC;YAED,2BAA2B;YAC3B,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YACnF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,WAAW,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBACpC,WAAW,CAAC,aAAa,GAAG,WAAW,CAAC;YAC1C,CAAC;YACD,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClC,WAAW,CAAC,qBAAqB,GAAG,IAAI,CAAC;gBACzC,WAAW,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;YACtD,CAAC;YAED,mCAAmC;YACnC,IAAI,WAAW,CAAC,sBAAsB,IAAI,WAAW,CAAC,gBAAgB,EAAE,CAAC;gBACvE,OAAO,CAAC,WAAW,CAAC,CAAC;YACvB,CAAC;YAED,OAAO,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,IAAI,YAAY,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,CAAC;gBACpD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,QAAQ,YAAY,CAAC,CAAC,CAAC;YAC1D,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,QAAQ,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YACrE,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,QAAiB;QAC1C,IAAI,CAAC;YACH,kDAAkD;YAClD,IAAI,OAAO,GAAG,oEAAoE,CAAC;YACnF,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,IAAI,aAAa,QAAQ,EAAE,CAAC;YACrC,CAAC;YAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE;gBAChC,GAAG,EAAE,IAAI,CAAC,UAAU;gBACpB,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YAEH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAChC,MAAM,YAAY,GAAkB,EAAE,CAAC;YAEvC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;gBACrB,MAAM,WAAW,GAAgB;oBAC/B,MAAM,EAAE,EAAE,CAAC,MAAM;oBACjB,KAAK,EAAE,EAAE,CAAC,KAAK;oBACf,MAAM,EAAE,EAAE,CAAC,WAAW;oBACtB,GAAG,EAAE,EAAE,CAAC,GAAG;oBACX,sBAAsB,EAAE,KAAK;oBAC7B,gBAAgB,EAAE,KAAK;oBACvB,mBAAmB,EAAE,EAAE;oBACvB,aAAa,EAAE,EAAE;oBACjB,qBAAqB,EAAE,KAAK;oBAC5B,kBAAkB,EAAE,EAAE;iBACvB,CAAC;gBAEF,iCAAiC;gBACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBAC9D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,WAAW,CAAC,sBAAsB,GAAG,IAAI,CAAC;oBAC1C,WAAW,CAAC,mBAAmB,GAAG,QAAQ,CAAC;gBAC7C,CAAC;gBAED,2BAA2B;gBAC3B,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBACnF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3B,WAAW,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBACpC,WAAW,CAAC,aAAa,GAAG,WAAW,CAAC;gBAC1C,CAAC;gBACD,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAClC,WAAW,CAAC,qBAAqB,GAAG,IAAI,CAAC;oBACzC,WAAW,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;gBACtD,CAAC;gBAED,oCAAoC;gBACpC,IAAI,WAAW,CAAC,sBAAsB,IAAI,WAAW,CAAC,gBAAgB,EAAE,CAAC;oBACvE,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC;YAED,OAAO,YAAY,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,KAAK,CAAC,CAAC;YACvD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,QAAgB;QAC3C,IAAI,CAAC;YACH,6BAA6B;YAC7B,MAAM,QAAQ,GAAG,QAAQ,CACvB,gCAAgC,EAChC;gBACE,GAAG,EAAE,IAAI,CAAC,UAAU;gBACpB,QAAQ,EAAE,OAAO;aAClB,CACF,CAAC;YACF,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAEvD,yDAAyD;YACzD,MAAM,YAAY,GAAG;;+BAEI,KAAK,CAAC,KAAK,aAAa,QAAQ;kCAC7B,QAAQ;;;;;;;;;;;;;;;;;;;;;;OAsBnC,CAAC;YAEF,MAAM,aAAa,GAAG,QAAQ,CAC5B,4BAA4B,YAAY,GAAG,EAC3C;gBACE,GAAG,EAAE,IAAI,CAAC,UAAU;gBACpB,QAAQ,EAAE,OAAO;aAClB,CACF,CAAC;YAEF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACzC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,IAAI,EAAE,CAAC;YACjF,MAAM,mBAAmB,GAAgB,EAAE,CAAC;YAE5C,sBAAsB;YACtB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,wBAAwB;gBACxB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;oBACtB,SAAS;gBACX,CAAC;gBAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC;gBAC9C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1B,SAAS;gBACX,CAAC;gBAED,kDAAkD;gBAClD,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAEjC,+DAA+D;gBAC/D,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;gBAEvC,IAAI,CAAC,UAAU,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC;oBACrC,8EAA8E;oBAC9E,mBAAmB,CAAC,IAAI,CAAC;wBACvB,EAAE,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE;wBAClF,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK;wBACjC,IAAI,EAAE,YAAY,CAAC,IAAI;wBACvB,SAAS,EAAE,YAAY,CAAC,SAAS;wBACjC,IAAI,EAAE,YAAY,CAAC,IAAI;wBACvB,IAAI,EAAE,YAAY,CAAC,IAAI;qBACxB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,4DAA4D;YAC5D,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,QAAgB;QAC7C,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,QAAQ,CACzB,gBAAgB,QAAQ,oBAAoB,EAC5C;gBACE,GAAG,EAAE,IAAI,CAAC,UAAU;gBACpB,QAAQ,EAAE,OAAO;aAClB,CACF,CAAC;YAEF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACtC,MAAM,aAAa,GAAa,EAAE,CAAC;YACnC,MAAM,kBAAkB,GAAa,EAAE,CAAC;YAExC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;oBACzD,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAE/B,0CAA0C;oBAC1C,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;oBAChD,IACE,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC;wBAC/B,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC;wBAC/B,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBACjC,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC;wBACnC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC;wBAC/B,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC;wBAChC,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBACjC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC;wBAC/B,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC;wBAChC,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBACjC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC;wBAC/B,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC;wBACpC,cAAc,CAAC,QAAQ,CAAC,YAAY,CAAC;wBACrC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC;wBAC9B,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBACjC,cAAc,CAAC,QAAQ,CAAC,SAAS,CAAC,EAClC,CAAC;wBACD,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACtC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,kBAAkB,EAAE,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,2DAA2D;YAC3D,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,CAAC;QACrD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAgB;QACrC,QAAQ,CAAC,kBAAkB,QAAQ,EAAE,EAAE;YACrC,GAAG,EAAE,IAAI,CAAC,UAAU;YACpB,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,QAAgB;QACzC,IAAI,CAAC;YACH,iDAAiD;YACjD,MAAM,UAAU,GAAG,QAAQ,CACzB,gBAAgB,QAAQ,kCAAkC,EAC1D;gBACE,GAAG,EAAE,IAAI,CAAC,UAAU;gBACpB,QAAQ,EAAE,OAAO;aAClB,CACF,CAAC;YAEF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,WAAW,GAAG,EAAE,CAAC;YAErB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;oBACzD,4GAA4G;oBAC5G,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;oBACtD,IAAI,UAAU,EAAE,CAAC;wBACf,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;wBAE5B,IAAI,CAAC;4BACH,mCAAmC;4BACnC,MAAM,IAAI,GAAG,QAAQ,CACnB,eAAe,KAAK,eAAe,EACnC;gCACE,GAAG,EAAE,IAAI,CAAC,UAAU;gCACpB,QAAQ,EAAE,OAAO;gCACjB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,6BAA6B;6BAC1D,CACF,CAAC;4BAEF,IAAI,IAAI,EAAE,CAAC;gCACT,WAAW,IAAI,2BAA2B,KAAK,CAAC,IAAI,QAAQ,CAAC;gCAC7D,8DAA8D;gCAC9D,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;oCACvB,WAAW,IAAI,uBAAuB,CAAC;oCACvC,WAAW,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;gCACpD,CAAC;qCAAM,CAAC;oCACN,WAAW,IAAI,IAAI,CAAC;gCACtB,CAAC;4BACH,CAAC;wBACH,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,mEAAmE;4BACnE,OAAO,CAAC,KAAK,CAAC,8BAA8B,KAAK,GAAG,EAAE,KAAK,CAAC,CAAC;wBAC/D,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO,WAAW,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACpD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class RepositoryManager {
|
|
2
|
+
getValidWorkingDirectory(): Promise<string>;
|
|
3
|
+
private isGitRepository;
|
|
4
|
+
private isIvanRepository;
|
|
5
|
+
private isValidTargetRepository;
|
|
6
|
+
private promptForRepositoryPath;
|
|
7
|
+
getRepositoryInfo(workingDir: string): {
|
|
8
|
+
name: string;
|
|
9
|
+
branch: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=repository-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository-manager.d.ts","sourceRoot":"","sources":["../../src/services/repository-manager.ts"],"names":[],"mappings":"AAMA,qBAAa,iBAAiB;IACtB,wBAAwB,IAAI,OAAO,CAAC,MAAM,CAAC;IAkBjD,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,uBAAuB;YAIjB,uBAAuB;IA8CrC,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CAaxE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
export class RepositoryManager {
|
|
7
|
+
async getValidWorkingDirectory() {
|
|
8
|
+
const currentDir = process.cwd();
|
|
9
|
+
if (this.isValidTargetRepository(currentDir)) {
|
|
10
|
+
return currentDir;
|
|
11
|
+
}
|
|
12
|
+
console.log(chalk.yellow('⚠️ Current directory is not a valid target repository'));
|
|
13
|
+
if (!this.isGitRepository(currentDir)) {
|
|
14
|
+
console.log(chalk.red('❌ Not a git repository'));
|
|
15
|
+
}
|
|
16
|
+
else if (this.isIvanRepository(currentDir)) {
|
|
17
|
+
console.log(chalk.red('❌ Cannot run Ivan on itself'));
|
|
18
|
+
}
|
|
19
|
+
return await this.promptForRepositoryPath();
|
|
20
|
+
}
|
|
21
|
+
isGitRepository(dir) {
|
|
22
|
+
try {
|
|
23
|
+
execSync('git rev-parse --git-dir', {
|
|
24
|
+
cwd: dir,
|
|
25
|
+
stdio: 'ignore'
|
|
26
|
+
});
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
isIvanRepository(dir) {
|
|
34
|
+
try {
|
|
35
|
+
const packageJsonPath = path.join(dir, 'package.json');
|
|
36
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
40
|
+
return packageJson.name === '@ariso-ai/ivan' || packageJson.name === 'ivan';
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
isValidTargetRepository(dir) {
|
|
47
|
+
return this.isGitRepository(dir) && !this.isIvanRepository(dir);
|
|
48
|
+
}
|
|
49
|
+
async promptForRepositoryPath() {
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(chalk.blue('📁 Please specify the repository where Ivan should work'));
|
|
52
|
+
while (true) {
|
|
53
|
+
const { repositoryPath } = await inquirer.prompt([
|
|
54
|
+
{
|
|
55
|
+
type: 'input',
|
|
56
|
+
name: 'repositoryPath',
|
|
57
|
+
message: 'Enter the path to your target repository:',
|
|
58
|
+
validate: (input) => {
|
|
59
|
+
if (!input || input.trim().length === 0) {
|
|
60
|
+
return 'Please enter a valid path';
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
]);
|
|
66
|
+
const fullPath = path.resolve(repositoryPath.trim());
|
|
67
|
+
if (!fs.existsSync(fullPath)) {
|
|
68
|
+
console.log(chalk.red('❌ Path does not exist'));
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (!fs.statSync(fullPath).isDirectory()) {
|
|
72
|
+
console.log(chalk.red('❌ Path is not a directory'));
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (!this.isGitRepository(fullPath)) {
|
|
76
|
+
console.log(chalk.red('❌ Path is not a git repository'));
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (this.isIvanRepository(fullPath)) {
|
|
80
|
+
console.log(chalk.red('❌ Cannot run Ivan on itself'));
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
console.log(chalk.green(`✅ Using repository: ${fullPath}`));
|
|
84
|
+
return fullPath;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
getRepositoryInfo(workingDir) {
|
|
88
|
+
try {
|
|
89
|
+
const repoName = path.basename(workingDir);
|
|
90
|
+
const branch = execSync('git branch --show-current', {
|
|
91
|
+
cwd: workingDir,
|
|
92
|
+
encoding: 'utf8'
|
|
93
|
+
}).trim();
|
|
94
|
+
return { name: repoName, branch };
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return { name: path.basename(workingDir), branch: 'unknown' };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=repository-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository-manager.js","sourceRoot":"","sources":["../../src/services/repository-manager.ts"],"names":[],"mappings":"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"}
|