@rwendell/dossier 0.0.0-stage → 0.1.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 +322 -2
- package/agents/dossier-answerer.md +168 -0
- package/agents/dossier-proposer.md +215 -0
- package/agents/dossier-tailor.md +232 -0
- package/dist/answer/prompt.d.ts +17 -0
- package/dist/answer/prompt.js +44 -0
- package/dist/answer/prompt.js.map +1 -0
- package/dist/answer/run.d.ts +21 -0
- package/dist/answer/run.js +272 -0
- package/dist/answer/run.js.map +1 -0
- package/dist/career/import-resume.d.ts +17 -0
- package/dist/career/import-resume.js +194 -0
- package/dist/career/import-resume.js.map +1 -0
- package/dist/career/load.d.ts +10 -0
- package/dist/career/load.js +96 -0
- package/dist/career/load.js.map +1 -0
- package/dist/career/schema.d.ts +147 -0
- package/dist/career/schema.js +95 -0
- package/dist/career/schema.js.map +1 -0
- package/dist/clean/run.d.ts +1 -0
- package/dist/clean/run.js +8 -0
- package/dist/clean/run.js.map +1 -0
- package/dist/cli/commands/answer.d.ts +23 -0
- package/dist/cli/commands/answer.js +110 -0
- package/dist/cli/commands/answer.js.map +1 -0
- package/dist/cli/commands/clean.d.ts +2 -0
- package/dist/cli/commands/clean.js +11 -0
- package/dist/cli/commands/clean.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.js +83 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init.d.ts +7 -0
- package/dist/cli/commands/init.js +80 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/paths.d.ts +7 -0
- package/dist/cli/commands/paths.js +42 -0
- package/dist/cli/commands/paths.js.map +1 -0
- package/dist/cli/commands/proposal.d.ts +30 -0
- package/dist/cli/commands/proposal.js +148 -0
- package/dist/cli/commands/proposal.js.map +1 -0
- package/dist/cli/commands/pull-private.d.ts +8 -0
- package/dist/cli/commands/pull-private.js +30 -0
- package/dist/cli/commands/pull-private.js.map +1 -0
- package/dist/cli/commands/score.d.ts +11 -0
- package/dist/cli/commands/score.js +58 -0
- package/dist/cli/commands/score.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +13 -0
- package/dist/cli/commands/sync.js +65 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/commands/tailor.d.ts +24 -0
- package/dist/cli/commands/tailor.js +113 -0
- package/dist/cli/commands/tailor.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +6 -0
- package/dist/cli/commands/verify.js +15 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +85 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/config.d.ts +36 -0
- package/dist/config/config.js +71 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/paths.d.ts +34 -0
- package/dist/config/paths.js +126 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/evidence/numbers.d.ts +2 -0
- package/dist/evidence/numbers.js +26 -0
- package/dist/evidence/numbers.js.map +1 -0
- package/dist/evidence/verify.d.ts +109 -0
- package/dist/evidence/verify.js +445 -0
- package/dist/evidence/verify.js.map +1 -0
- package/dist/job/input.d.ts +9 -0
- package/dist/job/input.js +141 -0
- package/dist/job/input.js.map +1 -0
- package/dist/job/page.d.ts +14 -0
- package/dist/job/page.js +426 -0
- package/dist/job/page.js.map +1 -0
- package/dist/job/types.d.ts +30 -0
- package/dist/job/types.js +2 -0
- package/dist/job/types.js.map +1 -0
- package/dist/llm/agents.d.ts +7 -0
- package/dist/llm/agents.js +46 -0
- package/dist/llm/agents.js.map +1 -0
- package/dist/llm/opencode.d.ts +19 -0
- package/dist/llm/opencode.js +117 -0
- package/dist/llm/opencode.js.map +1 -0
- package/dist/llm/providers.d.ts +63 -0
- package/dist/llm/providers.js +207 -0
- package/dist/llm/providers.js.map +1 -0
- package/dist/private/pull.d.ts +7 -0
- package/dist/private/pull.js +168 -0
- package/dist/private/pull.js.map +1 -0
- package/dist/projects/rank.d.ts +17 -0
- package/dist/projects/rank.js +100 -0
- package/dist/projects/rank.js.map +1 -0
- package/dist/projects/store.d.ts +7 -0
- package/dist/projects/store.js +31 -0
- package/dist/projects/store.js.map +1 -0
- package/dist/projects/sync-github.d.ts +11 -0
- package/dist/projects/sync-github.js +269 -0
- package/dist/projects/sync-github.js.map +1 -0
- package/dist/projects/sync-local.d.ts +8 -0
- package/dist/projects/sync-local.js +318 -0
- package/dist/projects/sync-local.js.map +1 -0
- package/dist/projects/types.d.ts +71 -0
- package/dist/projects/types.js +2 -0
- package/dist/projects/types.js.map +1 -0
- package/dist/proposal/prompt.d.ts +20 -0
- package/dist/proposal/prompt.js +64 -0
- package/dist/proposal/prompt.js.map +1 -0
- package/dist/proposal/run.d.ts +28 -0
- package/dist/proposal/run.js +386 -0
- package/dist/proposal/run.js.map +1 -0
- package/dist/resume/basics.d.ts +4 -0
- package/dist/resume/basics.js +33 -0
- package/dist/resume/basics.js.map +1 -0
- package/dist/resume/find.d.ts +12 -0
- package/dist/resume/find.js +27 -0
- package/dist/resume/find.js.map +1 -0
- package/dist/resume/format.d.ts +3 -0
- package/dist/resume/format.js +53 -0
- package/dist/resume/format.js.map +1 -0
- package/dist/resume/one-page.d.ts +149 -0
- package/dist/resume/one-page.js +164 -0
- package/dist/resume/one-page.js.map +1 -0
- package/dist/resume/prompt.d.ts +10 -0
- package/dist/resume/prompt.js +23 -0
- package/dist/resume/prompt.js.map +1 -0
- package/dist/resume/render.d.ts +8 -0
- package/dist/resume/render.js +84 -0
- package/dist/resume/render.js.map +1 -0
- package/dist/resume/run.d.ts +21 -0
- package/dist/resume/run.js +350 -0
- package/dist/resume/run.js.map +1 -0
- package/dist/resume/skills.d.ts +6 -0
- package/dist/resume/skills.js +47 -0
- package/dist/resume/skills.js.map +1 -0
- package/dist/resume/trace.d.ts +13 -0
- package/dist/resume/trace.js +82 -0
- package/dist/resume/trace.js.map +1 -0
- package/dist/resume/types.d.ts +94 -0
- package/dist/resume/types.js +2 -0
- package/dist/resume/types.js.map +1 -0
- package/dist/resume/verify.d.ts +19 -0
- package/dist/resume/verify.js +193 -0
- package/dist/resume/verify.js.map +1 -0
- package/dist/upwork/profile.d.ts +50 -0
- package/dist/upwork/profile.js +302 -0
- package/dist/upwork/profile.js.map +1 -0
- package/dist/upwork/settings.d.ts +96 -0
- package/dist/upwork/settings.js +166 -0
- package/dist/upwork/settings.js.map +1 -0
- package/dist/util/open-file.d.ts +1 -0
- package/dist/util/open-file.js +24 -0
- package/dist/util/open-file.js.map +1 -0
- package/dist/util/slug.d.ts +2 -0
- package/dist/util/slug.js +13 -0
- package/dist/util/slug.js.map +1 -0
- package/dist/verify/run.d.ts +4 -0
- package/dist/verify/run.js +91 -0
- package/dist/verify/run.js.map +1 -0
- package/package.json +67 -4
- package/templates/career.example.yml +63 -0
- package/templates/career.private.example.yml +10 -0
- package/templates/config.example.yml +16 -0
- package/templates/freelance.example.yml +48 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { Achievement, Career, Role } from '../career/schema.js';
|
|
2
|
+
import type { Resume, Trace } from './types.js';
|
|
3
|
+
export declare const PAGE_CONTENT_HEIGHT = 960;
|
|
4
|
+
export declare const LINE_HEIGHT = 21;
|
|
5
|
+
export declare const MIN_FILL_HEIGHT: number;
|
|
6
|
+
export declare const TRIM_PLANS: readonly [{
|
|
7
|
+
readonly recent: 6;
|
|
8
|
+
readonly middle: 4;
|
|
9
|
+
readonly oldest: 2;
|
|
10
|
+
readonly projects: 3;
|
|
11
|
+
readonly skillGroups: 4;
|
|
12
|
+
readonly skillKeywords: 7;
|
|
13
|
+
}, {
|
|
14
|
+
readonly recent: 6;
|
|
15
|
+
readonly middle: 4;
|
|
16
|
+
readonly oldest: 2;
|
|
17
|
+
readonly projects: 3;
|
|
18
|
+
readonly skillGroups: 4;
|
|
19
|
+
readonly skillKeywords: 6;
|
|
20
|
+
}, {
|
|
21
|
+
readonly recent: 6;
|
|
22
|
+
readonly middle: 4;
|
|
23
|
+
readonly oldest: 2;
|
|
24
|
+
readonly projects: 2;
|
|
25
|
+
readonly skillGroups: 4;
|
|
26
|
+
readonly skillKeywords: 6;
|
|
27
|
+
}, {
|
|
28
|
+
readonly recent: 5;
|
|
29
|
+
readonly middle: 4;
|
|
30
|
+
readonly oldest: 2;
|
|
31
|
+
readonly projects: 2;
|
|
32
|
+
readonly skillGroups: 4;
|
|
33
|
+
readonly skillKeywords: 6;
|
|
34
|
+
}, {
|
|
35
|
+
readonly recent: 5;
|
|
36
|
+
readonly middle: 3;
|
|
37
|
+
readonly oldest: 2;
|
|
38
|
+
readonly projects: 2;
|
|
39
|
+
readonly skillGroups: 4;
|
|
40
|
+
readonly skillKeywords: 6;
|
|
41
|
+
}, {
|
|
42
|
+
readonly recent: 5;
|
|
43
|
+
readonly middle: 3;
|
|
44
|
+
readonly oldest: 2;
|
|
45
|
+
readonly projects: 2;
|
|
46
|
+
readonly skillGroups: 3;
|
|
47
|
+
readonly skillKeywords: 6;
|
|
48
|
+
}, {
|
|
49
|
+
readonly recent: 4;
|
|
50
|
+
readonly middle: 3;
|
|
51
|
+
readonly oldest: 2;
|
|
52
|
+
readonly projects: 2;
|
|
53
|
+
readonly skillGroups: 3;
|
|
54
|
+
readonly skillKeywords: 6;
|
|
55
|
+
}, {
|
|
56
|
+
readonly recent: 4;
|
|
57
|
+
readonly middle: 3;
|
|
58
|
+
readonly oldest: 2;
|
|
59
|
+
readonly projects: 2;
|
|
60
|
+
readonly skillGroups: 3;
|
|
61
|
+
readonly skillKeywords: 5;
|
|
62
|
+
}, {
|
|
63
|
+
readonly recent: 4;
|
|
64
|
+
readonly middle: 2;
|
|
65
|
+
readonly oldest: 2;
|
|
66
|
+
readonly projects: 2;
|
|
67
|
+
readonly skillGroups: 3;
|
|
68
|
+
readonly skillKeywords: 5;
|
|
69
|
+
}, {
|
|
70
|
+
readonly recent: 4;
|
|
71
|
+
readonly middle: 2;
|
|
72
|
+
readonly oldest: 1;
|
|
73
|
+
readonly projects: 2;
|
|
74
|
+
readonly skillGroups: 3;
|
|
75
|
+
readonly skillKeywords: 5;
|
|
76
|
+
}, {
|
|
77
|
+
readonly recent: 4;
|
|
78
|
+
readonly middle: 2;
|
|
79
|
+
readonly oldest: 1;
|
|
80
|
+
readonly projects: 1;
|
|
81
|
+
readonly skillGroups: 3;
|
|
82
|
+
readonly skillKeywords: 5;
|
|
83
|
+
}, {
|
|
84
|
+
readonly recent: 3;
|
|
85
|
+
readonly middle: 2;
|
|
86
|
+
readonly oldest: 1;
|
|
87
|
+
readonly projects: 1;
|
|
88
|
+
readonly skillGroups: 3;
|
|
89
|
+
readonly skillKeywords: 5;
|
|
90
|
+
}, {
|
|
91
|
+
readonly recent: 3;
|
|
92
|
+
readonly middle: 2;
|
|
93
|
+
readonly oldest: 1;
|
|
94
|
+
readonly projects: 1;
|
|
95
|
+
readonly skillGroups: 3;
|
|
96
|
+
readonly skillKeywords: 4;
|
|
97
|
+
}, {
|
|
98
|
+
readonly recent: 3;
|
|
99
|
+
readonly middle: 1;
|
|
100
|
+
readonly oldest: 1;
|
|
101
|
+
readonly projects: 1;
|
|
102
|
+
readonly skillGroups: 3;
|
|
103
|
+
readonly skillKeywords: 4;
|
|
104
|
+
}, {
|
|
105
|
+
readonly recent: 2;
|
|
106
|
+
readonly middle: 1;
|
|
107
|
+
readonly oldest: 1;
|
|
108
|
+
readonly projects: 1;
|
|
109
|
+
readonly skillGroups: 2;
|
|
110
|
+
readonly skillKeywords: 5;
|
|
111
|
+
}, {
|
|
112
|
+
readonly recent: 2;
|
|
113
|
+
readonly middle: 1;
|
|
114
|
+
readonly oldest: 1;
|
|
115
|
+
readonly projects: 0;
|
|
116
|
+
readonly skillGroups: 2;
|
|
117
|
+
readonly skillKeywords: 5;
|
|
118
|
+
}, {
|
|
119
|
+
readonly recent: 2;
|
|
120
|
+
readonly middle: 1;
|
|
121
|
+
readonly oldest: 1;
|
|
122
|
+
readonly projects: 0;
|
|
123
|
+
readonly skillGroups: 2;
|
|
124
|
+
readonly skillKeywords: 4;
|
|
125
|
+
}, {
|
|
126
|
+
readonly recent: 1;
|
|
127
|
+
readonly middle: 1;
|
|
128
|
+
readonly oldest: 1;
|
|
129
|
+
readonly projects: 0;
|
|
130
|
+
readonly skillGroups: 2;
|
|
131
|
+
readonly skillKeywords: 4;
|
|
132
|
+
}];
|
|
133
|
+
/**
|
|
134
|
+
* Remove lower-value trailing content so a resume can fit on one page.
|
|
135
|
+
* Mutates resume and trace. Returns true when anything changed.
|
|
136
|
+
*/
|
|
137
|
+
export declare function trimResume(resume: Resume, trace: Trace, level: number): boolean;
|
|
138
|
+
export declare function collectUnusedAchievements(career: Career, trace: Trace): Array<{
|
|
139
|
+
role: Role;
|
|
140
|
+
achievement: Achievement;
|
|
141
|
+
}>;
|
|
142
|
+
export declare function appendAchievement(resume: Resume, trace: Trace, candidate: {
|
|
143
|
+
role: Role;
|
|
144
|
+
achievement: Achievement;
|
|
145
|
+
}): {
|
|
146
|
+
index: number;
|
|
147
|
+
path: string;
|
|
148
|
+
} | null;
|
|
149
|
+
export declare function removeLastHighlight(resume: Resume, trace: Trace, index: number): boolean;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
export const PAGE_CONTENT_HEIGHT = 960;
|
|
2
|
+
export const LINE_HEIGHT = 21;
|
|
3
|
+
export const MIN_FILL_HEIGHT = PAGE_CONTENT_HEIGHT - 2 * LINE_HEIGHT;
|
|
4
|
+
export const TRIM_PLANS = [
|
|
5
|
+
{ recent: 6, middle: 4, oldest: 2, projects: 3, skillGroups: 4, skillKeywords: 7 },
|
|
6
|
+
{ recent: 6, middle: 4, oldest: 2, projects: 3, skillGroups: 4, skillKeywords: 6 },
|
|
7
|
+
{ recent: 6, middle: 4, oldest: 2, projects: 2, skillGroups: 4, skillKeywords: 6 },
|
|
8
|
+
{ recent: 5, middle: 4, oldest: 2, projects: 2, skillGroups: 4, skillKeywords: 6 },
|
|
9
|
+
{ recent: 5, middle: 3, oldest: 2, projects: 2, skillGroups: 4, skillKeywords: 6 },
|
|
10
|
+
{ recent: 5, middle: 3, oldest: 2, projects: 2, skillGroups: 3, skillKeywords: 6 },
|
|
11
|
+
{ recent: 4, middle: 3, oldest: 2, projects: 2, skillGroups: 3, skillKeywords: 6 },
|
|
12
|
+
{ recent: 4, middle: 3, oldest: 2, projects: 2, skillGroups: 3, skillKeywords: 5 },
|
|
13
|
+
{ recent: 4, middle: 2, oldest: 2, projects: 2, skillGroups: 3, skillKeywords: 5 },
|
|
14
|
+
{ recent: 4, middle: 2, oldest: 1, projects: 2, skillGroups: 3, skillKeywords: 5 },
|
|
15
|
+
{ recent: 4, middle: 2, oldest: 1, projects: 1, skillGroups: 3, skillKeywords: 5 },
|
|
16
|
+
{ recent: 3, middle: 2, oldest: 1, projects: 1, skillGroups: 3, skillKeywords: 5 },
|
|
17
|
+
{ recent: 3, middle: 2, oldest: 1, projects: 1, skillGroups: 3, skillKeywords: 4 },
|
|
18
|
+
{ recent: 3, middle: 1, oldest: 1, projects: 1, skillGroups: 3, skillKeywords: 4 },
|
|
19
|
+
{ recent: 2, middle: 1, oldest: 1, projects: 1, skillGroups: 2, skillKeywords: 5 },
|
|
20
|
+
{ recent: 2, middle: 1, oldest: 1, projects: 0, skillGroups: 2, skillKeywords: 5 },
|
|
21
|
+
{ recent: 2, middle: 1, oldest: 1, projects: 0, skillGroups: 2, skillKeywords: 4 },
|
|
22
|
+
{ recent: 1, middle: 1, oldest: 1, projects: 0, skillGroups: 2, skillKeywords: 4 },
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Remove lower-value trailing content so a resume can fit on one page.
|
|
26
|
+
* Mutates resume and trace. Returns true when anything changed.
|
|
27
|
+
*/
|
|
28
|
+
export function trimResume(resume, trace, level) {
|
|
29
|
+
const plan = TRIM_PLANS[Math.min(level, TRIM_PLANS.length - 1)];
|
|
30
|
+
let changed = false;
|
|
31
|
+
const work = Array.isArray(resume.work) ? resume.work : [];
|
|
32
|
+
work.forEach((job, index) => {
|
|
33
|
+
const highlights = Array.isArray(job.highlights) ? job.highlights : [];
|
|
34
|
+
let limit;
|
|
35
|
+
if (work.length === 1 || index === 0)
|
|
36
|
+
limit = plan.recent;
|
|
37
|
+
else if (index === work.length - 1)
|
|
38
|
+
limit = plan.oldest;
|
|
39
|
+
else
|
|
40
|
+
limit = plan.middle;
|
|
41
|
+
if (highlights.length > limit) {
|
|
42
|
+
highlights.splice(limit);
|
|
43
|
+
changed = true;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const projects = Array.isArray(resume.projects) ? resume.projects : [];
|
|
47
|
+
if (projects.length > plan.projects) {
|
|
48
|
+
projects.splice(plan.projects);
|
|
49
|
+
changed = true;
|
|
50
|
+
}
|
|
51
|
+
const groups = Array.isArray(resume.skills) ? resume.skills : [];
|
|
52
|
+
if (groups.length > plan.skillGroups) {
|
|
53
|
+
groups.splice(plan.skillGroups);
|
|
54
|
+
changed = true;
|
|
55
|
+
}
|
|
56
|
+
for (const group of groups) {
|
|
57
|
+
if (Array.isArray(group.keywords) &&
|
|
58
|
+
group.keywords.length > plan.skillKeywords) {
|
|
59
|
+
group.keywords.splice(plan.skillKeywords);
|
|
60
|
+
changed = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (level >= 3 && resume.basics?.summary) {
|
|
64
|
+
const sentences = resume.basics.summary.match(/[^.!?]+[.!?]+/g) ?? [
|
|
65
|
+
resume.basics.summary,
|
|
66
|
+
];
|
|
67
|
+
const shortened = sentences
|
|
68
|
+
.slice(0, level >= 5 ? 1 : 2)
|
|
69
|
+
.join(' ')
|
|
70
|
+
.replace(/\s+/g, ' ')
|
|
71
|
+
.trim();
|
|
72
|
+
if (shortened && shortened.length < resume.basics.summary.length) {
|
|
73
|
+
resume.basics.summary = shortened;
|
|
74
|
+
changed = true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (trimTrace(trace, resume))
|
|
78
|
+
changed = true;
|
|
79
|
+
return changed;
|
|
80
|
+
}
|
|
81
|
+
export function collectUnusedAchievements(career, trace) {
|
|
82
|
+
const used = new Set([
|
|
83
|
+
...(trace.bullets ?? []).flatMap((entry) => entry.evidence ?? []),
|
|
84
|
+
...(trace.summary_evidence ?? []),
|
|
85
|
+
]);
|
|
86
|
+
const candidates = [];
|
|
87
|
+
for (const role of career.roles) {
|
|
88
|
+
for (const achievement of role.achievements) {
|
|
89
|
+
if (!used.has(achievement.id)) {
|
|
90
|
+
candidates.push({ role, achievement });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return candidates.sort((a, b) => (b.achievement.strength ?? 0) - (a.achievement.strength ?? 0) ||
|
|
95
|
+
String(a.achievement.text ?? '').length -
|
|
96
|
+
String(b.achievement.text ?? '').length);
|
|
97
|
+
}
|
|
98
|
+
export function appendAchievement(resume, trace, candidate) {
|
|
99
|
+
const work = Array.isArray(resume.work) ? resume.work : [];
|
|
100
|
+
const index = work.findIndex((job) => normalize(job.name) === normalize(candidate.role.company));
|
|
101
|
+
if (index === -1)
|
|
102
|
+
return null;
|
|
103
|
+
const job = work[index];
|
|
104
|
+
if (!Array.isArray(job.highlights))
|
|
105
|
+
job.highlights = [];
|
|
106
|
+
const text = String(candidate.achievement.text ?? '')
|
|
107
|
+
.replace(/\s+/g, ' ')
|
|
108
|
+
.trim();
|
|
109
|
+
if (!text)
|
|
110
|
+
return null;
|
|
111
|
+
job.highlights.push(text);
|
|
112
|
+
const path = `work[${index}].highlights[${job.highlights.length - 1}]`;
|
|
113
|
+
if (!Array.isArray(trace.bullets))
|
|
114
|
+
trace.bullets = [];
|
|
115
|
+
trace.bullets.push({
|
|
116
|
+
path,
|
|
117
|
+
evidence: [candidate.achievement.id],
|
|
118
|
+
source: 'career',
|
|
119
|
+
});
|
|
120
|
+
return { index, path };
|
|
121
|
+
}
|
|
122
|
+
export function removeLastHighlight(resume, trace, index) {
|
|
123
|
+
const job = resume.work?.[index];
|
|
124
|
+
if (!job || !Array.isArray(job.highlights) || job.highlights.length === 0) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
job.highlights.pop();
|
|
128
|
+
const path = `work[${index}].highlights[${job.highlights.length}]`;
|
|
129
|
+
trace.bullets = (trace.bullets ?? []).filter((entry) => entry.path !== path);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
function normalize(value) {
|
|
133
|
+
return String(value ?? '')
|
|
134
|
+
.toLowerCase()
|
|
135
|
+
.replace(/[^a-z0-9]+/g, ' ')
|
|
136
|
+
.trim();
|
|
137
|
+
}
|
|
138
|
+
function trimTrace(trace, resume) {
|
|
139
|
+
let changed = false;
|
|
140
|
+
const validPaths = new Set();
|
|
141
|
+
(resume.work ?? []).forEach((job, index) => {
|
|
142
|
+
(job.highlights ?? []).forEach((_, highlightIndex) => {
|
|
143
|
+
validPaths.add(`work[${index}].highlights[${highlightIndex}]`);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
(resume.projects ?? []).forEach((project, index) => {
|
|
147
|
+
(project.highlights ?? []).forEach((_, highlightIndex) => {
|
|
148
|
+
validPaths.add(`projects[${index}].highlights[${highlightIndex}]`);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
const bullets = (trace.bullets ?? []).filter((entry) => validPaths.has(entry.path));
|
|
152
|
+
if (bullets.length !== (trace.bullets ?? []).length) {
|
|
153
|
+
trace.bullets = bullets;
|
|
154
|
+
changed = true;
|
|
155
|
+
}
|
|
156
|
+
const projectNames = new Set((resume.projects ?? []).map((project) => project.name));
|
|
157
|
+
const projects = (trace.projects ?? []).filter((entry) => projectNames.has(entry.name));
|
|
158
|
+
if (projects.length !== (trace.projects ?? []).length) {
|
|
159
|
+
trace.projects = projects;
|
|
160
|
+
changed = true;
|
|
161
|
+
}
|
|
162
|
+
return changed;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=one-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"one-page.js","sourceRoot":"","sources":["../../src/resume/one-page.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AACvC,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC9B,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,GAAG,CAAC,GAAG,WAAW,CAAC;AAErE,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE;IAClF,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,E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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Career } from '../career/schema.js';
|
|
2
|
+
import type { Candidate } from '../evidence/verify.js';
|
|
3
|
+
import type { Job } from '../job/types.js';
|
|
4
|
+
export interface TailorPromptInput {
|
|
5
|
+
career: Career;
|
|
6
|
+
job: Job;
|
|
7
|
+
slug: string;
|
|
8
|
+
candidates: Candidate[];
|
|
9
|
+
}
|
|
10
|
+
export declare function buildTailorPrompt({ career, job, slug, candidates, }: TailorPromptInput): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { stringify as stringifyYaml } from 'yaml';
|
|
2
|
+
export function buildTailorPrompt({ career, job, slug, candidates, }) {
|
|
3
|
+
const sections = [
|
|
4
|
+
'<application>',
|
|
5
|
+
`company: ${job.company || '(not provided)'}`,
|
|
6
|
+
`title: ${job.title}`,
|
|
7
|
+
`url: ${job.url || '(not provided)'}`,
|
|
8
|
+
`slug: ${slug}`,
|
|
9
|
+
'</application>',
|
|
10
|
+
'',
|
|
11
|
+
'<job_description>',
|
|
12
|
+
job.body || job.title,
|
|
13
|
+
'</job_description>',
|
|
14
|
+
];
|
|
15
|
+
if (job.details && Object.keys(job.details).length > 0) {
|
|
16
|
+
sections.push('', '<job_details>', stringifyYaml(job.details).trim(), '</job_details>');
|
|
17
|
+
}
|
|
18
|
+
sections.push('', '<career>', stringifyYaml(career).trim(), '</career>', '', '<project_candidates>', JSON.stringify(candidates, null, 2), '</project_candidates>', '', 'The project entries above are candidates, not verified facts. They may come from personal GitHub, organizations, or local ~/projects repositories. Use a candidate only when it directly demonstrates a requirement and its README or local commit context supports the claim. Cite the entry\'s `evidence` value. Do not include a candidate merely because it is recent or pinned.', '', `Tailor the resume for the ${job.title} role${job.company ? ` at ${job.company}` : ''}.`, job.source === 'generic'
|
|
19
|
+
? 'This is a general-purpose resume, not a specific job. Follow the generic prioritization criteria in the job description.'
|
|
20
|
+
: '', 'The resume must fit on exactly one page and fill it. Return the JSON object described in your system prompt. Output JSON only.');
|
|
21
|
+
return sections.join('\n');
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/resume/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC;AAYlD,MAAM,UAAU,iBAAiB,CAAC,EAChC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,UAAU,GACQ;IAClB,MAAM,QAAQ,GAAa;QACzB,eAAe;QACf,YAAY,GAAG,CAAC,OAAO,IAAI,gBAAgB,EAAE;QAC7C,UAAU,GAAG,CAAC,KAAK,EAAE;QACrB,QAAQ,GAAG,CAAC,GAAG,IAAI,gBAAgB,EAAE;QACrC,SAAS,IAAI,EAAE;QACf,gBAAgB;QAChB,EAAE;QACF,mBAAmB;QACnB,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK;QACrB,oBAAoB;KACrB,CAAC;IAEF,IAAI,GAAG,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvD,QAAQ,CAAC,IAAI,CACX,EAAE,EACF,eAAe,EACf,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EACjC,gBAAgB,CACjB,CAAC;IACJ,CAAC;IAED,QAAQ,CAAC,IAAI,CACX,EAAE,EACF,UAAU,EACV,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAC5B,WAAW,EACX,EAAE,EACF,sBAAsB,EACtB,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EACnC,uBAAuB,EACvB,EAAE,EACF,sXAAsX,EACtX,EAAE,EACF,6BAA6B,GAAG,CAAC,KAAK,QAAQ,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EACxF,GAAG,CAAC,MAAM,KAAK,SAAS;QACtB,CAAC,CAAC,0HAA0H;QAC5H,CAAC,CAAC,EAAE,EACN,gIAAgI,CACjI,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function renderHtml(resumePath: string, htmlPath: string, theme: string): void;
|
|
2
|
+
export declare function renderPdf(resumePath: string, pdfPath: string, theme: string): void;
|
|
3
|
+
export declare function getPdfPageCount(pdfPath: string): Promise<number>;
|
|
4
|
+
export interface PageMeasurer {
|
|
5
|
+
measure(htmlPath: string): Promise<number>;
|
|
6
|
+
close(): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createPageMeasurer(): Promise<PageMeasurer>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
|
+
import { PDFDocument } from 'pdf-lib';
|
|
6
|
+
import { PAGE_CONTENT_HEIGHT } from './one-page.js';
|
|
7
|
+
const packageRoot = fileURLToPath(new URL('../../', import.meta.url));
|
|
8
|
+
function resumedBin() {
|
|
9
|
+
const main = fileURLToPath(import.meta.resolve('resumed'));
|
|
10
|
+
return join(dirname(dirname(main)), 'bin', 'resumed.js');
|
|
11
|
+
}
|
|
12
|
+
export function renderHtml(resumePath, htmlPath, theme) {
|
|
13
|
+
const result = spawnSync(process.execPath, [resumedBin(), 'render', resumePath, '-o', htmlPath, '-t', theme], {
|
|
14
|
+
cwd: packageRoot,
|
|
15
|
+
encoding: 'utf8',
|
|
16
|
+
timeout: 120_000,
|
|
17
|
+
});
|
|
18
|
+
if (result.error || result.status !== 0 || !existsSync(htmlPath)) {
|
|
19
|
+
const detail = result.error?.message ||
|
|
20
|
+
result.stderr?.trim() ||
|
|
21
|
+
`exited with status ${result.status}`;
|
|
22
|
+
throw new Error(`Could not render resume HTML: ${detail}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function renderPdf(resumePath, pdfPath, theme) {
|
|
26
|
+
const result = spawnSync(process.execPath, [
|
|
27
|
+
resumedBin(),
|
|
28
|
+
'export',
|
|
29
|
+
resumePath,
|
|
30
|
+
'-o',
|
|
31
|
+
pdfPath,
|
|
32
|
+
'-t',
|
|
33
|
+
theme,
|
|
34
|
+
'--puppeteer-arg=--no-sandbox',
|
|
35
|
+
], {
|
|
36
|
+
cwd: packageRoot,
|
|
37
|
+
encoding: 'utf8',
|
|
38
|
+
timeout: 180_000,
|
|
39
|
+
});
|
|
40
|
+
if (result.error || result.status !== 0 || !existsSync(pdfPath)) {
|
|
41
|
+
const detail = result.error?.message ||
|
|
42
|
+
result.stderr?.trim() ||
|
|
43
|
+
`exited with status ${result.status}`;
|
|
44
|
+
throw new Error(`Could not render resume PDF: ${detail}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function getPdfPageCount(pdfPath) {
|
|
48
|
+
const pdf = await PDFDocument.load(readFileSync(pdfPath), {
|
|
49
|
+
ignoreEncryption: true,
|
|
50
|
+
});
|
|
51
|
+
return pdf.getPageCount();
|
|
52
|
+
}
|
|
53
|
+
export async function createPageMeasurer() {
|
|
54
|
+
const puppeteer = (await import('puppeteer')).default;
|
|
55
|
+
const browser = await puppeteer.launch({
|
|
56
|
+
headless: true,
|
|
57
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
58
|
+
});
|
|
59
|
+
return {
|
|
60
|
+
async measure(htmlPath) {
|
|
61
|
+
const page = await browser.newPage();
|
|
62
|
+
try {
|
|
63
|
+
await page.emulateMediaType('print');
|
|
64
|
+
await page.setViewport({
|
|
65
|
+
width: 720,
|
|
66
|
+
height: PAGE_CONTENT_HEIGHT,
|
|
67
|
+
deviceScaleFactor: 1,
|
|
68
|
+
});
|
|
69
|
+
await page.goto(pathToFileURL(htmlPath).href, { waitUntil: 'load' });
|
|
70
|
+
return await page.evaluate(() => {
|
|
71
|
+
const resume = document.querySelector('#resume') ?? document.body;
|
|
72
|
+
return resume.getBoundingClientRect().height;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
await page.close();
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
async close() {
|
|
80
|
+
await browser.close();
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/resume/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface TailorRunOptions {
|
|
2
|
+
input?: string;
|
|
3
|
+
out?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
company?: string;
|
|
7
|
+
url?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
generic?: boolean;
|
|
10
|
+
profile?: string;
|
|
11
|
+
noProfile?: boolean;
|
|
12
|
+
theme?: string;
|
|
13
|
+
provider?: string;
|
|
14
|
+
model?: string;
|
|
15
|
+
timeout?: number;
|
|
16
|
+
refresh?: boolean;
|
|
17
|
+
noRender?: boolean;
|
|
18
|
+
open?: boolean;
|
|
19
|
+
debug?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function runTailor(options: TailorRunOptions): Promise<void>;
|