projex-cli 0.2.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 (85) hide show
  1. package/dist/cli.d.ts +6 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +321 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/event-bus.d.ts +35 -0
  6. package/dist/event-bus.d.ts.map +1 -0
  7. package/dist/event-bus.js +71 -0
  8. package/dist/event-bus.js.map +1 -0
  9. package/dist/events/event-bus.d.ts +35 -0
  10. package/dist/events/event-bus.d.ts.map +1 -0
  11. package/dist/events/event-bus.js +71 -0
  12. package/dist/events/event-bus.js.map +1 -0
  13. package/dist/events/index.d.ts +3 -0
  14. package/dist/events/index.d.ts.map +1 -0
  15. package/dist/events/index.js +3 -0
  16. package/dist/events/index.js.map +1 -0
  17. package/dist/events/types.d.ts +143 -0
  18. package/dist/events/types.d.ts.map +1 -0
  19. package/dist/events/types.js +6 -0
  20. package/dist/events/types.js.map +1 -0
  21. package/dist/index.d.ts +11 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +12 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/inference/enricher.d.ts +18 -0
  26. package/dist/inference/enricher.d.ts.map +1 -0
  27. package/dist/inference/enricher.js +290 -0
  28. package/dist/inference/enricher.js.map +1 -0
  29. package/dist/inference/index.d.ts +5 -0
  30. package/dist/inference/index.d.ts.map +1 -0
  31. package/dist/inference/index.js +5 -0
  32. package/dist/inference/index.js.map +1 -0
  33. package/dist/inference/lifecycle-tracker.d.ts +40 -0
  34. package/dist/inference/lifecycle-tracker.d.ts.map +1 -0
  35. package/dist/inference/lifecycle-tracker.js +132 -0
  36. package/dist/inference/lifecycle-tracker.js.map +1 -0
  37. package/dist/inference/portfolio-generator.d.ts +44 -0
  38. package/dist/inference/portfolio-generator.d.ts.map +1 -0
  39. package/dist/inference/portfolio-generator.js +239 -0
  40. package/dist/inference/portfolio-generator.js.map +1 -0
  41. package/dist/inference/project-detector.d.ts +17 -0
  42. package/dist/inference/project-detector.d.ts.map +1 -0
  43. package/dist/inference/project-detector.js +127 -0
  44. package/dist/inference/project-detector.js.map +1 -0
  45. package/dist/ingestion/github-client.d.ts +56 -0
  46. package/dist/ingestion/github-client.d.ts.map +1 -0
  47. package/dist/ingestion/github-client.js +213 -0
  48. package/dist/ingestion/github-client.js.map +1 -0
  49. package/dist/ingestion/github-poller.d.ts +41 -0
  50. package/dist/ingestion/github-poller.d.ts.map +1 -0
  51. package/dist/ingestion/github-poller.js +121 -0
  52. package/dist/ingestion/github-poller.js.map +1 -0
  53. package/dist/ingestion/normalizer.d.ts +41 -0
  54. package/dist/ingestion/normalizer.d.ts.map +1 -0
  55. package/dist/ingestion/normalizer.js +173 -0
  56. package/dist/ingestion/normalizer.js.map +1 -0
  57. package/dist/integrations/analyzer.d.ts +74 -0
  58. package/dist/integrations/analyzer.d.ts.map +1 -0
  59. package/dist/integrations/analyzer.js +287 -0
  60. package/dist/integrations/analyzer.js.map +1 -0
  61. package/dist/integrations/index.d.ts +4 -0
  62. package/dist/integrations/index.d.ts.map +1 -0
  63. package/dist/integrations/index.js +5 -0
  64. package/dist/integrations/index.js.map +1 -0
  65. package/dist/integrations/injectors.d.ts +60 -0
  66. package/dist/integrations/injectors.d.ts.map +1 -0
  67. package/dist/integrations/injectors.js +361 -0
  68. package/dist/integrations/injectors.js.map +1 -0
  69. package/dist/integrations/template-generator.d.ts +45 -0
  70. package/dist/integrations/template-generator.d.ts.map +1 -0
  71. package/dist/integrations/template-generator.js +187 -0
  72. package/dist/integrations/template-generator.js.map +1 -0
  73. package/dist/storage/index.d.ts +2 -0
  74. package/dist/storage/index.d.ts.map +1 -0
  75. package/dist/storage/index.js +2 -0
  76. package/dist/storage/index.js.map +1 -0
  77. package/dist/storage/project-store.d.ts +23 -0
  78. package/dist/storage/project-store.d.ts.map +1 -0
  79. package/dist/storage/project-store.js +107 -0
  80. package/dist/storage/project-store.js.map +1 -0
  81. package/dist/types.d.ts +143 -0
  82. package/dist/types.d.ts.map +1 -0
  83. package/dist/types.js +6 -0
  84. package/dist/types.js.map +1 -0
  85. package/package.json +55 -0
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Core event types for the portfolio inference system.
3
+ * All signals are normalized to these event structures.
4
+ */
5
+ export type EventType = 'repo.created' | 'repo.pushed' | 'repo.topics_changed' | 'repo.description_changed' | 'repo.archived' | 'repo.enriched';
6
+ export interface RepoIdentifier {
7
+ /** Unique ID in format "github:owner/repo" */
8
+ id: string;
9
+ /** Repository name */
10
+ name: string;
11
+ /** Full repository URL */
12
+ url: string;
13
+ /** Owner (user or org) */
14
+ owner: string;
15
+ }
16
+ export interface BaseEvent {
17
+ eventId: string;
18
+ eventType: EventType;
19
+ timestamp: Date;
20
+ source: 'github';
21
+ repo: RepoIdentifier;
22
+ }
23
+ export interface RepoCreatedEvent extends BaseEvent {
24
+ eventType: 'repo.created';
25
+ payload: {
26
+ description: string | null;
27
+ topics: string[];
28
+ isPrivate: boolean;
29
+ };
30
+ }
31
+ export interface RepoPushedEvent extends BaseEvent {
32
+ eventType: 'repo.pushed';
33
+ payload: {
34
+ commitCount: number;
35
+ branch: string;
36
+ };
37
+ }
38
+ export interface RepoTopicsChangedEvent extends BaseEvent {
39
+ eventType: 'repo.topics_changed';
40
+ payload: {
41
+ topics: string[];
42
+ previousTopics: string[];
43
+ };
44
+ }
45
+ export interface RepoDescriptionChangedEvent extends BaseEvent {
46
+ eventType: 'repo.description_changed';
47
+ payload: {
48
+ description: string | null;
49
+ previousDescription: string | null;
50
+ };
51
+ }
52
+ export interface RepoArchivedEvent extends BaseEvent {
53
+ eventType: 'repo.archived';
54
+ payload: {
55
+ archivedAt: Date;
56
+ };
57
+ }
58
+ export interface RepoEnrichedEvent extends BaseEvent {
59
+ eventType: 'repo.enriched';
60
+ payload: {
61
+ languages: Record<string, number>;
62
+ readme: string | null;
63
+ packageFiles: PackageFileInfo[];
64
+ defaultBranch: string;
65
+ starCount: number;
66
+ forkCount: number;
67
+ };
68
+ }
69
+ export interface PackageFileInfo {
70
+ type: 'npm' | 'cargo' | 'pip' | 'go' | 'gem' | 'composer';
71
+ filename: string;
72
+ dependencies: string[];
73
+ devDependencies: string[];
74
+ }
75
+ export type SignalEvent = RepoCreatedEvent | RepoPushedEvent | RepoTopicsChangedEvent | RepoDescriptionChangedEvent | RepoArchivedEvent | RepoEnrichedEvent;
76
+ export type ProjectStatus = 'ACTIVE' | 'LIKELY_COMPLETED' | 'COMPLETED' | 'ARCHIVED' | 'IGNORED';
77
+ export type PortfolioStatus = 'NONE' | 'DRAFT' | 'PENDING_REVIEW' | 'APPROVED' | 'REJECTED';
78
+ export interface TechStackItem {
79
+ name: string;
80
+ category: 'language' | 'framework' | 'library' | 'tool' | 'platform';
81
+ confidence: number;
82
+ source: 'languages_api' | 'package_file' | 'readme' | 'topics';
83
+ }
84
+ export interface Project {
85
+ /** Unique ID: "github:owner/repo" */
86
+ id: string;
87
+ name: string;
88
+ displayName: string;
89
+ owner: string;
90
+ url: string;
91
+ status: ProjectStatus;
92
+ isPrivate: boolean;
93
+ purpose: string | null;
94
+ techStack: TechStackItem[];
95
+ topics: string[];
96
+ startDate: Date;
97
+ lastActivityDate: Date;
98
+ completionDate: Date | null;
99
+ confidence: {
100
+ purpose: number;
101
+ techStack: number;
102
+ completion: number;
103
+ };
104
+ rawData: {
105
+ description: string | null;
106
+ readme: string | null;
107
+ languages: Record<string, number>;
108
+ packageFiles: PackageFileInfo[];
109
+ };
110
+ portfolioStatus: PortfolioStatus;
111
+ portfolioDraft: PortfolioDraft | null;
112
+ createdAt: Date;
113
+ updatedAt: Date;
114
+ }
115
+ export interface PortfolioDraft {
116
+ title: string;
117
+ tagline: string;
118
+ description: string;
119
+ techStack: string[];
120
+ timelineStart: Date;
121
+ timelineEnd: Date | null;
122
+ highlights: string[];
123
+ githubUrl: string;
124
+ liveUrl: string | null;
125
+ userEdits: Partial<Omit<PortfolioDraft, 'userEdits' | 'approved' | 'approvedAt'>>;
126
+ approved: boolean;
127
+ approvedAt: Date | null;
128
+ }
129
+ export interface Config {
130
+ github: {
131
+ token: string;
132
+ username: string;
133
+ pollingIntervalMinutes: number;
134
+ };
135
+ inference: {
136
+ completionThresholdDays: number;
137
+ minCommitsForCompletion: number;
138
+ };
139
+ storage: {
140
+ dataDir: string;
141
+ };
142
+ }
143
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/events/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Core event types for the portfolio inference system.
3
+ * All signals are normalized to these event structures.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/events/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,11 @@
1
+ export * from './events/types.js';
2
+ export * from './events/event-bus.js';
3
+ export * from './ingestion/github-client.js';
4
+ export * from './ingestion/github-poller.js';
5
+ export * from './ingestion/normalizer.js';
6
+ export * from './inference/project-detector.js';
7
+ export * from './inference/enricher.js';
8
+ export * from './inference/lifecycle-tracker.js';
9
+ export * from './inference/portfolio-generator.js';
10
+ export * from './storage/project-store.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC;AACjD,cAAc,oCAAoC,CAAC;AACnD,cAAc,4BAA4B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ // Core exports
2
+ export * from './events/types.js';
3
+ export * from './events/event-bus.js';
4
+ export * from './ingestion/github-client.js';
5
+ export * from './ingestion/github-poller.js';
6
+ export * from './ingestion/normalizer.js';
7
+ export * from './inference/project-detector.js';
8
+ export * from './inference/enricher.js';
9
+ export * from './inference/lifecycle-tracker.js';
10
+ export * from './inference/portfolio-generator.js';
11
+ export * from './storage/project-store.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC;AACjD,cAAc,oCAAoC,CAAC;AACnD,cAAc,4BAA4B,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Enricher - Rules 2 & 3: Tech stack inference and purpose extraction
3
+ * Prioritizes accuracy over simplicity as requested.
4
+ */
5
+ import type { ProjectStore } from '../storage/project-store.js';
6
+ import { EventBus } from '../events/event-bus.js';
7
+ export declare class Enricher {
8
+ private store;
9
+ private eventBus;
10
+ constructor(store: ProjectStore, eventBus: EventBus);
11
+ private handleEnriched;
12
+ private inferTechStack;
13
+ private extractTechFromReadme;
14
+ private calculateTechStackConfidence;
15
+ private extractPurpose;
16
+ private extractPurposeFromReadme;
17
+ }
18
+ //# sourceMappingURL=enricher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enricher.d.ts","sourceRoot":"","sources":["../../src/inference/enricher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AA0FlD,qBAAa,QAAQ;IAEb,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;gBADR,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,QAAQ;YAOhB,cAAc;IA8B5B,OAAO,CAAC,cAAc;IA2DtB,OAAO,CAAC,qBAAqB;IA4C7B,OAAO,CAAC,4BAA4B;IAgBpC,OAAO,CAAC,cAAc;IA+BtB,OAAO,CAAC,wBAAwB;CAmDnC"}
@@ -0,0 +1,290 @@
1
+ /**
2
+ * Enricher - Rules 2 & 3: Tech stack inference and purpose extraction
3
+ * Prioritizes accuracy over simplicity as requested.
4
+ */
5
+ // Framework detection patterns for package files
6
+ const FRAMEWORK_PATTERNS = {
7
+ // JavaScript/TypeScript
8
+ 'react': { name: 'React', category: 'framework' },
9
+ 'react-dom': { name: 'React', category: 'framework' },
10
+ 'next': { name: 'Next.js', category: 'framework' },
11
+ 'vue': { name: 'Vue.js', category: 'framework' },
12
+ 'nuxt': { name: 'Nuxt.js', category: 'framework' },
13
+ '@angular/core': { name: 'Angular', category: 'framework' },
14
+ 'svelte': { name: 'Svelte', category: 'framework' },
15
+ 'express': { name: 'Express', category: 'framework' },
16
+ 'fastify': { name: 'Fastify', category: 'framework' },
17
+ 'nestjs': { name: 'NestJS', category: 'framework' },
18
+ '@nestjs/core': { name: 'NestJS', category: 'framework' },
19
+ 'koa': { name: 'Koa', category: 'framework' },
20
+ 'hono': { name: 'Hono', category: 'framework' },
21
+ 'electron': { name: 'Electron', category: 'framework' },
22
+ 'tauri': { name: 'Tauri', category: 'framework' },
23
+ // Databases / ORMs
24
+ 'prisma': { name: 'Prisma', category: 'library' },
25
+ '@prisma/client': { name: 'Prisma', category: 'library' },
26
+ 'drizzle-orm': { name: 'Drizzle', category: 'library' },
27
+ 'typeorm': { name: 'TypeORM', category: 'library' },
28
+ 'mongoose': { name: 'Mongoose', category: 'library' },
29
+ 'sequelize': { name: 'Sequelize', category: 'library' },
30
+ // Testing
31
+ 'jest': { name: 'Jest', category: 'tool' },
32
+ 'vitest': { name: 'Vitest', category: 'tool' },
33
+ 'mocha': { name: 'Mocha', category: 'tool' },
34
+ 'playwright': { name: 'Playwright', category: 'tool' },
35
+ 'cypress': { name: 'Cypress', category: 'tool' },
36
+ // Build tools
37
+ 'vite': { name: 'Vite', category: 'tool' },
38
+ 'webpack': { name: 'Webpack', category: 'tool' },
39
+ 'esbuild': { name: 'esbuild', category: 'tool' },
40
+ 'rollup': { name: 'Rollup', category: 'tool' },
41
+ // Python
42
+ 'django': { name: 'Django', category: 'framework' },
43
+ 'flask': { name: 'Flask', category: 'framework' },
44
+ 'fastapi': { name: 'FastAPI', category: 'framework' },
45
+ 'pytorch': { name: 'PyTorch', category: 'library' },
46
+ 'torch': { name: 'PyTorch', category: 'library' },
47
+ 'tensorflow': { name: 'TensorFlow', category: 'library' },
48
+ 'pandas': { name: 'Pandas', category: 'library' },
49
+ 'numpy': { name: 'NumPy', category: 'library' },
50
+ 'scikit-learn': { name: 'Scikit-learn', category: 'library' },
51
+ // Rust
52
+ 'actix-web': { name: 'Actix Web', category: 'framework' },
53
+ 'axum': { name: 'Axum', category: 'framework' },
54
+ 'tokio': { name: 'Tokio', category: 'library' },
55
+ 'serde': { name: 'Serde', category: 'library' },
56
+ // Go
57
+ 'gin': { name: 'Gin', category: 'framework' },
58
+ 'fiber': { name: 'Fiber', category: 'framework' },
59
+ 'echo': { name: 'Echo', category: 'framework' },
60
+ };
61
+ // Language name normalization
62
+ const LANGUAGE_NAMES = {
63
+ 'TypeScript': 'TypeScript',
64
+ 'JavaScript': 'JavaScript',
65
+ 'Python': 'Python',
66
+ 'Rust': 'Rust',
67
+ 'Go': 'Go',
68
+ 'Java': 'Java',
69
+ 'Kotlin': 'Kotlin',
70
+ 'Swift': 'Swift',
71
+ 'C#': 'C#',
72
+ 'C++': 'C++',
73
+ 'C': 'C',
74
+ 'Ruby': 'Ruby',
75
+ 'PHP': 'PHP',
76
+ 'Dart': 'Dart',
77
+ 'Elixir': 'Elixir',
78
+ 'Scala': 'Scala',
79
+ 'Shell': 'Shell',
80
+ 'HTML': 'HTML',
81
+ 'CSS': 'CSS',
82
+ 'SCSS': 'SCSS',
83
+ 'Dockerfile': 'Docker',
84
+ };
85
+ export class Enricher {
86
+ store;
87
+ eventBus;
88
+ constructor(store, eventBus) {
89
+ this.store = store;
90
+ this.eventBus = eventBus;
91
+ this.eventBus.subscribe(['repo.enriched'], (event) => this.handleEnriched(event));
92
+ }
93
+ async handleEnriched(event) {
94
+ const project = this.store.getProject(event.repo.id);
95
+ if (!project) {
96
+ console.log(`[Enricher] Project not found: ${event.repo.id}`);
97
+ return;
98
+ }
99
+ console.log(`[Enricher] Enriching project: ${event.repo.id}`);
100
+ // Store raw data
101
+ project.rawData.languages = event.payload.languages;
102
+ project.rawData.readme = event.payload.readme;
103
+ project.rawData.packageFiles = event.payload.packageFiles;
104
+ // Rule 2: Tech stack inference
105
+ project.techStack = this.inferTechStack(event);
106
+ project.confidence.techStack = this.calculateTechStackConfidence(project.techStack);
107
+ // Rule 3: Purpose extraction
108
+ const { purpose, confidence } = this.extractPurpose(event, project);
109
+ project.purpose = purpose;
110
+ project.confidence.purpose = confidence;
111
+ project.updatedAt = new Date();
112
+ this.store.saveProject(project);
113
+ console.log(`[Enricher] Updated ${event.repo.id}: ${project.techStack.length} tech items, purpose confidence: ${confidence.toFixed(2)}`);
114
+ }
115
+ inferTechStack(event) {
116
+ const techStack = [];
117
+ const seen = new Set();
118
+ // 1. Languages from GitHub API (high confidence)
119
+ const totalBytes = Object.values(event.payload.languages).reduce((a, b) => a + b, 0);
120
+ for (const [lang, bytes] of Object.entries(event.payload.languages)) {
121
+ const normalizedName = LANGUAGE_NAMES[lang] ?? lang;
122
+ if (!seen.has(normalizedName.toLowerCase())) {
123
+ const percentage = totalBytes > 0 ? bytes / totalBytes : 0;
124
+ // Only include languages that are >5% of codebase
125
+ if (percentage > 0.05) {
126
+ techStack.push({
127
+ name: normalizedName,
128
+ category: 'language',
129
+ confidence: Math.min(0.9, 0.5 + percentage),
130
+ source: 'languages_api',
131
+ });
132
+ seen.add(normalizedName.toLowerCase());
133
+ }
134
+ }
135
+ }
136
+ // 2. Frameworks/libraries from package files (high accuracy)
137
+ for (const pkgFile of event.payload.packageFiles) {
138
+ const allDeps = [...pkgFile.dependencies, ...pkgFile.devDependencies];
139
+ for (const dep of allDeps) {
140
+ const pattern = FRAMEWORK_PATTERNS[dep.toLowerCase()];
141
+ if (pattern && !seen.has(pattern.name.toLowerCase())) {
142
+ techStack.push({
143
+ name: pattern.name,
144
+ category: pattern.category,
145
+ confidence: 0.95, // High confidence from explicit dependency
146
+ source: 'package_file',
147
+ });
148
+ seen.add(pattern.name.toLowerCase());
149
+ }
150
+ }
151
+ }
152
+ // 3. README mentions (lower confidence)
153
+ if (event.payload.readme) {
154
+ const readmePatterns = this.extractTechFromReadme(event.payload.readme);
155
+ for (const item of readmePatterns) {
156
+ if (!seen.has(item.name.toLowerCase())) {
157
+ techStack.push({
158
+ ...item,
159
+ confidence: 0.6, // Lower confidence from mentions
160
+ source: 'readme',
161
+ });
162
+ seen.add(item.name.toLowerCase());
163
+ }
164
+ }
165
+ }
166
+ // Sort by confidence
167
+ return techStack.sort((a, b) => b.confidence - a.confidence);
168
+ }
169
+ extractTechFromReadme(readme) {
170
+ const items = [];
171
+ const lowerReadme = readme.toLowerCase();
172
+ // Common patterns in READMEs
173
+ const patterns = [
174
+ { regex: /built with\s+(\w+)/gi, category: 'framework' },
175
+ { regex: /powered by\s+(\w+)/gi, category: 'platform' },
176
+ { regex: /uses?\s+(\w+)\s+for/gi, category: 'library' },
177
+ { regex: /deployed (?:on|to)\s+(\w+)/gi, category: 'platform' },
178
+ ];
179
+ for (const { regex, category } of patterns) {
180
+ let match;
181
+ while ((match = regex.exec(readme)) !== null) {
182
+ const name = match[1];
183
+ // Check if it's a known tech
184
+ if (FRAMEWORK_PATTERNS[name.toLowerCase()] || LANGUAGE_NAMES[name]) {
185
+ items.push({ name, category });
186
+ }
187
+ }
188
+ }
189
+ // Platform detection from common phrases
190
+ const platformPatterns = [
191
+ { pattern: /vercel/i, name: 'Vercel' },
192
+ { pattern: /netlify/i, name: 'Netlify' },
193
+ { pattern: /heroku/i, name: 'Heroku' },
194
+ { pattern: /aws|amazon web services/i, name: 'AWS' },
195
+ { pattern: /google cloud|gcp/i, name: 'Google Cloud' },
196
+ { pattern: /azure/i, name: 'Azure' },
197
+ { pattern: /docker/i, name: 'Docker' },
198
+ { pattern: /kubernetes|k8s/i, name: 'Kubernetes' },
199
+ ];
200
+ for (const { pattern, name } of platformPatterns) {
201
+ if (pattern.test(lowerReadme)) {
202
+ items.push({ name, category: 'platform' });
203
+ }
204
+ }
205
+ return items;
206
+ }
207
+ calculateTechStackConfidence(techStack) {
208
+ if (techStack.length === 0)
209
+ return 0;
210
+ // Average confidence weighted by source reliability
211
+ let totalWeight = 0;
212
+ let weightedSum = 0;
213
+ for (const item of techStack) {
214
+ const weight = item.source === 'package_file' ? 2 : item.source === 'languages_api' ? 1.5 : 1;
215
+ totalWeight += weight;
216
+ weightedSum += item.confidence * weight;
217
+ }
218
+ return totalWeight > 0 ? weightedSum / totalWeight : 0;
219
+ }
220
+ extractPurpose(event, project) {
221
+ // Priority 1: Extract from README first sentence/paragraph
222
+ if (event.payload.readme) {
223
+ const extracted = this.extractPurposeFromReadme(event.payload.readme);
224
+ if (extracted) {
225
+ return { purpose: extracted, confidence: 0.85 };
226
+ }
227
+ }
228
+ // Priority 2: Use description
229
+ if (project.rawData.description) {
230
+ return { purpose: project.rawData.description, confidence: 0.6 };
231
+ }
232
+ // Priority 3: Generate from name and tech stack
233
+ if (project.techStack.length > 0) {
234
+ const frameworks = project.techStack
235
+ .filter(t => t.category === 'framework')
236
+ .map(t => t.name);
237
+ if (frameworks.length > 0) {
238
+ return {
239
+ purpose: `A ${frameworks[0]} project`,
240
+ confidence: 0.3,
241
+ };
242
+ }
243
+ }
244
+ return { purpose: 'Purpose not detected', confidence: 0 };
245
+ }
246
+ extractPurposeFromReadme(readme) {
247
+ // Skip common header patterns
248
+ const lines = readme.split('\n');
249
+ let inHeader = true;
250
+ let firstParagraph = '';
251
+ for (const line of lines) {
252
+ const trimmed = line.trim();
253
+ // Skip badges, headers, and empty lines at start
254
+ if (inHeader) {
255
+ if (trimmed.startsWith('#') ||
256
+ trimmed.startsWith('!') ||
257
+ trimmed.startsWith('[') ||
258
+ trimmed.startsWith('<!--') ||
259
+ trimmed === '' ||
260
+ /^\*\*[^*]+\*\*$/.test(trimmed) // Bold-only lines
261
+ ) {
262
+ continue;
263
+ }
264
+ inHeader = false;
265
+ }
266
+ if (trimmed === '') {
267
+ if (firstParagraph)
268
+ break;
269
+ continue;
270
+ }
271
+ firstParagraph += (firstParagraph ? ' ' : '') + trimmed;
272
+ }
273
+ if (!firstParagraph)
274
+ return null;
275
+ // Clean up and truncate
276
+ const cleaned = firstParagraph
277
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // Remove markdown links
278
+ .replace(/`[^`]+`/g, match => match.slice(1, -1)) // Remove code backticks
279
+ .trim();
280
+ // Take first 2-3 sentences
281
+ const sentences = cleaned.match(/[^.!?]+[.!?]+/g) || [cleaned];
282
+ const purpose = sentences.slice(0, 2).join(' ').trim();
283
+ // Limit length
284
+ if (purpose.length > 300) {
285
+ return purpose.slice(0, 297) + '...';
286
+ }
287
+ return purpose || null;
288
+ }
289
+ }
290
+ //# sourceMappingURL=enricher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enricher.js","sourceRoot":"","sources":["../../src/inference/enricher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from './project-detector.js';
2
+ export * from './enricher.js';
3
+ export * from './lifecycle-tracker.js';
4
+ export * from './portfolio-generator.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inference/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './project-detector.js';
2
+ export * from './enricher.js';
3
+ export * from './lifecycle-tracker.js';
4
+ export * from './portfolio-generator.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/inference/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Lifecycle Tracker - Rule 4: Project completion detection
3
+ * Detects when projects become inactive or are explicitly archived.
4
+ */
5
+ import type { Project, Config } from '../events/types.js';
6
+ import type { ProjectStore } from '../storage/project-store.js';
7
+ import { EventBus } from '../events/event-bus.js';
8
+ export declare class LifecycleTracker {
9
+ private store;
10
+ private eventBus;
11
+ private completionThresholdDays;
12
+ private minCommitsForCompletion;
13
+ constructor(store: ProjectStore, eventBus: EventBus, config: Config);
14
+ /**
15
+ * Handle explicit archive events - high confidence completion
16
+ */
17
+ private handleArchived;
18
+ /**
19
+ * Check all projects for inactivity-based completion
20
+ * Should be called periodically (e.g., after each poll)
21
+ */
22
+ checkForCompletedProjects(): Project[];
23
+ /**
24
+ * Check if project has enough content to be considered a real project
25
+ */
26
+ private hasSubstantialContent;
27
+ /**
28
+ * Calculate confidence in completion status
29
+ */
30
+ private calculateCompletionConfidence;
31
+ /**
32
+ * Manually mark a project as completed
33
+ */
34
+ markAsCompleted(projectId: string): boolean;
35
+ /**
36
+ * Manually mark a project to be ignored (not a portfolio candidate)
37
+ */
38
+ ignoreProject(projectId: string): boolean;
39
+ }
40
+ //# sourceMappingURL=lifecycle-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-tracker.d.ts","sourceRoot":"","sources":["../../src/inference/lifecycle-tracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAGR,OAAO,EACP,MAAM,EACT,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,qBAAa,gBAAgB;IAKrB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;IALpB,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,uBAAuB,CAAS;gBAG5B,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,QAAQ,EAC1B,MAAM,EAAE,MAAM;IAWlB;;OAEG;YACW,cAAc;IAkB5B;;;OAGG;IACH,yBAAyB,IAAI,OAAO,EAAE;IAgCtC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;OAEG;IACH,OAAO,CAAC,6BAA6B;IAuBrC;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAa3C;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;CAW5C"}