| 32 | } |
| 33 | |
| 34 | async function main() { |
| 35 | console.log('Loading items from database...'); |
| 36 | const db = new Database(DB_PATH, { readonly: true }); |
| 37 | |
| 38 | // Get all issues and PRs |
| 39 | const issues = db |
| 40 | .prepare( |
| 41 | ` |
| 42 | SELECT i.id, i.title, i.body, i.number, r.full_name as repo |
| 43 | FROM issues i |
| 44 | JOIN repos r ON i.repo_id = r.id |
| 45 | WHERE i.title IS NOT NULL |
| 46 | `, |
| 47 | ) |
| 48 | .all() as Array<{ |
| 49 | id: number; |
| 50 | title: string; |
| 51 | body: string | null; |
| 52 | number: number; |
| 53 | repo: string; |
| 54 | }>; |
| 55 | |
| 56 | const pulls = db |
| 57 | .prepare( |
| 58 | ` |
| 59 | SELECT p.id, p.title, p.body, p.number, r.full_name as repo |
| 60 | FROM pulls p |
| 61 | JOIN repos r ON p.repo_id = r.id |
| 62 | WHERE p.title IS NOT NULL |
| 63 | `, |
| 64 | ) |
| 65 | .all() as Array<{ |
| 66 | id: number; |
| 67 | title: string; |
| 68 | body: string | null; |
| 69 | number: number; |
| 70 | repo: string; |
| 71 | }>; |
| 72 | |
| 73 | console.log(`Found ${issues.length} issues and ${pulls.length} PRs`); |
| 74 | |
| 75 | const allItems = [ |
| 76 | ...issues.map((i) => ({ ...i, type: 'issue' as const })), |
| 77 | ...pulls.map((p) => ({ ...p, type: 'pull' as const })), |
| 78 | ]; |
| 79 | |
| 80 | console.log(`Total: ${allItems.length} items to embed`); |
| 81 | |
| 82 | // Check for existing embeddings |
| 83 | let existingIndex: EmbeddingIndex | null = null; |
| 84 | let existingEmbeddings: Float32Array | null = null; |
| 85 | |
| 86 | if (existsSync(INDEX_PATH) && existsSync(EMBEDDINGS_PATH)) { |
| 87 | console.log('Found existing embeddings, checking for updates...'); |
| 88 | existingIndex = JSON.parse(readFileSync(INDEX_PATH, 'utf-8')); |
| 89 | const buffer = readFileSync(EMBEDDINGS_PATH); |
| 90 | existingEmbeddings = new Float32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 4); |
| 91 | |