hirebase-mcp 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.
Files changed (227) hide show
  1. package/README.md +133 -0
  2. package/dist/application/dto/candidate-summary.d.ts +10 -0
  3. package/dist/application/dto/candidate-summary.js +2 -0
  4. package/dist/application/dto/candidate-summary.js.map +1 -0
  5. package/dist/application/dto/extracted-cv.d.ts +43 -0
  6. package/dist/application/dto/extracted-cv.js +2 -0
  7. package/dist/application/dto/extracted-cv.js.map +1 -0
  8. package/dist/application/dto/filter-input.d.ts +7 -0
  9. package/dist/application/dto/filter-input.js +2 -0
  10. package/dist/application/dto/filter-input.js.map +1 -0
  11. package/dist/application/dto/index.d.ts +5 -0
  12. package/dist/application/dto/index.js +2 -0
  13. package/dist/application/dto/index.js.map +1 -0
  14. package/dist/application/dto/search-results.d.ts +13 -0
  15. package/dist/application/dto/search-results.js +2 -0
  16. package/dist/application/dto/search-results.js.map +1 -0
  17. package/dist/application/dto/stats.d.ts +8 -0
  18. package/dist/application/dto/stats.js +2 -0
  19. package/dist/application/dto/stats.js.map +1 -0
  20. package/dist/application/ports/document-parser.d.ts +8 -0
  21. package/dist/application/ports/document-parser.js +2 -0
  22. package/dist/application/ports/document-parser.js.map +1 -0
  23. package/dist/application/ports/embedding-service.d.ts +4 -0
  24. package/dist/application/ports/embedding-service.js +2 -0
  25. package/dist/application/ports/embedding-service.js.map +1 -0
  26. package/dist/application/ports/export-service.d.ts +5 -0
  27. package/dist/application/ports/export-service.js +2 -0
  28. package/dist/application/ports/export-service.js.map +1 -0
  29. package/dist/application/ports/index.d.ts +4 -0
  30. package/dist/application/ports/index.js +2 -0
  31. package/dist/application/ports/index.js.map +1 -0
  32. package/dist/application/ports/structured-extractor.d.ts +4 -0
  33. package/dist/application/ports/structured-extractor.js +2 -0
  34. package/dist/application/ports/structured-extractor.js.map +1 -0
  35. package/dist/application/use-cases/add-cv.d.ts +15 -0
  36. package/dist/application/use-cases/add-cv.js +88 -0
  37. package/dist/application/use-cases/add-cv.js.map +1 -0
  38. package/dist/application/use-cases/bulk-add-cvs.d.ts +14 -0
  39. package/dist/application/use-cases/bulk-add-cvs.js +32 -0
  40. package/dist/application/use-cases/bulk-add-cvs.js.map +1 -0
  41. package/dist/application/use-cases/delete-cv.d.ts +10 -0
  42. package/dist/application/use-cases/delete-cv.js +21 -0
  43. package/dist/application/use-cases/delete-cv.js.map +1 -0
  44. package/dist/application/use-cases/export-results.d.ts +9 -0
  45. package/dist/application/use-cases/export-results.js +21 -0
  46. package/dist/application/use-cases/export-results.js.map +1 -0
  47. package/dist/application/use-cases/filter-candidates.d.ts +9 -0
  48. package/dist/application/use-cases/filter-candidates.js +51 -0
  49. package/dist/application/use-cases/filter-candidates.js.map +1 -0
  50. package/dist/application/use-cases/get-cv-chunks.d.ts +15 -0
  51. package/dist/application/use-cases/get-cv-chunks.js +18 -0
  52. package/dist/application/use-cases/get-cv-chunks.js.map +1 -0
  53. package/dist/application/use-cases/get-cv-detail.d.ts +7 -0
  54. package/dist/application/use-cases/get-cv-detail.js +15 -0
  55. package/dist/application/use-cases/get-cv-detail.js.map +1 -0
  56. package/dist/application/use-cases/get-cv-versions.d.ts +9 -0
  57. package/dist/application/use-cases/get-cv-versions.js +18 -0
  58. package/dist/application/use-cases/get-cv-versions.js.map +1 -0
  59. package/dist/application/use-cases/get-stats.d.ts +9 -0
  60. package/dist/application/use-cases/get-stats.js +42 -0
  61. package/dist/application/use-cases/get-stats.js.map +1 -0
  62. package/dist/application/use-cases/index.d.ts +13 -0
  63. package/dist/application/use-cases/index.js +14 -0
  64. package/dist/application/use-cases/index.js.map +1 -0
  65. package/dist/application/use-cases/list-cvs.d.ts +8 -0
  66. package/dist/application/use-cases/list-cvs.js +20 -0
  67. package/dist/application/use-cases/list-cvs.js.map +1 -0
  68. package/dist/application/use-cases/manage-tags.d.ts +7 -0
  69. package/dist/application/use-cases/manage-tags.js +36 -0
  70. package/dist/application/use-cases/manage-tags.js.map +1 -0
  71. package/dist/application/use-cases/semantic-search.d.ts +11 -0
  72. package/dist/application/use-cases/semantic-search.js +40 -0
  73. package/dist/application/use-cases/semantic-search.js.map +1 -0
  74. package/dist/application/use-cases/update-cv.d.ts +17 -0
  75. package/dist/application/use-cases/update-cv.js +94 -0
  76. package/dist/application/use-cases/update-cv.js.map +1 -0
  77. package/dist/domain/entities/candidate.d.ts +22 -0
  78. package/dist/domain/entities/candidate.js +2 -0
  79. package/dist/domain/entities/candidate.js.map +1 -0
  80. package/dist/domain/entities/cv-chunk.d.ts +10 -0
  81. package/dist/domain/entities/cv-chunk.js +2 -0
  82. package/dist/domain/entities/cv-chunk.js.map +1 -0
  83. package/dist/domain/entities/cv-version.d.ts +7 -0
  84. package/dist/domain/entities/cv-version.js +2 -0
  85. package/dist/domain/entities/cv-version.js.map +1 -0
  86. package/dist/domain/entities/index.d.ts +3 -0
  87. package/dist/domain/entities/index.js +2 -0
  88. package/dist/domain/entities/index.js.map +1 -0
  89. package/dist/domain/repositories/candidate-repository.d.ts +12 -0
  90. package/dist/domain/repositories/candidate-repository.js +2 -0
  91. package/dist/domain/repositories/candidate-repository.js.map +1 -0
  92. package/dist/domain/repositories/chunk-repository.d.ts +13 -0
  93. package/dist/domain/repositories/chunk-repository.js +2 -0
  94. package/dist/domain/repositories/chunk-repository.js.map +1 -0
  95. package/dist/domain/repositories/index.d.ts +3 -0
  96. package/dist/domain/repositories/index.js +2 -0
  97. package/dist/domain/repositories/index.js.map +1 -0
  98. package/dist/domain/repositories/version-repository.d.ts +6 -0
  99. package/dist/domain/repositories/version-repository.js +2 -0
  100. package/dist/domain/repositories/version-repository.js.map +1 -0
  101. package/dist/domain/value-objects/certification.d.ts +5 -0
  102. package/dist/domain/value-objects/certification.js +2 -0
  103. package/dist/domain/value-objects/certification.js.map +1 -0
  104. package/dist/domain/value-objects/contact-info.d.ts +5 -0
  105. package/dist/domain/value-objects/contact-info.js +2 -0
  106. package/dist/domain/value-objects/contact-info.js.map +1 -0
  107. package/dist/domain/value-objects/education.d.ts +7 -0
  108. package/dist/domain/value-objects/education.js +2 -0
  109. package/dist/domain/value-objects/education.js.map +1 -0
  110. package/dist/domain/value-objects/experience.d.ts +7 -0
  111. package/dist/domain/value-objects/experience.js +2 -0
  112. package/dist/domain/value-objects/experience.js.map +1 -0
  113. package/dist/domain/value-objects/index.d.ts +7 -0
  114. package/dist/domain/value-objects/index.js +2 -0
  115. package/dist/domain/value-objects/index.js.map +1 -0
  116. package/dist/domain/value-objects/language.d.ts +4 -0
  117. package/dist/domain/value-objects/language.js +2 -0
  118. package/dist/domain/value-objects/language.js.map +1 -0
  119. package/dist/domain/value-objects/links.d.ts +6 -0
  120. package/dist/domain/value-objects/links.js +2 -0
  121. package/dist/domain/value-objects/links.js.map +1 -0
  122. package/dist/domain/value-objects/project.d.ts +5 -0
  123. package/dist/domain/value-objects/project.js +2 -0
  124. package/dist/domain/value-objects/project.js.map +1 -0
  125. package/dist/infrastructure/ai/index.d.ts +2 -0
  126. package/dist/infrastructure/ai/index.js +3 -0
  127. package/dist/infrastructure/ai/index.js.map +1 -0
  128. package/dist/infrastructure/ai/openai-embedding-service.d.ts +8 -0
  129. package/dist/infrastructure/ai/openai-embedding-service.js +39 -0
  130. package/dist/infrastructure/ai/openai-embedding-service.js.map +1 -0
  131. package/dist/infrastructure/ai/openai-structured-extractor.d.ts +9 -0
  132. package/dist/infrastructure/ai/openai-structured-extractor.js +117 -0
  133. package/dist/infrastructure/ai/openai-structured-extractor.js.map +1 -0
  134. package/dist/infrastructure/config/app-config.d.ts +7 -0
  135. package/dist/infrastructure/config/app-config.js +13 -0
  136. package/dist/infrastructure/config/app-config.js.map +1 -0
  137. package/dist/infrastructure/export/csv-export-service.d.ts +6 -0
  138. package/dist/infrastructure/export/csv-export-service.js +24 -0
  139. package/dist/infrastructure/export/csv-export-service.js.map +1 -0
  140. package/dist/infrastructure/parsers/docx-parser.d.ts +5 -0
  141. package/dist/infrastructure/parsers/docx-parser.js +17 -0
  142. package/dist/infrastructure/parsers/docx-parser.js.map +1 -0
  143. package/dist/infrastructure/parsers/index.d.ts +2 -0
  144. package/dist/infrastructure/parsers/index.js +3 -0
  145. package/dist/infrastructure/parsers/index.js.map +1 -0
  146. package/dist/infrastructure/parsers/pdf-parser.d.ts +5 -0
  147. package/dist/infrastructure/parsers/pdf-parser.js +20 -0
  148. package/dist/infrastructure/parsers/pdf-parser.js.map +1 -0
  149. package/dist/infrastructure/persistence/database.d.ts +12 -0
  150. package/dist/infrastructure/persistence/database.js +77 -0
  151. package/dist/infrastructure/persistence/database.js.map +1 -0
  152. package/dist/infrastructure/persistence/index.d.ts +4 -0
  153. package/dist/infrastructure/persistence/index.js +5 -0
  154. package/dist/infrastructure/persistence/index.js.map +1 -0
  155. package/dist/infrastructure/persistence/lancedb-candidate-repository.d.ts +20 -0
  156. package/dist/infrastructure/persistence/lancedb-candidate-repository.js +158 -0
  157. package/dist/infrastructure/persistence/lancedb-candidate-repository.js.map +1 -0
  158. package/dist/infrastructure/persistence/lancedb-chunk-repository.d.ts +17 -0
  159. package/dist/infrastructure/persistence/lancedb-chunk-repository.js +102 -0
  160. package/dist/infrastructure/persistence/lancedb-chunk-repository.js.map +1 -0
  161. package/dist/infrastructure/persistence/lancedb-version-repository.d.ts +12 -0
  162. package/dist/infrastructure/persistence/lancedb-version-repository.js +59 -0
  163. package/dist/infrastructure/persistence/lancedb-version-repository.js.map +1 -0
  164. package/dist/interface/cli/index.d.ts +2 -0
  165. package/dist/interface/cli/index.js +14 -0
  166. package/dist/interface/cli/index.js.map +1 -0
  167. package/dist/interface/mcp/server.d.ts +2 -0
  168. package/dist/interface/mcp/server.js +63 -0
  169. package/dist/interface/mcp/server.js.map +1 -0
  170. package/dist/interface/mcp/tools/add-cv.d.ts +3 -0
  171. package/dist/interface/mcp/tools/add-cv.js +20 -0
  172. package/dist/interface/mcp/tools/add-cv.js.map +1 -0
  173. package/dist/interface/mcp/tools/bulk-add-cvs.d.ts +3 -0
  174. package/dist/interface/mcp/tools/bulk-add-cvs.js +28 -0
  175. package/dist/interface/mcp/tools/bulk-add-cvs.js.map +1 -0
  176. package/dist/interface/mcp/tools/delete-cv.d.ts +3 -0
  177. package/dist/interface/mcp/tools/delete-cv.js +20 -0
  178. package/dist/interface/mcp/tools/delete-cv.js.map +1 -0
  179. package/dist/interface/mcp/tools/export-results.d.ts +3 -0
  180. package/dist/interface/mcp/tools/export-results.js +23 -0
  181. package/dist/interface/mcp/tools/export-results.js.map +1 -0
  182. package/dist/interface/mcp/tools/filter-candidates.d.ts +3 -0
  183. package/dist/interface/mcp/tools/filter-candidates.js +32 -0
  184. package/dist/interface/mcp/tools/filter-candidates.js.map +1 -0
  185. package/dist/interface/mcp/tools/get-cv-chunks.d.ts +3 -0
  186. package/dist/interface/mcp/tools/get-cv-chunks.js +26 -0
  187. package/dist/interface/mcp/tools/get-cv-chunks.js.map +1 -0
  188. package/dist/interface/mcp/tools/get-cv-detail.d.ts +3 -0
  189. package/dist/interface/mcp/tools/get-cv-detail.js +20 -0
  190. package/dist/interface/mcp/tools/get-cv-detail.js.map +1 -0
  191. package/dist/interface/mcp/tools/get-cv-versions.d.ts +3 -0
  192. package/dist/interface/mcp/tools/get-cv-versions.js +20 -0
  193. package/dist/interface/mcp/tools/get-cv-versions.js.map +1 -0
  194. package/dist/interface/mcp/tools/get-stats.d.ts +3 -0
  195. package/dist/interface/mcp/tools/get-stats.js +19 -0
  196. package/dist/interface/mcp/tools/get-stats.js.map +1 -0
  197. package/dist/interface/mcp/tools/list-cvs.d.ts +3 -0
  198. package/dist/interface/mcp/tools/list-cvs.js +32 -0
  199. package/dist/interface/mcp/tools/list-cvs.js.map +1 -0
  200. package/dist/interface/mcp/tools/manage-tags.d.ts +3 -0
  201. package/dist/interface/mcp/tools/manage-tags.js +24 -0
  202. package/dist/interface/mcp/tools/manage-tags.js.map +1 -0
  203. package/dist/interface/mcp/tools/semantic-search.d.ts +3 -0
  204. package/dist/interface/mcp/tools/semantic-search.js +27 -0
  205. package/dist/interface/mcp/tools/semantic-search.js.map +1 -0
  206. package/dist/interface/mcp/tools/update-cv.d.ts +3 -0
  207. package/dist/interface/mcp/tools/update-cv.js +23 -0
  208. package/dist/interface/mcp/tools/update-cv.js.map +1 -0
  209. package/dist/interface/mcp/types.d.ts +16 -0
  210. package/dist/interface/mcp/types.js +2 -0
  211. package/dist/interface/mcp/types.js.map +1 -0
  212. package/dist/shared/errors/index.d.ts +32 -0
  213. package/dist/shared/errors/index.js +56 -0
  214. package/dist/shared/errors/index.js.map +1 -0
  215. package/dist/shared/types/index.d.ts +19 -0
  216. package/dist/shared/types/index.js +2 -0
  217. package/dist/shared/types/index.js.map +1 -0
  218. package/dist/shared/utils/chunking.d.ts +3 -0
  219. package/dist/shared/utils/chunking.js +89 -0
  220. package/dist/shared/utils/chunking.js.map +1 -0
  221. package/dist/shared/utils/index.d.ts +2 -0
  222. package/dist/shared/utils/index.js +3 -0
  223. package/dist/shared/utils/index.js.map +1 -0
  224. package/dist/shared/utils/text.d.ts +5 -0
  225. package/dist/shared/utils/text.js +21 -0
  226. package/dist/shared/utils/text.js.map +1 -0
  227. package/package.json +61 -0
@@ -0,0 +1,13 @@
1
+ import type { CvChunk } from '../entities/cv-chunk.js';
2
+ import type { SectionType } from '../../shared/types/index.js';
3
+ export interface SearchResult {
4
+ chunk: CvChunk;
5
+ score: number;
6
+ }
7
+ export interface IChunkRepository {
8
+ saveMany(chunks: CvChunk[]): Promise<void>;
9
+ findByCandidateId(candidateId: string, sectionType?: SectionType): Promise<CvChunk[]>;
10
+ deleteByCandidateId(candidateId: string): Promise<void>;
11
+ semanticSearch(queryVector: number[], limit: number, filter?: string): Promise<SearchResult[]>;
12
+ count(): Promise<number>;
13
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chunk-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-repository.js","sourceRoot":"","sources":["../../../src/domain/repositories/chunk-repository.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export type { ICandidateRepository } from './candidate-repository.js';
2
+ export type { IChunkRepository, SearchResult } from './chunk-repository.js';
3
+ export type { IVersionRepository } from './version-repository.js';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/domain/repositories/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { CvVersion } from '../entities/cv-version.js';
2
+ export interface IVersionRepository {
3
+ save(version: CvVersion): Promise<void>;
4
+ findByCandidateId(candidateId: string): Promise<CvVersion[]>;
5
+ deleteByCandidateId(candidateId: string): Promise<void>;
6
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=version-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-repository.js","sourceRoot":"","sources":["../../../src/domain/repositories/version-repository.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export interface Certification {
2
+ readonly name: string;
3
+ readonly issuer?: string;
4
+ readonly date?: string;
5
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=certification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certification.js","sourceRoot":"","sources":["../../../src/domain/value-objects/certification.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export interface ContactInfo {
2
+ readonly email?: string;
3
+ readonly phone?: string;
4
+ readonly location?: string;
5
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=contact-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-info.js","sourceRoot":"","sources":["../../../src/domain/value-objects/contact-info.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export interface Education {
2
+ readonly institution: string;
3
+ readonly degree?: string;
4
+ readonly field?: string;
5
+ readonly startDate?: string;
6
+ readonly endDate?: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=education.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"education.js","sourceRoot":"","sources":["../../../src/domain/value-objects/education.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export interface Experience {
2
+ readonly company: string;
3
+ readonly position: string;
4
+ readonly startDate?: string;
5
+ readonly endDate?: string;
6
+ readonly description?: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=experience.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experience.js","sourceRoot":"","sources":["../../../src/domain/value-objects/experience.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export type { ContactInfo } from './contact-info.js';
2
+ export type { Experience } from './experience.js';
3
+ export type { Education } from './education.js';
4
+ export type { Language } from './language.js';
5
+ export type { Certification } from './certification.js';
6
+ export type { Project } from './project.js';
7
+ export type { Links } from './links.js';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/domain/value-objects/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export interface Language {
2
+ readonly language: string;
3
+ readonly level?: string;
4
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=language.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language.js","sourceRoot":"","sources":["../../../src/domain/value-objects/language.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ export interface Links {
2
+ readonly linkedin?: string;
3
+ readonly github?: string;
4
+ readonly portfolio?: string;
5
+ readonly other?: string[];
6
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../../src/domain/value-objects/links.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export interface Project {
2
+ readonly name: string;
3
+ readonly description?: string;
4
+ readonly technologies?: string[];
5
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/domain/value-objects/project.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export { OpenAiEmbeddingService } from './openai-embedding-service.js';
2
+ export { OpenAiStructuredExtractor } from './openai-structured-extractor.js';
@@ -0,0 +1,3 @@
1
+ export { OpenAiEmbeddingService } from './openai-embedding-service.js';
2
+ export { OpenAiStructuredExtractor } from './openai-structured-extractor.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { IEmbeddingService } from '../../application/ports/embedding-service.js';
2
+ export declare class OpenAiEmbeddingService implements IEmbeddingService {
3
+ private client;
4
+ private model;
5
+ constructor(apiKey: string, model?: string);
6
+ embed(text: string): Promise<number[]>;
7
+ embedBatch(texts: string[]): Promise<number[][]>;
8
+ }
@@ -0,0 +1,39 @@
1
+ import OpenAI from 'openai';
2
+ import { EmbeddingError } from '../../shared/errors/index.js';
3
+ export class OpenAiEmbeddingService {
4
+ client;
5
+ model;
6
+ constructor(apiKey, model = 'text-embedding-3-large') {
7
+ this.client = new OpenAI({ apiKey });
8
+ this.model = model;
9
+ }
10
+ async embed(text) {
11
+ try {
12
+ const response = await this.client.embeddings.create({
13
+ model: this.model,
14
+ input: text,
15
+ });
16
+ return response.data[0].embedding;
17
+ }
18
+ catch (error) {
19
+ throw new EmbeddingError('Failed to generate embedding', error);
20
+ }
21
+ }
22
+ async embedBatch(texts) {
23
+ if (texts.length === 0)
24
+ return [];
25
+ try {
26
+ const response = await this.client.embeddings.create({
27
+ model: this.model,
28
+ input: texts,
29
+ });
30
+ return response.data
31
+ .sort((a, b) => a.index - b.index)
32
+ .map((d) => d.embedding);
33
+ }
34
+ catch (error) {
35
+ throw new EmbeddingError('Failed to generate batch embeddings', error);
36
+ }
37
+ }
38
+ }
39
+ //# sourceMappingURL=openai-embedding-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-embedding-service.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/openai-embedding-service.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,OAAO,sBAAsB;IACzB,MAAM,CAAS;IACf,KAAK,CAAS;IAEtB,YAAY,MAAc,EAAE,QAAgB,wBAAwB;QAClE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;gBACnD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,cAAc,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAe;QAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAElC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;gBACnD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC,IAAI;iBACjB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;iBACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,cAAc,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import type { IStructuredExtractor } from '../../application/ports/structured-extractor.js';
2
+ import type { ExtractedCv } from '../../application/dto/extracted-cv.js';
3
+ export declare class OpenAiStructuredExtractor implements IStructuredExtractor {
4
+ private client;
5
+ private model;
6
+ constructor(apiKey: string, model?: string);
7
+ extract(rawText: string): Promise<ExtractedCv>;
8
+ private mapToExtractedCv;
9
+ }
@@ -0,0 +1,117 @@
1
+ import OpenAI from 'openai';
2
+ import { z } from 'zod';
3
+ import { zodTextFormat } from 'openai/helpers/zod';
4
+ import { ExtractionError } from '../../shared/errors/index.js';
5
+ const CvExtractionSchema = z.object({
6
+ name: z.string(),
7
+ email: z.string().optional(),
8
+ phone: z.string().optional(),
9
+ location: z.string().optional(),
10
+ summary: z.string().optional(),
11
+ experience: z.array(z.object({
12
+ company: z.string(),
13
+ position: z.string(),
14
+ start_date: z.string().optional(),
15
+ end_date: z.string().optional(),
16
+ description: z.string().optional(),
17
+ })),
18
+ education: z.array(z.object({
19
+ institution: z.string(),
20
+ degree: z.string().optional(),
21
+ field: z.string().optional(),
22
+ start_date: z.string().optional(),
23
+ end_date: z.string().optional(),
24
+ })),
25
+ skills: z.array(z.string()),
26
+ languages: z.array(z.object({
27
+ language: z.string(),
28
+ level: z.string().optional(),
29
+ })),
30
+ certifications: z.array(z.object({
31
+ name: z.string(),
32
+ issuer: z.string().optional(),
33
+ date: z.string().optional(),
34
+ })),
35
+ projects: z.array(z.object({
36
+ name: z.string(),
37
+ description: z.string().optional(),
38
+ technologies: z.array(z.string()).optional(),
39
+ })),
40
+ links: z
41
+ .object({
42
+ linkedin: z.string().optional(),
43
+ github: z.string().optional(),
44
+ portfolio: z.string().optional(),
45
+ other: z.array(z.string()).optional(),
46
+ })
47
+ .optional(),
48
+ total_experience_years: z.number().optional(),
49
+ });
50
+ const SYSTEM_PROMPT = `You are a CV/resume parser. Extract structured information from the following CV text.
51
+ Be thorough and accurate. If a field is not present in the CV, omit it.
52
+ For total_experience_years, calculate the total based on work experience dates if possible.
53
+ Extract all skills mentioned anywhere in the CV.
54
+ For languages, include proficiency level if mentioned.
55
+ Return the data in the exact schema format requested.`;
56
+ export class OpenAiStructuredExtractor {
57
+ client;
58
+ model;
59
+ constructor(apiKey, model = 'gpt-5-mini') {
60
+ this.client = new OpenAI({ apiKey });
61
+ this.model = model;
62
+ }
63
+ async extract(rawText) {
64
+ try {
65
+ const response = await this.client.responses.parse({
66
+ model: this.model,
67
+ input: [
68
+ { role: 'developer', content: SYSTEM_PROMPT },
69
+ { role: 'user', content: rawText },
70
+ ],
71
+ text: {
72
+ format: zodTextFormat(CvExtractionSchema, 'cv_extraction'),
73
+ },
74
+ });
75
+ const parsed = response.output_parsed;
76
+ if (!parsed) {
77
+ throw new Error('No parsed output from OpenAI');
78
+ }
79
+ return this.mapToExtractedCv(parsed);
80
+ }
81
+ catch (error) {
82
+ if (error instanceof ExtractionError)
83
+ throw error;
84
+ throw new ExtractionError('Failed to extract structured CV data', error);
85
+ }
86
+ }
87
+ mapToExtractedCv(parsed) {
88
+ return {
89
+ name: parsed.name,
90
+ email: parsed.email,
91
+ phone: parsed.phone,
92
+ location: parsed.location,
93
+ summary: parsed.summary,
94
+ experience: parsed.experience.map((e) => ({
95
+ company: e.company,
96
+ position: e.position,
97
+ startDate: e.start_date,
98
+ endDate: e.end_date,
99
+ description: e.description,
100
+ })),
101
+ education: parsed.education.map((e) => ({
102
+ institution: e.institution,
103
+ degree: e.degree,
104
+ field: e.field,
105
+ startDate: e.start_date,
106
+ endDate: e.end_date,
107
+ })),
108
+ skills: parsed.skills,
109
+ languages: parsed.languages,
110
+ certifications: parsed.certifications,
111
+ projects: parsed.projects,
112
+ links: parsed.links,
113
+ totalExperienceYears: parsed.total_experience_years,
114
+ };
115
+ }
116
+ }
117
+ //# sourceMappingURL=openai-structured-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-structured-extractor.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/openai-structured-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface AppConfig {
2
+ openaiApiKey: string;
3
+ lancedbPath: string;
4
+ embeddingModel: string;
5
+ extractionModel: string;
6
+ }
7
+ export declare function loadConfig(): AppConfig;
@@ -0,0 +1,13 @@
1
+ export function loadConfig() {
2
+ const openaiApiKey = process.env.OPENAI_API_KEY;
3
+ if (!openaiApiKey) {
4
+ throw new Error('OPENAI_API_KEY environment variable is required');
5
+ }
6
+ return {
7
+ openaiApiKey,
8
+ lancedbPath: process.env.LANCEDB_PATH ?? './data/lancedb',
9
+ embeddingModel: process.env.EMBEDDING_MODEL ?? 'text-embedding-3-large',
10
+ extractionModel: process.env.EXTRACTION_MODEL ?? 'gpt-5-mini',
11
+ };
12
+ }
13
+ //# sourceMappingURL=app-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../../src/infrastructure/config/app-config.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,UAAU;IACxB,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAChD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,OAAO;QACL,YAAY;QACZ,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,gBAAgB;QACzD,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB;QACvE,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,YAAY;KAC9D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { IExportService } from '../../application/ports/export-service.js';
2
+ import type { Candidate } from '../../domain/entities/candidate.js';
3
+ import type { ExportFormat } from '../../shared/types/index.js';
4
+ export declare class CsvExportService implements IExportService {
5
+ export(candidates: Candidate[], format: ExportFormat): string;
6
+ }
@@ -0,0 +1,24 @@
1
+ import Papa from 'papaparse';
2
+ export class CsvExportService {
3
+ export(candidates, format) {
4
+ if (format === 'json') {
5
+ return JSON.stringify(candidates, null, 2);
6
+ }
7
+ const rows = candidates.map((c) => ({
8
+ id: c.id,
9
+ name: c.name,
10
+ email: c.contact.email ?? '',
11
+ phone: c.contact.phone ?? '',
12
+ location: c.contact.location ?? '',
13
+ skills: c.skills.join('; '),
14
+ experience_years: c.experienceYears ?? '',
15
+ education: c.education
16
+ .map((e) => [e.degree, e.field ? `in ${e.field}` : '', `at ${e.institution}`].filter(Boolean).join(' '))
17
+ .join('; '),
18
+ tags: c.tags.join('; '),
19
+ created_at: c.createdAt,
20
+ }));
21
+ return Papa.unparse(rows);
22
+ }
23
+ }
24
+ //# sourceMappingURL=csv-export-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv-export-service.js","sourceRoot":"","sources":["../../../src/infrastructure/export/csv-export-service.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,MAAM,OAAO,gBAAgB;IAC3B,MAAM,CAAC,UAAuB,EAAE,MAAoB;QAClD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YAC5B,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YAC5B,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE;YAClC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YAC3B,gBAAgB,EAAE,CAAC,CAAC,eAAe,IAAI,EAAE;YACzC,SAAS,EAAE,CAAC,CAAC,SAAS;iBACnB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;iBACvG,IAAI,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACvB,UAAU,EAAE,CAAC,CAAC,SAAS;SACxB,CAAC,CAAC,CAAC;QAEJ,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import type { IDocumentParser, ParsedDocument } from '../../application/ports/document-parser.js';
2
+ export declare class DocxParser implements IDocumentParser {
3
+ supports(fileType: string): boolean;
4
+ parse(filePath: string): Promise<ParsedDocument>;
5
+ }
@@ -0,0 +1,17 @@
1
+ import mammoth from 'mammoth';
2
+ import { DocumentParseError } from '../../shared/errors/index.js';
3
+ export class DocxParser {
4
+ supports(fileType) {
5
+ return fileType === 'docx';
6
+ }
7
+ async parse(filePath) {
8
+ try {
9
+ const result = await mammoth.extractRawText({ path: filePath });
10
+ return { text: result.value };
11
+ }
12
+ catch (error) {
13
+ throw new DocumentParseError(`Failed to parse DOCX: ${filePath}`, error);
14
+ }
15
+ }
16
+ }
17
+ //# sourceMappingURL=docx-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docx-parser.js","sourceRoot":"","sources":["../../../src/infrastructure/parsers/docx-parser.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,OAAO,UAAU;IACrB,QAAQ,CAAC,QAAgB;QACvB,OAAO,QAAQ,KAAK,MAAM,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YAChE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,kBAAkB,CAAC,yBAAyB,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export { PdfParser } from './pdf-parser.js';
2
+ export { DocxParser } from './docx-parser.js';
@@ -0,0 +1,3 @@
1
+ export { PdfParser } from './pdf-parser.js';
2
+ export { DocxParser } from './docx-parser.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/parsers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { IDocumentParser, ParsedDocument } from '../../application/ports/document-parser.js';
2
+ export declare class PdfParser implements IDocumentParser {
3
+ supports(fileType: string): boolean;
4
+ parse(filePath: string): Promise<ParsedDocument>;
5
+ }
@@ -0,0 +1,20 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { extractText, getDocumentProxy } from 'unpdf';
3
+ import { DocumentParseError } from '../../shared/errors/index.js';
4
+ export class PdfParser {
5
+ supports(fileType) {
6
+ return fileType === 'pdf';
7
+ }
8
+ async parse(filePath) {
9
+ try {
10
+ const buffer = await readFile(filePath);
11
+ const pdf = await getDocumentProxy(new Uint8Array(buffer));
12
+ const { totalPages, text } = await extractText(pdf, { mergePages: true });
13
+ return { text: text, pageCount: totalPages };
14
+ }
15
+ catch (error) {
16
+ throw new DocumentParseError(`Failed to parse PDF: ${filePath}`, error);
17
+ }
18
+ }
19
+ }
20
+ //# sourceMappingURL=pdf-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-parser.js","sourceRoot":"","sources":["../../../src/infrastructure/parsers/pdf-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,OAAO,SAAS;IACpB,QAAQ,CAAC,QAAgB;QACvB,OAAO,QAAQ,KAAK,KAAK,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACxC,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3D,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1E,OAAO,EAAE,IAAI,EAAE,IAAc,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,kBAAkB,CAAC,wBAAwB,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { Connection, Table } from '@lancedb/lancedb';
2
+ export declare function getDatabase(dbPath: string): Promise<Connection>;
3
+ export declare function getOrCreateTable(db: Connection, tableName: string, seedData?: Record<string, unknown>[]): Promise<Table>;
4
+ export declare function getCandidateSeedRow(): Record<string, unknown>[];
5
+ export declare function getChunkSeedRow(): Record<string, unknown>[];
6
+ export declare function getVersionSeedRow(): Record<string, unknown>[];
7
+ export declare const TABLE_NAMES: {
8
+ readonly candidates: "candidates";
9
+ readonly chunks: "cv_chunks";
10
+ readonly versions: "cv_versions";
11
+ };
12
+ export declare const VECTOR_DIM = 3072;
@@ -0,0 +1,77 @@
1
+ import * as lancedb from '@lancedb/lancedb';
2
+ const VECTOR_DIMENSION = 3072;
3
+ let dbInstance = null;
4
+ export async function getDatabase(dbPath) {
5
+ if (!dbInstance) {
6
+ dbInstance = await lancedb.connect(dbPath);
7
+ }
8
+ return dbInstance;
9
+ }
10
+ export async function getOrCreateTable(db, tableName, seedData) {
11
+ const tableNames = await db.tableNames();
12
+ if (tableNames.includes(tableName)) {
13
+ return db.openTable(tableName);
14
+ }
15
+ if (seedData && seedData.length > 0) {
16
+ return db.createTable(tableName, seedData);
17
+ }
18
+ throw new Error(`Table "${tableName}" does not exist and no seed data provided`);
19
+ }
20
+ export function getCandidateSeedRow() {
21
+ return [
22
+ {
23
+ id: '__seed__',
24
+ name: '',
25
+ email: '',
26
+ phone: '',
27
+ location: '',
28
+ summary: '',
29
+ skills: '[]',
30
+ languages: '[]',
31
+ experience_years: 0,
32
+ experience: '[]',
33
+ education: '[]',
34
+ certifications: '[]',
35
+ projects: '[]',
36
+ links: '{}',
37
+ tags: '[]',
38
+ source_file: '',
39
+ file_type: '',
40
+ raw_text: '',
41
+ created_at: '',
42
+ updated_at: '',
43
+ version: 0,
44
+ },
45
+ ];
46
+ }
47
+ export function getChunkSeedRow() {
48
+ return [
49
+ {
50
+ id: '__seed__',
51
+ candidate_id: '',
52
+ section_type: '',
53
+ content: '',
54
+ vector: new Array(VECTOR_DIMENSION).fill(0),
55
+ metadata: '{}',
56
+ created_at: '',
57
+ },
58
+ ];
59
+ }
60
+ export function getVersionSeedRow() {
61
+ return [
62
+ {
63
+ id: '__seed__',
64
+ candidate_id: '',
65
+ version: 0,
66
+ data: '{}',
67
+ created_at: '',
68
+ },
69
+ ];
70
+ }
71
+ export const TABLE_NAMES = {
72
+ candidates: 'candidates',
73
+ chunks: 'cv_chunks',
74
+ versions: 'cv_versions',
75
+ };
76
+ export const VECTOR_DIM = VECTOR_DIMENSION;
77
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/infrastructure/persistence/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAG5C,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B,IAAI,UAAU,GAAsB,IAAI,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC9C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,EAAc,EACd,SAAiB,EACjB,QAAoC;IAEpC,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC;IAEzC,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,UAAU,SAAS,4CAA4C,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL;YACE,EAAE,EAAE,UAAU;YACd,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,EAAE;YACT,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,EAAE;YACX,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,IAAI;YACf,gBAAgB,EAAE,CAAC;YACnB,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,IAAI;YACf,cAAc,EAAE,IAAI;YACpB,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI;YACV,WAAW,EAAE,EAAE;YACf,SAAS,EAAE,EAAE;YACb,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,EAAE;YACd,OAAO,EAAE,CAAC;SACX;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL;YACE,EAAE,EAAE,UAAU;YACd,YAAY,EAAE,EAAE;YAChB,YAAY,EAAE,EAAE;YAChB,OAAO,EAAE,EAAE;YACX,MAAM,EAAE,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3C,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,EAAE;SACf;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO;QACL;YACE,EAAE,EAAE,UAAU;YACd,YAAY,EAAE,EAAE;YAChB,OAAO,EAAE,CAAC;YACV,IAAI,EAAE,IAAI;YACV,UAAU,EAAE,EAAE;SACf;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,UAAU,EAAE,YAAY;IACxB,MAAM,EAAE,WAAW;IACnB,QAAQ,EAAE,aAAa;CACf,CAAC;AAEX,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { getDatabase, getOrCreateTable, TABLE_NAMES, VECTOR_DIM } from './database.js';
2
+ export { LanceDbCandidateRepository } from './lancedb-candidate-repository.js';
3
+ export { LanceDbChunkRepository } from './lancedb-chunk-repository.js';
4
+ export { LanceDbVersionRepository } from './lancedb-version-repository.js';