@ariso-ai/ivan 1.0.25 → 1.0.28
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/config.js +11 -11
- package/dist/config.js.map +1 -1
- package/dist/database/migrations/016_create_reviews_table.d.ts +3 -0
- package/dist/database/migrations/016_create_reviews_table.d.ts.map +1 -0
- package/dist/database/migrations/016_create_reviews_table.js +19 -0
- package/dist/database/migrations/016_create_reviews_table.js.map +1 -0
- package/dist/database/migrations/016_create_session_analyses_table.d.ts +3 -0
- package/dist/database/migrations/016_create_session_analyses_table.d.ts.map +1 -0
- package/dist/database/migrations/016_create_session_analyses_table.js +19 -0
- package/dist/database/migrations/016_create_session_analyses_table.js.map +1 -0
- package/dist/database/migrations/index.d.ts.map +1 -1
- package/dist/database/migrations/index.js +3 -1
- package/dist/database/migrations/index.js.map +1 -1
- package/dist/database.d.ts +2 -0
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +3 -0
- package/dist/database.js.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/learnings/coding-sessions-command.d.ts +12 -0
- package/dist/learnings/coding-sessions-command.d.ts.map +1 -0
- package/dist/learnings/coding-sessions-command.js +274 -0
- package/dist/learnings/coding-sessions-command.js.map +1 -0
- package/dist/learnings/database.js +1 -1
- package/dist/learnings/database.js.map +1 -1
- package/dist/learnings/embeddings.d.ts.map +1 -1
- package/dist/learnings/embeddings.js +15 -2
- package/dist/learnings/embeddings.js.map +1 -1
- package/dist/learnings/index.d.ts +1 -1
- package/dist/learnings/index.d.ts.map +1 -1
- package/dist/learnings/index.js +23 -11
- package/dist/learnings/index.js.map +1 -1
- package/dist/learnings/install-hooks-command.js +2 -2
- package/dist/learnings/session-analyzer.d.ts +39 -0
- package/dist/learnings/session-analyzer.d.ts.map +1 -0
- package/dist/learnings/session-analyzer.js +339 -0
- package/dist/learnings/session-analyzer.js.map +1 -0
- package/dist/learnings/session-parser.d.ts +46 -0
- package/dist/learnings/session-parser.d.ts.map +1 -0
- package/dist/learnings/session-parser.js +235 -0
- package/dist/learnings/session-parser.js.map +1 -0
- package/dist/services/review-executor.d.ts +8 -0
- package/dist/services/review-executor.d.ts.map +1 -0
- package/dist/services/review-executor.js +159 -0
- package/dist/services/review-executor.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { randomUUID } from 'crypto';
|
|
4
|
+
import { DatabaseManager } from '../database.js';
|
|
5
|
+
import { ExecutorFactory } from './executor-factory.js';
|
|
6
|
+
export class ReviewExecutor {
|
|
7
|
+
dbManager;
|
|
8
|
+
constructor() {
|
|
9
|
+
this.dbManager = new DatabaseManager();
|
|
10
|
+
}
|
|
11
|
+
async executeReviews(prNumbers) {
|
|
12
|
+
const workingDir = process.cwd();
|
|
13
|
+
console.log(chalk.blue.bold(`🔍 Reviewing ${prNumbers.length} PR(s)...`));
|
|
14
|
+
console.log('');
|
|
15
|
+
for (const prNumber of prNumbers) {
|
|
16
|
+
await this.reviewPR(prNumber, workingDir);
|
|
17
|
+
console.log('');
|
|
18
|
+
}
|
|
19
|
+
this.dbManager.close();
|
|
20
|
+
console.log(chalk.green.bold('✅ All reviews completed!'));
|
|
21
|
+
console.log(chalk.gray('Run "ivan web" to view reviews in the dashboard.'));
|
|
22
|
+
}
|
|
23
|
+
async reviewPR(prNumber, workingDir) {
|
|
24
|
+
const db = this.dbManager.getKysely();
|
|
25
|
+
const now = new Date().toISOString();
|
|
26
|
+
const reviewUuid = randomUUID();
|
|
27
|
+
console.log(chalk.blue(`📋 Reviewing PR #${prNumber}...`));
|
|
28
|
+
// Fetch PR metadata
|
|
29
|
+
let prUrl = null;
|
|
30
|
+
let prTitle = null;
|
|
31
|
+
let repositoryId = null;
|
|
32
|
+
try {
|
|
33
|
+
const prJson = execSync(`gh pr view ${prNumber} --json number,title,url`, { cwd: workingDir, encoding: 'utf-8' });
|
|
34
|
+
const pr = JSON.parse(prJson);
|
|
35
|
+
prUrl = pr.url;
|
|
36
|
+
prTitle = pr.title;
|
|
37
|
+
console.log(chalk.gray(` Title: ${prTitle}`));
|
|
38
|
+
console.log(chalk.gray(` URL: ${prUrl}`));
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error(chalk.red(`❌ Failed to fetch PR #${prNumber} metadata:`), error);
|
|
42
|
+
}
|
|
43
|
+
// Look up repository_id from the DB
|
|
44
|
+
try {
|
|
45
|
+
const remoteUrl = execSync('git config --get remote.origin.url', {
|
|
46
|
+
cwd: workingDir,
|
|
47
|
+
encoding: 'utf-8'
|
|
48
|
+
}).trim();
|
|
49
|
+
const repo = await db
|
|
50
|
+
.selectFrom('repositories')
|
|
51
|
+
.select('id')
|
|
52
|
+
.where('remote_url', '=', remoteUrl)
|
|
53
|
+
.executeTakeFirst();
|
|
54
|
+
if (repo)
|
|
55
|
+
repositoryId = repo.id;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Ignore — repository may not be registered
|
|
59
|
+
}
|
|
60
|
+
// Create the review record as 'running'
|
|
61
|
+
await db
|
|
62
|
+
.insertInto('reviews')
|
|
63
|
+
.values({
|
|
64
|
+
uuid: reviewUuid,
|
|
65
|
+
pr_number: prNumber,
|
|
66
|
+
pr_url: prUrl,
|
|
67
|
+
pr_title: prTitle,
|
|
68
|
+
repository_id: repositoryId,
|
|
69
|
+
status: 'running',
|
|
70
|
+
review_content: null,
|
|
71
|
+
execution_log: null,
|
|
72
|
+
created_at: now,
|
|
73
|
+
updated_at: now
|
|
74
|
+
})
|
|
75
|
+
.execute();
|
|
76
|
+
// Build the review prompt using the PR diff
|
|
77
|
+
let prDiff = '';
|
|
78
|
+
let prFiles = '';
|
|
79
|
+
try {
|
|
80
|
+
prDiff = execSync(`gh pr diff ${prNumber}`, {
|
|
81
|
+
cwd: workingDir,
|
|
82
|
+
encoding: 'utf-8',
|
|
83
|
+
maxBuffer: 10 * 1024 * 1024
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
console.warn(chalk.yellow(` ⚠️ Could not fetch diff for PR #${prNumber}`));
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
prFiles = execSync(`gh pr view ${prNumber} --json files --jq '.files[].path'`, { cwd: workingDir, encoding: 'utf-8' });
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Ignore
|
|
94
|
+
}
|
|
95
|
+
const prompt = `You are a senior software engineer performing a thorough code review of PR #${prNumber}.
|
|
96
|
+
|
|
97
|
+
${prTitle ? `PR Title: ${prTitle}` : ''}
|
|
98
|
+
${prUrl ? `PR URL: ${prUrl}` : ''}
|
|
99
|
+
${prFiles ? `\nChanged files:\n${prFiles}` : ''}
|
|
100
|
+
|
|
101
|
+
${prDiff ? `\nDiff:\n\`\`\`diff\n${prDiff}\n\`\`\`` : 'No diff available — review the PR branch directly.'}
|
|
102
|
+
|
|
103
|
+
Please review this pull request and provide:
|
|
104
|
+
1. A brief summary of what the PR does
|
|
105
|
+
2. Potential bugs or logic errors
|
|
106
|
+
3. Security concerns (if any)
|
|
107
|
+
4. Code quality and maintainability issues
|
|
108
|
+
5. Suggestions for improvement
|
|
109
|
+
6. Overall verdict: Approve / Request Changes / Comment
|
|
110
|
+
|
|
111
|
+
Format your review clearly with sections and be specific about file and line references where applicable.
|
|
112
|
+
After completing your review, output the final review as plain text starting with the line: "## Code Review: PR #${prNumber}"`;
|
|
113
|
+
try {
|
|
114
|
+
const executor = ExecutorFactory.getExecutor();
|
|
115
|
+
executor.quietMode = false;
|
|
116
|
+
const { log, lastMessage } = await executor.executeTask(prompt, workingDir);
|
|
117
|
+
// Extract the review content from the last message or log
|
|
118
|
+
const reviewContent = this.extractReviewContent(lastMessage, log, prNumber);
|
|
119
|
+
await db
|
|
120
|
+
.updateTable('reviews')
|
|
121
|
+
.set({
|
|
122
|
+
status: 'completed',
|
|
123
|
+
review_content: reviewContent,
|
|
124
|
+
execution_log: log,
|
|
125
|
+
updated_at: new Date().toISOString()
|
|
126
|
+
})
|
|
127
|
+
.where('uuid', '=', reviewUuid)
|
|
128
|
+
.execute();
|
|
129
|
+
console.log(chalk.green(` ✅ Review for PR #${prNumber} completed.`));
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
133
|
+
await db
|
|
134
|
+
.updateTable('reviews')
|
|
135
|
+
.set({
|
|
136
|
+
status: 'failed',
|
|
137
|
+
execution_log: errorMsg,
|
|
138
|
+
updated_at: new Date().toISOString()
|
|
139
|
+
})
|
|
140
|
+
.where('uuid', '=', reviewUuid)
|
|
141
|
+
.execute();
|
|
142
|
+
console.error(chalk.red(` ❌ Review for PR #${prNumber} failed: ${errorMsg}`));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
extractReviewContent(lastMessage, log, prNumber) {
|
|
146
|
+
const marker = `## Code Review: PR #${prNumber}`;
|
|
147
|
+
// Try to find the structured review in the last message first
|
|
148
|
+
const inLast = lastMessage.indexOf(marker);
|
|
149
|
+
if (inLast !== -1)
|
|
150
|
+
return lastMessage.slice(inLast);
|
|
151
|
+
// Fall back to scanning the execution log
|
|
152
|
+
const inLog = log.indexOf(marker);
|
|
153
|
+
if (inLog !== -1)
|
|
154
|
+
return log.slice(inLog);
|
|
155
|
+
// If Claude didn't use the marker, return the last message as-is
|
|
156
|
+
return lastMessage || log;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=review-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-executor.js","sourceRoot":"","sources":["../../src/services/review-executor.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ariso-ai/ivan",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.28",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -73,6 +73,6 @@
|
|
|
73
73
|
"kysely": "^0.28.5",
|
|
74
74
|
"openai": "^5.16.0",
|
|
75
75
|
"ora": "^8.2.0",
|
|
76
|
-
"sqlite-vec": "^0.1.
|
|
76
|
+
"sqlite-vec": "^0.1.9"
|
|
77
77
|
}
|
|
78
78
|
}
|