autogit-tool 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.
- package/LICENSE +21 -0
- package/README.md +42 -0
- package/dist/ai/prompts.d.ts +10 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +169 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/ai/provider.d.ts +24 -0
- package/dist/ai/provider.d.ts.map +1 -0
- package/dist/ai/provider.js +305 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +228 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/analyze.d.ts +4 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +63 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +457 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/docs.d.ts +5 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +22 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +69 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/github.d.ts +5 -0
- package/dist/commands/github.d.ts.map +1 -0
- package/dist/commands/github.js +46 -0
- package/dist/commands/github.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +38 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/linkedin.d.ts +4 -0
- package/dist/commands/linkedin.d.ts.map +1 -0
- package/dist/commands/linkedin.js +42 -0
- package/dist/commands/linkedin.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +301 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/publish.d.ts +5 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +58 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/readme.d.ts +5 -0
- package/dist/commands/readme.d.ts.map +1 -0
- package/dist/commands/readme.js +32 -0
- package/dist/commands/readme.js.map +1 -0
- package/dist/commands/release.d.ts +5 -0
- package/dist/commands/release.d.ts.map +1 -0
- package/dist/commands/release.js +56 -0
- package/dist/commands/release.js.map +1 -0
- package/dist/commands/resume.d.ts +8 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +228 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/config/manager.d.ts +67 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +78 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/main-pipeline.d.ts +15 -0
- package/dist/pipeline/main-pipeline.d.ts.map +1 -0
- package/dist/pipeline/main-pipeline.js +279 -0
- package/dist/pipeline/main-pipeline.js.map +1 -0
- package/dist/scanner/file-scanner.d.ts +21 -0
- package/dist/scanner/file-scanner.d.ts.map +1 -0
- package/dist/scanner/file-scanner.js +90 -0
- package/dist/scanner/file-scanner.js.map +1 -0
- package/dist/scanner/project-analyzer.d.ts +26 -0
- package/dist/scanner/project-analyzer.d.ts.map +1 -0
- package/dist/scanner/project-analyzer.js +454 -0
- package/dist/scanner/project-analyzer.js.map +1 -0
- package/dist/services/docs-generator.d.ts +11 -0
- package/dist/services/docs-generator.d.ts.map +1 -0
- package/dist/services/docs-generator.js +172 -0
- package/dist/services/docs-generator.js.map +1 -0
- package/dist/services/git-service.d.ts +22 -0
- package/dist/services/git-service.d.ts.map +1 -0
- package/dist/services/git-service.js +162 -0
- package/dist/services/git-service.js.map +1 -0
- package/dist/services/github-service.d.ts +44 -0
- package/dist/services/github-service.d.ts.map +1 -0
- package/dist/services/github-service.js +131 -0
- package/dist/services/github-service.js.map +1 -0
- package/dist/services/insights.d.ts +24 -0
- package/dist/services/insights.d.ts.map +1 -0
- package/dist/services/insights.js +140 -0
- package/dist/services/insights.js.map +1 -0
- package/dist/services/readme-manager.d.ts +11 -0
- package/dist/services/readme-manager.d.ts.map +1 -0
- package/dist/services/readme-manager.js +180 -0
- package/dist/services/readme-manager.js.map +1 -0
- package/dist/services/resume-manager.d.ts +29 -0
- package/dist/services/resume-manager.d.ts.map +1 -0
- package/dist/services/resume-manager.js +186 -0
- package/dist/services/resume-manager.js.map +1 -0
- package/dist/services/social-generator.d.ts +14 -0
- package/dist/services/social-generator.d.ts.map +1 -0
- package/dist/services/social-generator.js +93 -0
- package/dist/services/social-generator.js.map +1 -0
- package/dist/utils/logger.d.ts +19 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +81 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/platform.d.ts +8 -0
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +27 -0
- package/dist/utils/platform.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { getProvider } from '../ai/provider.js';
|
|
2
|
+
import { insightsPrompt } from '../ai/prompts.js';
|
|
3
|
+
import { logger, spinner } from '../utils/logger.js';
|
|
4
|
+
export async function generateInsights(analysis, scan, useAI) {
|
|
5
|
+
if (useAI) {
|
|
6
|
+
const spin = spinner('Analyzing project insights...').start();
|
|
7
|
+
try {
|
|
8
|
+
const provider = getProvider();
|
|
9
|
+
const prompt = insightsPrompt(analysis);
|
|
10
|
+
const messages = [
|
|
11
|
+
{ role: 'system', content: 'You are a senior software engineer providing constructive project analysis. Always return valid JSON.' },
|
|
12
|
+
{ role: 'user', content: prompt },
|
|
13
|
+
];
|
|
14
|
+
const response = await provider.generate(messages, { temperature: 0.3 });
|
|
15
|
+
let content = response.content.trim();
|
|
16
|
+
// Strip markdown fencing
|
|
17
|
+
if (content.startsWith('```json')) {
|
|
18
|
+
content = content.slice(7);
|
|
19
|
+
}
|
|
20
|
+
else if (content.startsWith('```')) {
|
|
21
|
+
content = content.slice(3);
|
|
22
|
+
}
|
|
23
|
+
if (content.endsWith('```')) {
|
|
24
|
+
content = content.slice(0, -3);
|
|
25
|
+
}
|
|
26
|
+
const data = JSON.parse(content.trim());
|
|
27
|
+
spin.succeed('Project insights generated');
|
|
28
|
+
return {
|
|
29
|
+
documentationScore: data.documentation_score || { score: 5, reason: 'Unable to assess' },
|
|
30
|
+
codeQualityScore: data.code_quality_score || { score: 5, reason: 'Unable to assess' },
|
|
31
|
+
maintainabilityScore: data.maintainability_score || { score: 5, reason: 'Unable to assess' },
|
|
32
|
+
suggestions: data.suggestions || [],
|
|
33
|
+
performanceRecommendations: data.performance_recommendations || [],
|
|
34
|
+
securityObservations: data.security_observations || [],
|
|
35
|
+
missingTests: data.missing_tests || [],
|
|
36
|
+
missingDocumentation: data.missing_documentation || [],
|
|
37
|
+
todoSummary: data.todo_summary || [],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
spin.fail('AI insights generation failed');
|
|
42
|
+
logger.warn(`Using static analysis: ${error.message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Static analysis fallback
|
|
46
|
+
return generateStaticInsights(analysis, scan);
|
|
47
|
+
}
|
|
48
|
+
function generateStaticInsights(analysis, scan) {
|
|
49
|
+
const insights = {
|
|
50
|
+
documentationScore: { score: 0, reason: '' },
|
|
51
|
+
codeQualityScore: { score: 0, reason: '' },
|
|
52
|
+
maintainabilityScore: { score: 0, reason: '' },
|
|
53
|
+
suggestions: [],
|
|
54
|
+
performanceRecommendations: [],
|
|
55
|
+
securityObservations: [],
|
|
56
|
+
missingTests: [],
|
|
57
|
+
missingDocumentation: [],
|
|
58
|
+
todoSummary: [],
|
|
59
|
+
};
|
|
60
|
+
// Documentation score
|
|
61
|
+
let docScore = 0;
|
|
62
|
+
if (analysis.hasReadme)
|
|
63
|
+
docScore += 3;
|
|
64
|
+
if (scan.files.some(f => f.name === 'CONTRIBUTING.md'))
|
|
65
|
+
docScore += 2;
|
|
66
|
+
if (scan.files.some(f => f.name === 'CHANGELOG.md'))
|
|
67
|
+
docScore += 2;
|
|
68
|
+
if (analysis.license)
|
|
69
|
+
docScore += 1;
|
|
70
|
+
if (analysis.envVars.length > 0)
|
|
71
|
+
docScore += 1;
|
|
72
|
+
if (scan.files.some(f => f.name.includes('API')))
|
|
73
|
+
docScore += 1;
|
|
74
|
+
insights.documentationScore = {
|
|
75
|
+
score: Math.min(docScore, 10),
|
|
76
|
+
reason: docScore >= 7 ? 'Well documented' : docScore >= 4 ? 'Basic documentation present' : 'Needs more documentation',
|
|
77
|
+
};
|
|
78
|
+
// Code quality score (based on tooling)
|
|
79
|
+
let qualityScore = 5; // base
|
|
80
|
+
if (analysis.testFramework)
|
|
81
|
+
qualityScore += 2;
|
|
82
|
+
if (analysis.cicd.length > 0)
|
|
83
|
+
qualityScore += 1;
|
|
84
|
+
if (scan.files.some(f => f.name.includes('lint') || f.name.includes('eslint') || f.name.includes('prettier')))
|
|
85
|
+
qualityScore += 1;
|
|
86
|
+
if (scan.files.some(f => f.name.includes('.editorconfig')))
|
|
87
|
+
qualityScore += 1;
|
|
88
|
+
insights.codeQualityScore = {
|
|
89
|
+
score: Math.min(qualityScore, 10),
|
|
90
|
+
reason: qualityScore >= 8 ? 'Strong quality tooling' : qualityScore >= 5 ? 'Adequate' : 'Consider adding linting and tests',
|
|
91
|
+
};
|
|
92
|
+
// Maintainability
|
|
93
|
+
let maintScore = 5;
|
|
94
|
+
if (analysis.architecture !== 'unknown')
|
|
95
|
+
maintScore += 1;
|
|
96
|
+
if (scan.directories.length > 3)
|
|
97
|
+
maintScore += 1; // structured project
|
|
98
|
+
if (analysis.buildSystem)
|
|
99
|
+
maintScore += 1;
|
|
100
|
+
const avgFileSize = scan.totalSize / Math.max(scan.totalFiles, 1);
|
|
101
|
+
if (avgFileSize < 10000)
|
|
102
|
+
maintScore += 1; // small files
|
|
103
|
+
if (analysis.languages.length <= 3)
|
|
104
|
+
maintScore += 1; // focused tech stack
|
|
105
|
+
insights.maintainabilityScore = {
|
|
106
|
+
score: Math.min(maintScore, 10),
|
|
107
|
+
reason: maintScore >= 8 ? 'Highly maintainable' : maintScore >= 5 ? 'Moderate maintainability' : 'Consider restructuring',
|
|
108
|
+
};
|
|
109
|
+
// Suggestions
|
|
110
|
+
if (!analysis.hasReadme)
|
|
111
|
+
insights.suggestions.push('Add a README.md');
|
|
112
|
+
if (!analysis.testFramework)
|
|
113
|
+
insights.suggestions.push('Add a testing framework');
|
|
114
|
+
if (analysis.cicd.length === 0)
|
|
115
|
+
insights.suggestions.push('Set up CI/CD pipeline');
|
|
116
|
+
if (!analysis.license)
|
|
117
|
+
insights.suggestions.push('Add a LICENSE file');
|
|
118
|
+
if (analysis.envVars.length > 0 && !scan.files.some(f => f.name === '.env.example')) {
|
|
119
|
+
insights.suggestions.push('Add .env.example for environment variable documentation');
|
|
120
|
+
}
|
|
121
|
+
// Missing documentation
|
|
122
|
+
if (!analysis.hasReadme)
|
|
123
|
+
insights.missingDocumentation.push('README.md');
|
|
124
|
+
if (!scan.files.some(f => f.name === 'CONTRIBUTING.md'))
|
|
125
|
+
insights.missingDocumentation.push('CONTRIBUTING.md');
|
|
126
|
+
if (!scan.files.some(f => f.name === 'CHANGELOG.md'))
|
|
127
|
+
insights.missingDocumentation.push('CHANGELOG.md');
|
|
128
|
+
if (analysis.apis.length > 0 && !scan.files.some(f => f.name.includes('API'))) {
|
|
129
|
+
insights.missingDocumentation.push('API documentation');
|
|
130
|
+
}
|
|
131
|
+
// Security
|
|
132
|
+
if (scan.files.some(f => f.name === '.env')) {
|
|
133
|
+
insights.securityObservations.push('Ensure .env is in .gitignore');
|
|
134
|
+
}
|
|
135
|
+
if (!scan.files.some(f => f.name === '.gitignore')) {
|
|
136
|
+
insights.securityObservations.push('Add .gitignore to prevent committing sensitive files');
|
|
137
|
+
}
|
|
138
|
+
return insights;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=insights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insights.js","sourceRoot":"","sources":["../../src/services/insights.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAcrD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAyB,EACzB,IAAgB,EAChB,KAAc;IAEd,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC,KAAK,EAAE,CAAC;QAC9D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;YAExC,MAAM,QAAQ,GAAgB;gBAC5B,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,uGAAuG,EAAE;gBACpI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;aAClC,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;YACzE,IAAI,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAEtC,yBAAyB;YACzB,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAClC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC;iBAAM,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC;YACD,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACjC,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;YAE3C,OAAO;gBACL,kBAAkB,EAAE,IAAI,CAAC,mBAAmB,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE;gBACxF,gBAAgB,EAAE,IAAI,CAAC,kBAAkB,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE;gBACrF,oBAAoB,EAAE,IAAI,CAAC,qBAAqB,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE;gBAC5F,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;gBACnC,0BAA0B,EAAE,IAAI,CAAC,2BAA2B,IAAI,EAAE;gBAClE,oBAAoB,EAAE,IAAI,CAAC,qBAAqB,IAAI,EAAE;gBACtD,YAAY,EAAE,IAAI,CAAC,aAAa,IAAI,EAAE;gBACtC,oBAAoB,EAAE,IAAI,CAAC,qBAAqB,IAAI,EAAE;gBACtD,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE;aACrC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,OAAO,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,sBAAsB,CAAC,QAAyB,EAAE,IAAgB;IACzE,MAAM,QAAQ,GAAoB;QAChC,kBAAkB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5C,gBAAgB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1C,oBAAoB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9C,WAAW,EAAE,EAAE;QACf,0BAA0B,EAAE,EAAE;QAC9B,oBAAoB,EAAE,EAAE;QACxB,YAAY,EAAE,EAAE;QAChB,oBAAoB,EAAE,EAAE;QACxB,WAAW,EAAE,EAAE;KAChB,CAAC;IAEF,sBAAsB;IACtB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,QAAQ,CAAC,SAAS;QAAE,QAAQ,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC;QAAE,QAAQ,IAAI,CAAC,CAAC;IACtE,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC;QAAE,QAAQ,IAAI,CAAC,CAAC;IACnE,IAAI,QAAQ,CAAC,OAAO;QAAE,QAAQ,IAAI,CAAC,CAAC;IACpC,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,QAAQ,IAAI,CAAC,CAAC;IAC/C,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAAE,QAAQ,IAAI,CAAC,CAAC;IAChE,QAAQ,CAAC,kBAAkB,GAAG;QAC5B,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC7B,MAAM,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,0BAA0B;KACvH,CAAC;IAEF,wCAAwC;IACxC,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC,OAAO;IAC7B,IAAI,QAAQ,CAAC,aAAa;QAAE,YAAY,IAAI,CAAC,CAAC;IAC9C,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,YAAY,IAAI,CAAC,CAAC;IAChD,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAAE,YAAY,IAAI,CAAC,CAAC;IACjI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAAE,YAAY,IAAI,CAAC,CAAC;IAC9E,QAAQ,CAAC,gBAAgB,GAAG;QAC1B,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC;QACjC,MAAM,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,mCAAmC;KAC5H,CAAC;IAEF,kBAAkB;IAClB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,QAAQ,CAAC,YAAY,KAAK,SAAS;QAAE,UAAU,IAAI,CAAC,CAAC;IACzD,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,UAAU,IAAI,CAAC,CAAC,CAAC,qBAAqB;IACvE,IAAI,QAAQ,CAAC,WAAW;QAAE,UAAU,IAAI,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,WAAW,GAAG,KAAK;QAAE,UAAU,IAAI,CAAC,CAAC,CAAC,cAAc;IACxD,IAAI,QAAQ,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC;QAAE,UAAU,IAAI,CAAC,CAAC,CAAC,qBAAqB;IAC1E,QAAQ,CAAC,oBAAoB,GAAG;QAC9B,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC;QAC/B,MAAM,EAAE,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,wBAAwB;KAC1H,CAAC;IAEF,cAAc;IACd,IAAI,CAAC,QAAQ,CAAC,SAAS;QAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACtE,IAAI,CAAC,QAAQ,CAAC,aAAa;QAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAClF,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACnF,IAAI,CAAC,QAAQ,CAAC,OAAO;QAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACvE,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,EAAE,CAAC;QACpF,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;IACvF,CAAC;IAED,wBAAwB;IACxB,IAAI,CAAC,QAAQ,CAAC,SAAS;QAAE,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC;QAAE,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC/G,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC;QAAE,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACzG,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAC9E,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC1D,CAAC;IAED,WAAW;IACX,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CAAC;QAC5C,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,EAAE,CAAC;QACnD,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;IAC7F,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProjectAnalysis } from '../scanner/project-analyzer.js';
|
|
2
|
+
export interface ReadmeResult {
|
|
3
|
+
content: string;
|
|
4
|
+
isNew: boolean;
|
|
5
|
+
diff: string | null;
|
|
6
|
+
path: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function generateReadme(rootDir: string, analysis: ProjectAnalysis, useAI: boolean): Promise<ReadmeResult>;
|
|
9
|
+
export declare function writeReadme(result: ReadmeResult): void;
|
|
10
|
+
export declare function displayDiff(diff: string): void;
|
|
11
|
+
//# sourceMappingURL=readme-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readme-manager.d.ts","sourceRoot":"","sources":["../../src/services/readme-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAKtE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,YAAY,CAAC,CAyDvB;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAEtD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAa9C"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { createPatch } from 'diff';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { getProvider } from '../ai/provider.js';
|
|
6
|
+
import { readmeGenerationPrompt } from '../ai/prompts.js';
|
|
7
|
+
import { logger, spinner } from '../utils/logger.js';
|
|
8
|
+
export async function generateReadme(rootDir, analysis, useAI) {
|
|
9
|
+
const readmePath = analysis.readmePath || join(rootDir, 'README.md');
|
|
10
|
+
const existingContent = existsSync(readmePath) ? readFileSync(readmePath, 'utf-8') : null;
|
|
11
|
+
let newContent;
|
|
12
|
+
if (useAI) {
|
|
13
|
+
const spin = spinner('Generating README with AI...').start();
|
|
14
|
+
try {
|
|
15
|
+
const provider = getProvider();
|
|
16
|
+
const prompt = readmeGenerationPrompt(analysis, existingContent || undefined);
|
|
17
|
+
const messages = [
|
|
18
|
+
{ role: 'system', content: 'You are a professional technical documentation writer.' },
|
|
19
|
+
{ role: 'user', content: prompt },
|
|
20
|
+
];
|
|
21
|
+
const response = await provider.generate(messages, { temperature: 0.5 });
|
|
22
|
+
newContent = response.content.trim();
|
|
23
|
+
// Clean up any markdown fencing the AI might have added
|
|
24
|
+
if (newContent.startsWith('```markdown')) {
|
|
25
|
+
newContent = newContent.slice('```markdown'.length);
|
|
26
|
+
}
|
|
27
|
+
if (newContent.startsWith('```md')) {
|
|
28
|
+
newContent = newContent.slice('```md'.length);
|
|
29
|
+
}
|
|
30
|
+
if (newContent.startsWith('```')) {
|
|
31
|
+
newContent = newContent.slice(3);
|
|
32
|
+
}
|
|
33
|
+
if (newContent.endsWith('```')) {
|
|
34
|
+
newContent = newContent.slice(0, -3);
|
|
35
|
+
}
|
|
36
|
+
newContent = newContent.trim();
|
|
37
|
+
spin.succeed('README generated with AI');
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
spin.fail('AI generation failed');
|
|
41
|
+
logger.warn(`Falling back to template: ${error.message}`);
|
|
42
|
+
newContent = generateTemplateReadme(analysis);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
newContent = generateTemplateReadme(analysis);
|
|
47
|
+
}
|
|
48
|
+
// Generate diff
|
|
49
|
+
let diff = null;
|
|
50
|
+
if (existingContent) {
|
|
51
|
+
diff = createPatch('README.md', existingContent, newContent, 'existing', 'proposed');
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
content: newContent,
|
|
55
|
+
isNew: !existingContent,
|
|
56
|
+
diff,
|
|
57
|
+
path: readmePath,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function writeReadme(result) {
|
|
61
|
+
writeFileSync(result.path, result.content, 'utf-8');
|
|
62
|
+
}
|
|
63
|
+
export function displayDiff(diff) {
|
|
64
|
+
const lines = diff.split('\n');
|
|
65
|
+
for (const line of lines) {
|
|
66
|
+
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
67
|
+
console.log(chalk.green(line));
|
|
68
|
+
}
|
|
69
|
+
else if (line.startsWith('-') && !line.startsWith('---')) {
|
|
70
|
+
console.log(chalk.red(line));
|
|
71
|
+
}
|
|
72
|
+
else if (line.startsWith('@@')) {
|
|
73
|
+
console.log(chalk.cyan(line));
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
console.log(chalk.gray(line));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function generateTemplateReadme(analysis) {
|
|
81
|
+
const sections = [];
|
|
82
|
+
// Title
|
|
83
|
+
sections.push(`# ${analysis.name}\n`);
|
|
84
|
+
// Description
|
|
85
|
+
if (analysis.description) {
|
|
86
|
+
sections.push(`${analysis.description}\n`);
|
|
87
|
+
}
|
|
88
|
+
// Tech Stack
|
|
89
|
+
const techStack = [];
|
|
90
|
+
if (analysis.languages.length)
|
|
91
|
+
techStack.push(...analysis.languages);
|
|
92
|
+
if (analysis.frameworks.length)
|
|
93
|
+
techStack.push(...analysis.frameworks);
|
|
94
|
+
if (techStack.length) {
|
|
95
|
+
sections.push(`## Tech Stack\n`);
|
|
96
|
+
sections.push(techStack.map(t => `- ${t}`).join('\n') + '\n');
|
|
97
|
+
}
|
|
98
|
+
// Features
|
|
99
|
+
if (analysis.features.length) {
|
|
100
|
+
sections.push(`## Features\n`);
|
|
101
|
+
sections.push(analysis.features.map(f => `- ${f}`).join('\n') + '\n');
|
|
102
|
+
}
|
|
103
|
+
// Installation
|
|
104
|
+
sections.push(`## Installation\n`);
|
|
105
|
+
if (analysis.packageManager === 'npm' || analysis.packageManager === 'yarn' || analysis.packageManager === 'pnpm' || analysis.packageManager === 'bun') {
|
|
106
|
+
const pm = analysis.packageManager;
|
|
107
|
+
const installCmd = pm === 'yarn' ? 'yarn' : pm === 'pnpm' ? 'pnpm install' : pm === 'bun' ? 'bun install' : 'npm install';
|
|
108
|
+
sections.push('```bash');
|
|
109
|
+
sections.push(`# Clone the repository`);
|
|
110
|
+
sections.push(`git clone https://github.com/USERNAME/${analysis.name}.git`);
|
|
111
|
+
sections.push(`cd ${analysis.name}`);
|
|
112
|
+
sections.push('');
|
|
113
|
+
sections.push(`# Install dependencies`);
|
|
114
|
+
sections.push(installCmd);
|
|
115
|
+
sections.push('```\n');
|
|
116
|
+
}
|
|
117
|
+
else if (analysis.packageManager === 'cargo') {
|
|
118
|
+
sections.push('```bash');
|
|
119
|
+
sections.push(`git clone https://github.com/USERNAME/${analysis.name}.git`);
|
|
120
|
+
sections.push(`cd ${analysis.name}`);
|
|
121
|
+
sections.push(`cargo build --release`);
|
|
122
|
+
sections.push('```\n');
|
|
123
|
+
}
|
|
124
|
+
else if (analysis.packageManager?.includes('pip')) {
|
|
125
|
+
sections.push('```bash');
|
|
126
|
+
sections.push(`git clone https://github.com/USERNAME/${analysis.name}.git`);
|
|
127
|
+
sections.push(`cd ${analysis.name}`);
|
|
128
|
+
sections.push(`pip install -r requirements.txt`);
|
|
129
|
+
sections.push('```\n');
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
sections.push('```bash');
|
|
133
|
+
sections.push(`git clone https://github.com/USERNAME/${analysis.name}.git`);
|
|
134
|
+
sections.push(`cd ${analysis.name}`);
|
|
135
|
+
sections.push('```\n');
|
|
136
|
+
}
|
|
137
|
+
// Environment Variables
|
|
138
|
+
if (analysis.envVars.length) {
|
|
139
|
+
sections.push(`## Configuration\n`);
|
|
140
|
+
sections.push('Create a `.env` file in the root directory:\n');
|
|
141
|
+
sections.push('```env');
|
|
142
|
+
for (const v of analysis.envVars) {
|
|
143
|
+
sections.push(`${v}=`);
|
|
144
|
+
}
|
|
145
|
+
sections.push('```\n');
|
|
146
|
+
}
|
|
147
|
+
// Usage
|
|
148
|
+
sections.push(`## Usage\n`);
|
|
149
|
+
if (analysis.packageManager === 'npm') {
|
|
150
|
+
sections.push('```bash\nnpm start\n```\n');
|
|
151
|
+
}
|
|
152
|
+
else if (analysis.packageManager === 'yarn') {
|
|
153
|
+
sections.push('```bash\nyarn start\n```\n');
|
|
154
|
+
}
|
|
155
|
+
else if (analysis.packageManager === 'pnpm') {
|
|
156
|
+
sections.push('```bash\npnpm start\n```\n');
|
|
157
|
+
}
|
|
158
|
+
else if (analysis.packageManager === 'bun') {
|
|
159
|
+
sections.push('```bash\nbun start\n```\n');
|
|
160
|
+
}
|
|
161
|
+
else if (analysis.packageManager === 'cargo') {
|
|
162
|
+
sections.push('```bash\ncargo run\n```\n');
|
|
163
|
+
}
|
|
164
|
+
else if (analysis.packageManager?.includes('pip')) {
|
|
165
|
+
sections.push('```bash\npython main.py\n```\n');
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
sections.push('*Add usage instructions here.*\n');
|
|
169
|
+
}
|
|
170
|
+
// Contributing
|
|
171
|
+
sections.push(`## Contributing\n`);
|
|
172
|
+
sections.push(`Contributions are welcome! Please feel free to submit a Pull Request.\n`);
|
|
173
|
+
// License
|
|
174
|
+
if (analysis.license) {
|
|
175
|
+
sections.push(`## License\n`);
|
|
176
|
+
sections.push(`This project is licensed under the ${analysis.license} License.\n`);
|
|
177
|
+
}
|
|
178
|
+
return sections.join('\n');
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=readme-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readme-manager.js","sourceRoot":"","sources":["../../src/services/readme-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ProjectAnalysis } from '../scanner/project-analyzer.js';
|
|
2
|
+
export interface ResumeConfig {
|
|
3
|
+
path: string;
|
|
4
|
+
ownerName: string;
|
|
5
|
+
ownerEmail: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ResumeUpdateResult {
|
|
8
|
+
updated: boolean;
|
|
9
|
+
newEntry: string;
|
|
10
|
+
backupPath?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generate a LaTeX project entry from project analysis.
|
|
14
|
+
* Returns the full \resumeProjectHeading + \resumeItemListStart/End block.
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateLatexProjectEntry(analysis: ProjectAnalysis, useAI: boolean, ownerName: string): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Update a LaTeX resume by inserting a new project entry into the Projects section.
|
|
19
|
+
* Creates a backup before modifying.
|
|
20
|
+
*/
|
|
21
|
+
export declare function updateLatexResume(resumePath: string, newProjectEntry: string): ResumeUpdateResult;
|
|
22
|
+
/**
|
|
23
|
+
* Export resume PDF (if pdflatex is available) to ~/Documents/resume/
|
|
24
|
+
*/
|
|
25
|
+
export declare function exportResumePDF(texPath: string): Promise<{
|
|
26
|
+
exported: boolean;
|
|
27
|
+
pdfPath?: string;
|
|
28
|
+
}>;
|
|
29
|
+
//# sourceMappingURL=resume-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume-manager.d.ts","sourceRoot":"","sources":["../../src/services/resume-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAItE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GACtB,kBAAkB,CAyCpB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA2CvG"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { getProvider } from '../ai/provider.js';
|
|
5
|
+
import { logger, spinner } from '../utils/logger.js';
|
|
6
|
+
/**
|
|
7
|
+
* Generate a LaTeX project entry from project analysis.
|
|
8
|
+
* Returns the full \resumeProjectHeading + \resumeItemListStart/End block.
|
|
9
|
+
*/
|
|
10
|
+
export async function generateLatexProjectEntry(analysis, useAI, ownerName) {
|
|
11
|
+
if (!useAI) {
|
|
12
|
+
return generateTemplateEntry(analysis);
|
|
13
|
+
}
|
|
14
|
+
const spin = spinner('Generating resume entry with AI...').start();
|
|
15
|
+
try {
|
|
16
|
+
const provider = getProvider();
|
|
17
|
+
const prompt = buildResumePrompt(analysis, ownerName);
|
|
18
|
+
const messages = [
|
|
19
|
+
{ role: 'system', content: 'You are a professional resume writer specializing in technical resumes for software engineers.' },
|
|
20
|
+
{ role: 'user', content: prompt },
|
|
21
|
+
];
|
|
22
|
+
const response = await provider.generate(messages, { temperature: 0.6, maxTokens: 800 });
|
|
23
|
+
let entry = response.content.trim();
|
|
24
|
+
// Strip markdown fencing if present
|
|
25
|
+
entry = entry.replace(/^```(?:latex|tex)?\n?/i, '').replace(/\n?```$/i, '').trim();
|
|
26
|
+
spin.succeed('Resume entry generated');
|
|
27
|
+
return entry;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
spin.fail('AI generation failed');
|
|
31
|
+
logger.warn(`Falling back to template: ${error.message}`);
|
|
32
|
+
return generateTemplateEntry(analysis);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Update a LaTeX resume by inserting a new project entry into the Projects section.
|
|
37
|
+
* Creates a backup before modifying.
|
|
38
|
+
*/
|
|
39
|
+
export function updateLatexResume(resumePath, newProjectEntry) {
|
|
40
|
+
if (!existsSync(resumePath)) {
|
|
41
|
+
throw new Error(`Resume file not found: ${resumePath}`);
|
|
42
|
+
}
|
|
43
|
+
const content = readFileSync(resumePath, 'utf-8');
|
|
44
|
+
// Find the Projects section
|
|
45
|
+
const projectsSectionMatch = content.match(/\\section\{Projects\}([\s\S]*?)(?=\\section\{|\\end\{document\})/i);
|
|
46
|
+
if (!projectsSectionMatch) {
|
|
47
|
+
throw new Error('Could not find \\section{Projects} in resume');
|
|
48
|
+
}
|
|
49
|
+
const projectsSection = projectsSectionMatch[0];
|
|
50
|
+
const projectsStart = projectsSectionMatch.index;
|
|
51
|
+
// Find the \resumeSubHeadingListStart after Projects section
|
|
52
|
+
const listStartMatch = projectsSection.match(/\\resumeSubHeadingListStart/);
|
|
53
|
+
if (!listStartMatch) {
|
|
54
|
+
throw new Error('Could not find \\resumeSubHeadingListStart in Projects section');
|
|
55
|
+
}
|
|
56
|
+
// Insert the new entry right after \resumeSubHeadingListStart
|
|
57
|
+
const insertPos = projectsStart + listStartMatch.index + listStartMatch[0].length;
|
|
58
|
+
const updatedContent = content.slice(0, insertPos) +
|
|
59
|
+
'\n\n' + newProjectEntry +
|
|
60
|
+
content.slice(insertPos);
|
|
61
|
+
// Create backup
|
|
62
|
+
const backupPath = resumePath.replace(/\.tex$/i, `.backup-${Date.now()}.tex`);
|
|
63
|
+
writeFileSync(backupPath, content, 'utf-8');
|
|
64
|
+
// Write updated resume
|
|
65
|
+
writeFileSync(resumePath, updatedContent, 'utf-8');
|
|
66
|
+
return {
|
|
67
|
+
updated: true,
|
|
68
|
+
newEntry: newProjectEntry,
|
|
69
|
+
backupPath,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Export resume PDF (if pdflatex is available) to ~/Documents/resume/
|
|
74
|
+
*/
|
|
75
|
+
export async function exportResumePDF(texPath) {
|
|
76
|
+
const docsDir = join(homedir(), 'Documents', 'resume');
|
|
77
|
+
if (!existsSync(docsDir)) {
|
|
78
|
+
mkdirSync(docsDir, { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
// Check if pdflatex is available
|
|
81
|
+
try {
|
|
82
|
+
const { execSync } = await import('child_process');
|
|
83
|
+
execSync('pdflatex --version', { stdio: 'ignore' });
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return { exported: false };
|
|
87
|
+
}
|
|
88
|
+
// Compile LaTeX to PDF in the resume directory
|
|
89
|
+
const texDir = dirname(texPath);
|
|
90
|
+
const texBasename = texPath.split(/[/\\]/).pop().replace(/\.tex$/i, '');
|
|
91
|
+
try {
|
|
92
|
+
const { execSync } = await import('child_process');
|
|
93
|
+
// Run pdflatex twice (for proper references)
|
|
94
|
+
execSync(`pdflatex -interaction=nonstopmode "${texBasename}.tex"`, {
|
|
95
|
+
cwd: texDir,
|
|
96
|
+
stdio: 'ignore',
|
|
97
|
+
});
|
|
98
|
+
execSync(`pdflatex -interaction=nonstopmode "${texBasename}.tex"`, {
|
|
99
|
+
cwd: texDir,
|
|
100
|
+
stdio: 'ignore',
|
|
101
|
+
});
|
|
102
|
+
// Copy PDF to Documents/resume
|
|
103
|
+
const generatedPDF = join(texDir, `${texBasename}.pdf`);
|
|
104
|
+
if (existsSync(generatedPDF)) {
|
|
105
|
+
const destPDF = join(docsDir, `${texBasename}.pdf`);
|
|
106
|
+
const fs = await import('fs');
|
|
107
|
+
fs.copyFileSync(generatedPDF, destPDF);
|
|
108
|
+
return { exported: true, pdfPath: destPDF };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return { exported: false };
|
|
113
|
+
}
|
|
114
|
+
return { exported: false };
|
|
115
|
+
}
|
|
116
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
117
|
+
function buildResumePrompt(analysis, ownerName) {
|
|
118
|
+
const techStack = [...analysis.languages, ...analysis.frameworks, ...analysis.libraries].join(', ');
|
|
119
|
+
const features = analysis.features.length > 0 ? analysis.features.slice(0, 5).join('; ') : 'Core functionality implemented';
|
|
120
|
+
return `Generate a LaTeX resume project entry for ${ownerName}'s technical resume.
|
|
121
|
+
|
|
122
|
+
PROJECT DETAILS:
|
|
123
|
+
- Name: ${analysis.name}
|
|
124
|
+
- Tech Stack: ${techStack}
|
|
125
|
+
- Architecture: ${analysis.architecture}
|
|
126
|
+
- Description: ${analysis.description || 'A software project'}
|
|
127
|
+
- Key Features: ${features}
|
|
128
|
+
${analysis.database.length > 0 ? `- Database: ${analysis.database.join(', ')}` : ''}
|
|
129
|
+
${analysis.deployment.length > 0 ? `- Deployment: ${analysis.deployment.join(', ')}` : ''}
|
|
130
|
+
|
|
131
|
+
INSTRUCTIONS:
|
|
132
|
+
1. Use this LaTeX structure:
|
|
133
|
+
\\resumeProjectHeading
|
|
134
|
+
{\\textbf{Project Name} $|$ \\emph{Category/Type}}{}
|
|
135
|
+
\\resumeItemListStart
|
|
136
|
+
\\resumeItem{Bullet point 1}
|
|
137
|
+
\\resumeItem{Bullet point 2}
|
|
138
|
+
\\resumeItem{Bullet point 3}
|
|
139
|
+
\\resumeItem{\\textbf{Tech Stack:} technologies used}
|
|
140
|
+
\\resumeItemListEnd
|
|
141
|
+
|
|
142
|
+
2. Write 3-4 bullet points using strong action verbs (Built, Developed, Engineered, Implemented, Designed).
|
|
143
|
+
3. Focus on: what was built, technical depth, impact/scale, architectural decisions.
|
|
144
|
+
4. Last bullet should be: \\textbf{Tech Stack:} [list all technologies]
|
|
145
|
+
5. Keep bullets concise but technical (1-2 lines each).
|
|
146
|
+
6. Do NOT add extra commentary or explanations — return ONLY the LaTeX code.
|
|
147
|
+
|
|
148
|
+
Generate the entry now:`;
|
|
149
|
+
}
|
|
150
|
+
function generateTemplateEntry(analysis) {
|
|
151
|
+
const techStack = [...analysis.languages, ...analysis.frameworks, ...analysis.libraries]
|
|
152
|
+
.slice(0, 10)
|
|
153
|
+
.join(', ');
|
|
154
|
+
const projectType = analysis.frameworks.length > 0
|
|
155
|
+
? `${analysis.frameworks[0]} Project`
|
|
156
|
+
: analysis.languages[0]
|
|
157
|
+
? `${analysis.languages[0]} Project`
|
|
158
|
+
: 'Software Project';
|
|
159
|
+
const bullets = [];
|
|
160
|
+
// Bullet 1: What was built
|
|
161
|
+
if (analysis.description) {
|
|
162
|
+
bullets.push(`Built ${analysis.name} — ${analysis.description.toLowerCase()}.`);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
bullets.push(`Developed ${analysis.name}, a ${analysis.architecture.toLowerCase()} application.`);
|
|
166
|
+
}
|
|
167
|
+
// Bullet 2: Technical detail (architecture or key feature)
|
|
168
|
+
if (analysis.features.length > 0) {
|
|
169
|
+
bullets.push(`Implemented ${analysis.features[0].toLowerCase()}.`);
|
|
170
|
+
}
|
|
171
|
+
else if (analysis.database.length > 0) {
|
|
172
|
+
bullets.push(`Designed system architecture with ${analysis.database[0]} database integration.`);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
bullets.push(`Engineered modular ${analysis.architecture.toLowerCase()} with focus on maintainability.`);
|
|
176
|
+
}
|
|
177
|
+
// Bullet 3: Tech stack
|
|
178
|
+
bullets.push(`\\textbf{Tech Stack:} ${techStack}.`);
|
|
179
|
+
const bulletItems = bullets.map(b => ` \\resumeItem{${b}}`).join('\n');
|
|
180
|
+
return ` \\resumeProjectHeading
|
|
181
|
+
{\\textbf{${analysis.name}} $|$ \\emph{${projectType}}}{}
|
|
182
|
+
\\resumeItemListStart
|
|
183
|
+
${bulletItems}
|
|
184
|
+
\\resumeItemListEnd`;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=resume-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume-manager.js","sourceRoot":"","sources":["../../src/services/resume-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ProjectAnalysis } from '../scanner/project-analyzer.js';
|
|
2
|
+
export interface SocialContent {
|
|
3
|
+
linkedin: {
|
|
4
|
+
short: string;
|
|
5
|
+
medium: string;
|
|
6
|
+
long: string;
|
|
7
|
+
};
|
|
8
|
+
twitter: string;
|
|
9
|
+
devto: string;
|
|
10
|
+
resumeBullet: string;
|
|
11
|
+
portfolioDescription: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function generateSocialContent(analysis: ProjectAnalysis, useAI: boolean): Promise<SocialContent>;
|
|
14
|
+
//# sourceMappingURL=social-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social-generator.d.ts","sourceRoot":"","sources":["../../src/services/social-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAKtE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,aAAa,CAAC,CAyCxB"}
|