treliq 0.4.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +340 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +540 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/core/cache.d.ts +29 -0
  8. package/dist/core/cache.d.ts.map +1 -0
  9. package/dist/core/cache.js +64 -0
  10. package/dist/core/cache.js.map +1 -0
  11. package/dist/core/concurrency.d.ts +16 -0
  12. package/dist/core/concurrency.d.ts.map +1 -0
  13. package/dist/core/concurrency.js +60 -0
  14. package/dist/core/concurrency.js.map +1 -0
  15. package/dist/core/db.d.ts +127 -0
  16. package/dist/core/db.d.ts.map +1 -0
  17. package/dist/core/db.js +490 -0
  18. package/dist/core/db.js.map +1 -0
  19. package/dist/core/dedup.d.ts +18 -0
  20. package/dist/core/dedup.d.ts.map +1 -0
  21. package/dist/core/dedup.js +159 -0
  22. package/dist/core/dedup.js.map +1 -0
  23. package/dist/core/graphql.d.ts +30 -0
  24. package/dist/core/graphql.d.ts.map +1 -0
  25. package/dist/core/graphql.js +243 -0
  26. package/dist/core/graphql.js.map +1 -0
  27. package/dist/core/notifications.d.ts +37 -0
  28. package/dist/core/notifications.d.ts.map +1 -0
  29. package/dist/core/notifications.js +174 -0
  30. package/dist/core/notifications.js.map +1 -0
  31. package/dist/core/provider.d.ts +45 -0
  32. package/dist/core/provider.d.ts.map +1 -0
  33. package/dist/core/provider.js +147 -0
  34. package/dist/core/provider.js.map +1 -0
  35. package/dist/core/ratelimit.d.ts +40 -0
  36. package/dist/core/ratelimit.d.ts.map +1 -0
  37. package/dist/core/ratelimit.js +77 -0
  38. package/dist/core/ratelimit.js.map +1 -0
  39. package/dist/core/reputation.d.ts +16 -0
  40. package/dist/core/reputation.d.ts.map +1 -0
  41. package/dist/core/reputation.js +59 -0
  42. package/dist/core/reputation.js.map +1 -0
  43. package/dist/core/scanner.d.ts +58 -0
  44. package/dist/core/scanner.d.ts.map +1 -0
  45. package/dist/core/scanner.js +635 -0
  46. package/dist/core/scanner.js.map +1 -0
  47. package/dist/core/scoring.d.ts +36 -0
  48. package/dist/core/scoring.d.ts.map +1 -0
  49. package/dist/core/scoring.js +360 -0
  50. package/dist/core/scoring.js.map +1 -0
  51. package/dist/core/types.d.ts +89 -0
  52. package/dist/core/types.d.ts.map +1 -0
  53. package/dist/core/types.js +6 -0
  54. package/dist/core/types.js.map +1 -0
  55. package/dist/core/vectorstore.d.ts +42 -0
  56. package/dist/core/vectorstore.d.ts.map +1 -0
  57. package/dist/core/vectorstore.js +149 -0
  58. package/dist/core/vectorstore.js.map +1 -0
  59. package/dist/core/vision.d.ts +16 -0
  60. package/dist/core/vision.d.ts.map +1 -0
  61. package/dist/core/vision.js +41 -0
  62. package/dist/core/vision.js.map +1 -0
  63. package/dist/index.d.ts +21 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +34 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/server/app.d.ts +21 -0
  68. package/dist/server/app.d.ts.map +1 -0
  69. package/dist/server/app.js +284 -0
  70. package/dist/server/app.js.map +1 -0
  71. package/dist/server/index.d.ts +29 -0
  72. package/dist/server/index.d.ts.map +1 -0
  73. package/dist/server/index.js +117 -0
  74. package/dist/server/index.js.map +1 -0
  75. package/dist/server/scheduler.d.ts +26 -0
  76. package/dist/server/scheduler.d.ts.map +1 -0
  77. package/dist/server/scheduler.js +136 -0
  78. package/dist/server/scheduler.js.map +1 -0
  79. package/dist/server/sse.d.ts +33 -0
  80. package/dist/server/sse.d.ts.map +1 -0
  81. package/dist/server/sse.js +80 -0
  82. package/dist/server/sse.js.map +1 -0
  83. package/dist/server/webhooks.d.ts +23 -0
  84. package/dist/server/webhooks.d.ts.map +1 -0
  85. package/dist/server/webhooks.js +175 -0
  86. package/dist/server/webhooks.js.map +1 -0
  87. package/package.json +84 -0
package/dist/cli.js ADDED
@@ -0,0 +1,540 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const commander_1 = require("commander");
38
+ const readline_1 = require("readline");
39
+ const rest_1 = require("@octokit/rest");
40
+ const scanner_1 = require("./core/scanner");
41
+ const scoring_1 = require("./core/scoring");
42
+ const dedup_1 = require("./core/dedup");
43
+ const provider_1 = require("./core/provider");
44
+ const program = new commander_1.Command();
45
+ function resolveProvider(opts) {
46
+ const providerName = (opts.provider ?? 'gemini');
47
+ const envKeyMap = {
48
+ gemini: 'GEMINI_API_KEY',
49
+ openai: 'OPENAI_API_KEY',
50
+ anthropic: 'ANTHROPIC_API_KEY',
51
+ };
52
+ const apiKey = opts.apiKey || process.env[envKeyMap[providerName]];
53
+ if (!apiKey)
54
+ return undefined;
55
+ // For Anthropic, create a Gemini fallback for embeddings if available
56
+ let embeddingFallback;
57
+ if (providerName === 'anthropic') {
58
+ const geminiKey = process.env.GEMINI_API_KEY;
59
+ const openaiKey = process.env.OPENAI_API_KEY;
60
+ if (geminiKey)
61
+ embeddingFallback = (0, provider_1.createProvider)('gemini', geminiKey);
62
+ else if (openaiKey)
63
+ embeddingFallback = (0, provider_1.createProvider)('openai', openaiKey);
64
+ }
65
+ return (0, provider_1.createProvider)(providerName, apiKey, embeddingFallback);
66
+ }
67
+ function validateRepo(repo) {
68
+ const parts = repo.split('/');
69
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
70
+ console.error('❌ Invalid repo format. Expected: owner/repo');
71
+ process.exit(1);
72
+ }
73
+ }
74
+ function validateMaxPRs(maxStr) {
75
+ const maxPRs = parseInt(maxStr, 10);
76
+ if (isNaN(maxPRs) || maxPRs < 1 || maxPRs > 5000) {
77
+ console.error('❌ Invalid --max value. Must be 1-5000.');
78
+ process.exit(1);
79
+ }
80
+ return maxPRs;
81
+ }
82
+ function makeConfig(opts) {
83
+ validateRepo(opts.repo);
84
+ const token = opts.token || process.env.GITHUB_TOKEN || '';
85
+ const provider = resolveProvider(opts);
86
+ const maxPRs = validateMaxPRs(opts.max ?? '500');
87
+ return {
88
+ repo: opts.repo,
89
+ token,
90
+ provider,
91
+ geminiApiKey: opts.geminiKey || process.env.GEMINI_API_KEY,
92
+ duplicateThreshold: 0.85,
93
+ relatedThreshold: 0.80,
94
+ maxPRs,
95
+ outputFormat: (opts.format ?? 'table'),
96
+ comment: opts.comment ?? false,
97
+ trustContributors: opts.trustContributors ?? false,
98
+ useCache: opts.noCache ? false : true,
99
+ cacheFile: opts.cacheFile ?? '.treliq-cache.json',
100
+ dbPath: opts.dbPath,
101
+ };
102
+ }
103
+ function outputResult(result, format) {
104
+ if (format === 'json') {
105
+ // Strip embeddings for cleaner output
106
+ const clean = {
107
+ ...result,
108
+ rankedPRs: result.rankedPRs.map(({ embedding, ...rest }) => rest),
109
+ };
110
+ console.log(JSON.stringify(clean, null, 2));
111
+ return;
112
+ }
113
+ if (format === 'markdown') {
114
+ console.log(`# Treliq Report — ${result.repo}\n`);
115
+ console.log(`- **Scanned:** ${result.totalPRs} PRs`);
116
+ console.log(`- **Spam:** ${result.spamCount}`);
117
+ console.log(`- **Duplicate clusters:** ${result.duplicateClusters.length}\n`);
118
+ console.log('## Top PRs\n');
119
+ console.log('| # | Score | LLM | Risk | Title | Author | Age | Conflict | Vision | V.Score |');
120
+ console.log('|---|-------|-----|------|-------|--------|-----|----------|--------|---------|');
121
+ for (const pr of result.rankedPRs.slice(0, 30)) {
122
+ console.log(`| #${pr.number} | ${pr.totalScore} | ${pr.llmScore ?? '-'} | ${pr.llmRisk ?? '-'} | ${pr.title.slice(0, 50)} | @${pr.author} | ${pr.ageInDays}d | ${pr.mergeable} | ${pr.visionAlignment ?? '-'} | ${pr.visionScore ?? '-'} |`);
123
+ }
124
+ if (result.duplicateClusters.length > 0) {
125
+ console.log('\n## Duplicate Clusters\n');
126
+ for (const c of result.duplicateClusters) {
127
+ console.log(`### Cluster ${c.id} (similarity: ${(c.similarity * 100).toFixed(1)}%)`);
128
+ console.log(`Best: #${c.bestPR}`);
129
+ console.log(`PRs: ${c.prs.map(p => `#${p.number}`).join(', ')}\n`);
130
+ }
131
+ }
132
+ return;
133
+ }
134
+ // Table format (default)
135
+ console.log(`\n🔍 Treliq Report — ${result.repo}`);
136
+ console.log(` ${result.totalPRs} PRs scanned | ${result.spamCount} spam | ${result.duplicateClusters.length} dup clusters\n`);
137
+ const rows = result.rankedPRs.slice(0, 30).map(pr => ({
138
+ '#': pr.number,
139
+ Score: pr.totalScore,
140
+ LLM: pr.llmScore ?? '-',
141
+ Risk: pr.llmRisk ?? '-',
142
+ Title: pr.title.slice(0, 45),
143
+ Author: pr.author.slice(0, 12),
144
+ Age: `${pr.ageInDays}d`,
145
+ Conflict: pr.mergeable,
146
+ CI: pr.ciStatus,
147
+ 'V.Score': pr.visionScore ?? '-',
148
+ Vision: pr.visionAlignment === 'unchecked' ? 'N/A' : (pr.visionAlignment ?? 'No doc'),
149
+ Spam: pr.isSpam ? '🚩 Spam' : 'Clean',
150
+ Dup: pr.duplicateGroup !== undefined ? `G${pr.duplicateGroup}` : '—',
151
+ }));
152
+ console.table(rows);
153
+ if (result.duplicateClusters.length > 0) {
154
+ console.log('\n🔄 Duplicate Clusters:');
155
+ for (const c of result.duplicateClusters) {
156
+ console.log(` Cluster ${c.id}: ${c.prs.map(p => `#${p.number}`).join(', ')} (best: #${c.bestPR}, sim: ${(c.similarity * 100).toFixed(1)}%)`);
157
+ }
158
+ }
159
+ console.log(`\n📝 ${result.summary}`);
160
+ }
161
+ function outputScoredPR(scored, format) {
162
+ if (format === 'json') {
163
+ console.log(JSON.stringify(scored, null, 2));
164
+ }
165
+ else if (format === 'markdown') {
166
+ console.log(`## 🎯 Treliq Score — PR #${scored.number}\n`);
167
+ console.log(`**${scored.title}** by @${scored.author}\n`);
168
+ console.log(`| Metric | Value |`);
169
+ console.log(`|--------|-------|`);
170
+ console.log(`| **Total Score** | **${scored.totalScore}/100** |`);
171
+ console.log(`| Spam | ${scored.isSpam ? '🚩 Spam' : '✅ Clean'} |`);
172
+ console.log(`| Files Changed | ${scored.filesChanged} |`);
173
+ console.log(`| +${scored.additions} / -${scored.deletions} | ${scored.commits} commits |`);
174
+ if (scored.llmScore != null)
175
+ console.log(`| LLM Quality | ${scored.llmScore}/100 (${scored.llmRisk}) |`);
176
+ if (scored.visionScore != null)
177
+ console.log(`| Vision Alignment | ${scored.visionScore}/100 (${scored.visionAlignment}) |`);
178
+ console.log(`\n### Signal Breakdown\n`);
179
+ console.log(`| Signal | Score | Weight | Reason |`);
180
+ console.log(`|--------|-------|--------|--------|`);
181
+ for (const s of scored.signals) {
182
+ console.log(`| ${s.name} | ${s.score}/100 | ${s.weight} | ${s.reason} |`);
183
+ }
184
+ }
185
+ else {
186
+ console.log(`\n🎯 PR #${scored.number}: ${scored.title}`);
187
+ console.log(` Score: ${scored.totalScore}/100 | Spam: ${scored.isSpam ? 'Yes' : 'No'}\n`);
188
+ console.log(' Signals:');
189
+ for (const s of scored.signals) {
190
+ console.log(` ${s.name.padEnd(16)} ${String(s.score).padStart(3)}/100 (w: ${s.weight}) — ${s.reason}`);
191
+ }
192
+ }
193
+ }
194
+ program
195
+ .name('treliq')
196
+ .description('AI-Powered PR Triage for Open Source Maintainers')
197
+ .version('0.4.0');
198
+ program
199
+ .command('scan')
200
+ .description('Scan all open PRs in a repository')
201
+ .requiredOption('-r, --repo <owner/repo>', 'GitHub repository')
202
+ .option('-t, --token <token>', 'GitHub token (or GITHUB_TOKEN env)')
203
+ .option('-k, --gemini-key <key>', 'Gemini API key (or GEMINI_API_KEY env)')
204
+ .option('-p, --provider <name>', 'LLM provider: gemini|openai|anthropic', 'gemini')
205
+ .option('--api-key <key>', 'API key for the selected provider')
206
+ .option('-f, --format <format>', 'Output format: table|json|markdown', 'table')
207
+ .option('-m, --max <number>', 'Max PRs to scan', '500')
208
+ .option('--comment', 'Post results as PR comments', false)
209
+ .option('--trust-contributors', 'Exempt known contributors from spam detection', false)
210
+ .option('--no-cache', 'Force full rescan, ignore cache')
211
+ .option('--cache-file <path>', 'Custom cache file path', '.treliq-cache.json')
212
+ .action(async (opts) => {
213
+ const config = makeConfig(opts);
214
+ if (!config.token) {
215
+ console.error('❌ GITHUB_TOKEN required. Set via env or --token flag.');
216
+ process.exit(1);
217
+ }
218
+ const scanner = new scanner_1.TreliqScanner(config);
219
+ const result = await scanner.scan();
220
+ outputResult(result, config.outputFormat);
221
+ });
222
+ program
223
+ .command('score')
224
+ .description('Score a single PR')
225
+ .requiredOption('-r, --repo <owner/repo>', 'GitHub repository')
226
+ .requiredOption('-n, --pr <number>', 'PR number')
227
+ .option('-t, --token <token>', 'GitHub token')
228
+ .option('-p, --provider <name>', 'LLM provider: gemini|openai|anthropic', 'gemini')
229
+ .option('--api-key <key>', 'API key for the selected provider')
230
+ .option('-f, --format <format>', 'Output format', 'table')
231
+ .action(async (opts) => {
232
+ const config = makeConfig(opts);
233
+ if (!config.token) {
234
+ console.error('❌ GITHUB_TOKEN required.');
235
+ process.exit(1);
236
+ }
237
+ const prNum = parseInt(opts.pr, 10);
238
+ if (isNaN(prNum) || prNum < 1) {
239
+ console.error('❌ Invalid PR number.');
240
+ process.exit(1);
241
+ }
242
+ // Use scanner's fetchPRDetails to avoid code duplication
243
+ const scanner = new scanner_1.TreliqScanner({ ...config, maxPRs: 1 });
244
+ const prs = await scanner.fetchPRDetails([prNum]);
245
+ if (prs.length === 0) {
246
+ console.error(`❌ PR #${prNum} not found or could not be fetched.`);
247
+ process.exit(1);
248
+ }
249
+ const engine = new scoring_1.ScoringEngine(config.provider, config.trustContributors);
250
+ const scored = await engine.score(prs[0]);
251
+ outputScoredPR(scored, opts.format ?? 'table');
252
+ });
253
+ program
254
+ .command('dedup')
255
+ .description('Find duplicate PR groups')
256
+ .requiredOption('-r, --repo <owner/repo>', 'GitHub repository')
257
+ .option('-t, --token <token>', 'GitHub token')
258
+ .option('-k, --gemini-key <key>', 'Gemini API key')
259
+ .option('-p, --provider <name>', 'LLM provider: gemini|openai|anthropic', 'gemini')
260
+ .option('--api-key <key>', 'API key for the selected provider')
261
+ .option('-f, --format <format>', 'Output format', 'table')
262
+ .option('-m, --max <number>', 'Max PRs', '500')
263
+ .action(async (opts) => {
264
+ const config = makeConfig(opts);
265
+ if (!config.token) {
266
+ console.error('❌ GITHUB_TOKEN required.');
267
+ process.exit(1);
268
+ }
269
+ if (!config.provider) {
270
+ console.error('❌ API key required for dedup. Set via --api-key or env var.');
271
+ process.exit(1);
272
+ }
273
+ const scanner = new scanner_1.TreliqScanner(config);
274
+ const prs = await scanner.fetchPRs();
275
+ console.log(`📊 Scoring ${prs.length} PRs...`);
276
+ const engine = new scoring_1.ScoringEngine(config.provider, config.trustContributors);
277
+ const scored = [];
278
+ for (const pr of prs)
279
+ scored.push(await engine.score(pr));
280
+ const dedup = new dedup_1.DedupEngine(config.duplicateThreshold, config.relatedThreshold, config.provider);
281
+ const clusters = await dedup.findDuplicates(scored);
282
+ if (opts.format === 'json') {
283
+ console.log(JSON.stringify(clusters, null, 2));
284
+ }
285
+ else {
286
+ console.log(`\n🔄 Found ${clusters.length} duplicate clusters:\n`);
287
+ for (const c of clusters) {
288
+ console.log(` Cluster ${c.id} (sim: ${(c.similarity * 100).toFixed(1)}%):`);
289
+ for (const pr of c.prs) {
290
+ const marker = pr.number === c.bestPR ? '⭐' : ' ';
291
+ console.log(` ${marker} #${pr.number} (${pr.totalScore}) ${pr.title.slice(0, 60)}`);
292
+ }
293
+ console.log();
294
+ }
295
+ }
296
+ });
297
+ program
298
+ .command('close-spam')
299
+ .description('Close PRs identified as spam')
300
+ .requiredOption('-r, --repo <owner/repo>', 'GitHub repository')
301
+ .option('-t, --token <token>', 'GitHub token (or GITHUB_TOKEN env)')
302
+ .option('-p, --provider <name>', 'LLM provider: gemini|openai|anthropic', 'gemini')
303
+ .option('--api-key <key>', 'API key for the selected provider')
304
+ .option('--threshold <score>', 'Score threshold for spam detection', '25')
305
+ .option('--dry-run', 'Preview only, do not close PRs', false)
306
+ .option('--message <text>', 'Custom close comment')
307
+ .action(async (opts) => {
308
+ const config = makeConfig(opts);
309
+ if (!config.token) {
310
+ console.error('❌ GITHUB_TOKEN required.');
311
+ process.exit(1);
312
+ }
313
+ const threshold = parseInt(opts.threshold ?? '25', 10);
314
+ if (isNaN(threshold)) {
315
+ console.error('❌ Invalid threshold value.');
316
+ process.exit(1);
317
+ }
318
+ console.log(`🔍 Scanning for spam PRs (threshold: ${threshold})...`);
319
+ const scanner = new scanner_1.TreliqScanner(config);
320
+ const result = await scanner.scan();
321
+ const spamPRs = result.rankedPRs.filter(pr => pr.isSpam && pr.totalScore <= threshold);
322
+ if (spamPRs.length === 0) {
323
+ console.log('✅ No spam PRs found matching criteria.');
324
+ return;
325
+ }
326
+ console.log(`\n🚩 Found ${spamPRs.length} spam PRs:\n`);
327
+ for (const pr of spamPRs) {
328
+ console.log(` #${pr.number} - ${pr.title} (score: ${pr.totalScore}, by @${pr.author})`);
329
+ }
330
+ if (opts.dryRun) {
331
+ console.log('\n🔍 Dry run complete. No PRs were closed.');
332
+ return;
333
+ }
334
+ // Prompt for confirmation
335
+ const rl = (0, readline_1.createInterface)({
336
+ input: process.stdin,
337
+ output: process.stdout,
338
+ });
339
+ const answer = await new Promise(resolve => {
340
+ rl.question(`\n⚠️ Close ${spamPRs.length} spam PRs? (yes/no): `, resolve);
341
+ });
342
+ rl.close();
343
+ if (answer.toLowerCase() !== 'yes') {
344
+ console.log('❌ Operation cancelled.');
345
+ return;
346
+ }
347
+ const [owner, repo] = config.repo.split('/');
348
+ const octokit = new rest_1.Octokit({ auth: config.token });
349
+ const closeMessage = opts.message || 'This PR has been automatically closed as it was identified as spam by Treliq.';
350
+ console.log('\n🔨 Closing spam PRs...');
351
+ for (const pr of spamPRs) {
352
+ try {
353
+ // Post comment
354
+ await octokit.issues.createComment({
355
+ owner,
356
+ repo,
357
+ issue_number: pr.number,
358
+ body: closeMessage,
359
+ });
360
+ // Close PR
361
+ await octokit.pulls.update({
362
+ owner,
363
+ repo,
364
+ pull_number: pr.number,
365
+ state: 'closed',
366
+ });
367
+ console.log(` ✅ Closed #${pr.number}`);
368
+ }
369
+ catch (error) {
370
+ console.error(` ❌ Failed to close #${pr.number}: ${error.message}`);
371
+ }
372
+ }
373
+ console.log(`\n✅ Closed ${spamPRs.length} spam PRs.`);
374
+ });
375
+ program
376
+ .command('label-by-score')
377
+ .description('Apply priority labels based on PR scores')
378
+ .requiredOption('-r, --repo <owner/repo>', 'GitHub repository')
379
+ .option('-t, --token <token>', 'GitHub token (or GITHUB_TOKEN env)')
380
+ .option('-p, --provider <name>', 'LLM provider: gemini|openai|anthropic', 'gemini')
381
+ .option('--api-key <key>', 'API key for the selected provider')
382
+ .option('--high <score>', 'High priority threshold', '80')
383
+ .option('--medium <score>', 'Medium priority threshold', '50')
384
+ .option('--dry-run', 'Preview only, do not apply labels', false)
385
+ .action(async (opts) => {
386
+ const config = makeConfig(opts);
387
+ if (!config.token) {
388
+ console.error('❌ GITHUB_TOKEN required.');
389
+ process.exit(1);
390
+ }
391
+ const highThreshold = parseInt(opts.high ?? '80', 10);
392
+ const mediumThreshold = parseInt(opts.medium ?? '50', 10);
393
+ if (isNaN(highThreshold) || isNaN(mediumThreshold)) {
394
+ console.error('❌ Invalid threshold values.');
395
+ process.exit(1);
396
+ }
397
+ console.log(`🔍 Scanning and scoring PRs...`);
398
+ const scanner = new scanner_1.TreliqScanner(config);
399
+ const result = await scanner.scan();
400
+ const highPRs = result.rankedPRs.filter(pr => !pr.isSpam && pr.totalScore >= highThreshold);
401
+ const mediumPRs = result.rankedPRs.filter(pr => !pr.isSpam && pr.totalScore >= mediumThreshold && pr.totalScore < highThreshold);
402
+ const lowPRs = result.rankedPRs.filter(pr => !pr.isSpam && pr.totalScore < mediumThreshold);
403
+ console.log(`\n📊 Label Distribution:\n`);
404
+ console.log(` 🔴 High Priority (>=${highThreshold}): ${highPRs.length} PRs`);
405
+ console.log(` 🟡 Medium Priority (${mediumThreshold}-${highThreshold}): ${mediumPRs.length} PRs`);
406
+ console.log(` 🟢 Low Priority (<${mediumThreshold}): ${lowPRs.length} PRs`);
407
+ if (opts.dryRun) {
408
+ console.log('\n🔍 Dry run complete. No labels were applied.');
409
+ return;
410
+ }
411
+ const [owner, repo] = config.repo.split('/');
412
+ const octokit = new rest_1.Octokit({ auth: config.token });
413
+ console.log('\n🏷️ Applying labels...');
414
+ const labelMap = [
415
+ { prs: highPRs, label: 'treliq:high-priority', emoji: '🔴' },
416
+ { prs: mediumPRs, label: 'treliq:medium-priority', emoji: '🟡' },
417
+ { prs: lowPRs, label: 'treliq:low-priority', emoji: '🟢' },
418
+ ];
419
+ for (const { prs, label, emoji } of labelMap) {
420
+ for (const pr of prs) {
421
+ try {
422
+ await octokit.issues.addLabels({
423
+ owner,
424
+ repo,
425
+ issue_number: pr.number,
426
+ labels: [label],
427
+ });
428
+ console.log(` ${emoji} #${pr.number}: ${label}`);
429
+ }
430
+ catch (error) {
431
+ console.error(` ❌ Failed to label #${pr.number}: ${error.message}`);
432
+ }
433
+ }
434
+ }
435
+ console.log('\n✅ Labels applied successfully.');
436
+ });
437
+ program
438
+ .command('reset')
439
+ .description('Clear all PR data and scan history for a repository')
440
+ .requiredOption('-r, --repo <owner/repo>', 'GitHub repository')
441
+ .option('--db-path <path>', 'SQLite database path', './treliq.db')
442
+ .action(async (opts) => {
443
+ validateRepo(opts.repo);
444
+ const dbPath = opts.dbPath ?? './treliq.db';
445
+ const [owner, repo] = opts.repo.split('/');
446
+ const { TreliqDB } = await Promise.resolve().then(() => __importStar(require('./core/db')));
447
+ const db = new TreliqDB(dbPath);
448
+ const repoId = db.upsertRepository(owner, repo);
449
+ const stats = db.getRepositoryStats(repoId);
450
+ if (stats.totalPRs === 0) {
451
+ console.log(`ℹ️ No data found for ${opts.repo}. Nothing to clear.`);
452
+ db.close();
453
+ return;
454
+ }
455
+ console.log(`\n⚠️ About to clear data for ${opts.repo}:`);
456
+ console.log(` ${stats.totalPRs} PRs, ${stats.spamPRs} spam, ${stats.duplicateGroups} duplicate groups`);
457
+ const rl = (0, readline_1.createInterface)({ input: process.stdin, output: process.stdout });
458
+ const answer = await new Promise(resolve => {
459
+ rl.question('\n Delete all data? (yes/no): ', resolve);
460
+ });
461
+ rl.close();
462
+ if (answer.toLowerCase() !== 'yes') {
463
+ console.log('❌ Operation cancelled.');
464
+ db.close();
465
+ return;
466
+ }
467
+ const result = db.clearRepository(repoId);
468
+ db.optimize();
469
+ db.close();
470
+ console.log(`\n✅ Cleared: ${result.deletedPRs} PRs, ${result.deletedScans} scan records removed.`);
471
+ console.log(` Database optimized. Ready for fresh scan.`);
472
+ });
473
+ program
474
+ .command('server')
475
+ .description('Start Treliq server with web UI and scheduled scanning')
476
+ .option('--port <number>', 'Server port', '3000')
477
+ .option('--host <host>', 'Server host', '0.0.0.0')
478
+ .option('--db-path <path>', 'SQLite database path', './treliq.db')
479
+ .option('-t, --token <token>', 'GitHub token (or GITHUB_TOKEN env)')
480
+ .option('-p, --provider <name>', 'LLM provider: gemini|openai|anthropic', 'gemini')
481
+ .option('--api-key <key>', 'API key for the selected provider')
482
+ .option('--schedule <repos>', 'Comma-separated repos for hourly scanning')
483
+ .option('--cron <expression>', 'Custom cron expression', '0 * * * *')
484
+ .option('--webhook-secret <secret>', 'GitHub webhook secret')
485
+ .option('--slack-webhook <url>', 'Slack webhook URL')
486
+ .option('--discord-webhook <url>', 'Discord webhook URL')
487
+ .action(async (opts) => {
488
+ const token = opts.token || process.env.GITHUB_TOKEN;
489
+ if (!token) {
490
+ console.error('❌ GITHUB_TOKEN required for server mode.');
491
+ process.exit(1);
492
+ }
493
+ const port = parseInt(opts.port ?? '3000', 10);
494
+ const host = opts.host ?? '0.0.0.0';
495
+ const dbPath = opts.dbPath ?? './treliq.db';
496
+ const provider = resolveProvider(opts);
497
+ const scheduledRepos = opts.schedule?.split(',').map(r => r.trim()).filter(Boolean) || [];
498
+ const cronExpression = opts.cron ?? '0 * * * *';
499
+ const serverConfig = {
500
+ port,
501
+ host,
502
+ dbPath,
503
+ treliqConfig: {
504
+ repo: scheduledRepos[0] ?? '',
505
+ token,
506
+ provider,
507
+ duplicateThreshold: 0.85,
508
+ relatedThreshold: 0.80,
509
+ maxPRs: 500,
510
+ outputFormat: 'json',
511
+ comment: false,
512
+ trustContributors: false,
513
+ useCache: true,
514
+ cacheFile: '.treliq-cache.json',
515
+ dbPath,
516
+ },
517
+ webhookSecret: opts.webhookSecret,
518
+ scheduledRepos,
519
+ cronExpression,
520
+ slackWebhook: opts.slackWebhook,
521
+ discordWebhook: opts.discordWebhook,
522
+ };
523
+ console.log(`🚀 Starting Treliq server on ${host}:${port}...`);
524
+ console.log(` Database: ${dbPath}`);
525
+ if (scheduledRepos.length > 0) {
526
+ console.log(` Scheduled repos: ${scheduledRepos.join(', ')}`);
527
+ console.log(` Cron: ${cronExpression}`);
528
+ }
529
+ try {
530
+ // Dynamic import to avoid loading heavy dependencies for CLI-only users
531
+ const { startServer } = await Promise.resolve().then(() => __importStar(require('./server')));
532
+ await startServer(serverConfig);
533
+ }
534
+ catch (error) {
535
+ console.error(`❌ Failed to start server: ${error.message}`);
536
+ process.exit(1);
537
+ }
538
+ });
539
+ program.parse();
540
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Incremental cache for Treliq — skips re-scanning unchanged PRs
3
+ */
4
+ import type { ScoredPR } from './types';
5
+ export interface CachedPR {
6
+ updatedAt: string;
7
+ headSha: string;
8
+ scoredPR: Omit<ScoredPR, 'embedding'>;
9
+ }
10
+ export interface TreliqCache {
11
+ repo: string;
12
+ lastScan: string;
13
+ configHash: string;
14
+ prs: Record<string, CachedPR>;
15
+ }
16
+ /** Generate a hash of config options that affect scoring results */
17
+ export declare function configHash(opts: {
18
+ trustContributors: boolean;
19
+ providerName?: string;
20
+ }): string;
21
+ export declare function loadCache(cacheFile: string, repo: string, hash?: string): TreliqCache | null;
22
+ export declare function saveCache(cacheFile: string, repo: string, scored: ScoredPR[], shaMap: Map<number, string>, hash?: string): void;
23
+ export interface PRListItem {
24
+ number: number;
25
+ updatedAt: string;
26
+ headSha: string;
27
+ }
28
+ export declare function getCacheHit(cache: TreliqCache, item: PRListItem): ScoredPR | null;
29
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CAC/B;AAED,oEAAoE;AACpE,wBAAgB,UAAU,CAAC,IAAI,EAAE;IAAE,iBAAiB,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAM9F;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAc5F;AAED,wBAAgB,SAAS,CACvB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,EAAE,EAClB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAgBN;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAOjF"}