@iceinvein/agent-skills 0.1.19 → 0.1.21
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/README.md +20 -0
- package/package.json +2 -1
- package/skills/cover-letter/SKILL.md +161 -0
- package/skills/cover-letter/evals/evals.json +38 -0
- package/skills/cover-letter/evals/inputs/jd-linear-senior-backend.md +43 -0
- package/skills/cover-letter/evals/inputs/jd-pathway-junior-fullstack.md +44 -0
- package/skills/cover-letter/evals/inputs/jd-ramp-senior-go-platform.md +39 -0
- package/skills/cover-letter/evals/inputs/resume-jordan-martinez.md +39 -0
- package/skills/cover-letter/evals/inputs/resume-priya-iyer.md +38 -0
- package/skills/cover-letter/evals/inputs/resume-sam-wu.md +48 -0
- package/skills/cover-letter-audit/SKILL.md +314 -0
- package/skills/cover-letter-persona/SKILL.md +231 -0
- package/skills/cover-letter-rewrite/SKILL.md +298 -0
- package/skills/cover-letter-write/SKILL.md +267 -0
- package/skills/improve-my-codebase/CATALOGUE-FIELDS.md +26 -0
- package/skills/improve-my-codebase/SKILL.md +516 -0
- package/skills/index.json +114 -26
- package/skills/terse/SKILL.md +55 -26
- package/skills/terse/skill.json +6 -3
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cover-letter-rewrite
|
|
3
|
+
description: >
|
|
4
|
+
Revise an existing cover letter by auditing it first, then applying targeted
|
|
5
|
+
fixes: humanize AI-sounding prose, align claims with the resume, tighten
|
|
6
|
+
structure, adjust tone to match an active persona, or improve job-description
|
|
7
|
+
coverage. Preserves the applicant's voice where it's already working. Supports
|
|
8
|
+
focused passes with --focus humanize|align|tighten|structure|tone. Produces
|
|
9
|
+
markdown, DOCX, and PDF outputs. Use when the user says "rewrite cover letter",
|
|
10
|
+
"improve cover letter", "humanize cover letter", "fix cover letter", "tighten
|
|
11
|
+
cover letter", "this cover letter sounds AI", "make this less generic", "make
|
|
12
|
+
this more specific", or shares a letter and asks for edits.
|
|
13
|
+
argument-hint: "<letter-file> [--resume <file>] [--jd <file|url|text>] [--focus humanize|align|tighten|structure|tone] [--length short|standard|long] [--out <dir>]"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Cover Letter Rewrite
|
|
17
|
+
|
|
18
|
+
Revise an existing cover letter instead of starting over. The rewrite is
|
|
19
|
+
audit-driven: run the audit first, then apply a minimum-change rewrite
|
|
20
|
+
targeting the weakest category (or the user's --focus).
|
|
21
|
+
|
|
22
|
+
## When to use rewrite vs write
|
|
23
|
+
|
|
24
|
+
- **Rewrite**: user has a draft they like the bones of. Keep their voice,
|
|
25
|
+
fix specific issues.
|
|
26
|
+
- **Write**: user has resume + JD and nothing else, or the existing letter is
|
|
27
|
+
so generic it would be easier to start fresh (audit score below 50 with
|
|
28
|
+
multiple critical issues).
|
|
29
|
+
|
|
30
|
+
If the user asks to "improve" or "fix" a letter, default to rewrite. If the
|
|
31
|
+
letter scores below 50 with fabrication or complete topic drift, suggest a
|
|
32
|
+
fresh `/cover-letter write` instead.
|
|
33
|
+
|
|
34
|
+
## Inputs
|
|
35
|
+
|
|
36
|
+
Required:
|
|
37
|
+
|
|
38
|
+
- **Letter**: file path (`.md`, `.mdx`, `.docx`, `.pdf`) or pasted text.
|
|
39
|
+
|
|
40
|
+
Optional (but enable key checks):
|
|
41
|
+
|
|
42
|
+
- **Resume** (`--resume <file>`): enables evidence-alignment fixes.
|
|
43
|
+
- **Job description** (`--jd <file|url|text>`): enables coverage fixes.
|
|
44
|
+
|
|
45
|
+
Flags:
|
|
46
|
+
|
|
47
|
+
- `--focus <category>`: narrow the rewrite. See "Focus modes" below.
|
|
48
|
+
- `--length short|standard|long` (180/300/420 target).
|
|
49
|
+
- `--tone <persona-name>`: apply a persona for this run only.
|
|
50
|
+
- `--out <dir>` (default `./cover-letters/`).
|
|
51
|
+
- `--preserve-voice` (stricter; forbid changes outside the flagged issues).
|
|
52
|
+
- `--diff` (emit a unified diff between original and rewrite alongside files).
|
|
53
|
+
|
|
54
|
+
If resume or JD is missing and would be needed for the requested focus,
|
|
55
|
+
either ask for it or proceed with a caveat (for example, `--focus humanize`
|
|
56
|
+
does not need the resume, but `--focus align` does).
|
|
57
|
+
|
|
58
|
+
## Workflow
|
|
59
|
+
|
|
60
|
+
### Step 1: Parse inputs
|
|
61
|
+
|
|
62
|
+
Extract the letter using the same tools as `cover-letter-write`
|
|
63
|
+
(`pdftotext`, `pandoc`, direct read). Normalize to markdown for editing.
|
|
64
|
+
|
|
65
|
+
### Step 2: Run the audit
|
|
66
|
+
|
|
67
|
+
Invoke the audit rubric from `cover-letter-audit` on the letter plus optional
|
|
68
|
+
resume and JD. Capture:
|
|
69
|
+
|
|
70
|
+
- Overall score and category scores
|
|
71
|
+
- Specific issues at each severity level
|
|
72
|
+
- AI signals (burstiness, phrase list hits, TTR, em-dash count, passive %)
|
|
73
|
+
- Evidence alignment gaps
|
|
74
|
+
- JD coverage gaps
|
|
75
|
+
|
|
76
|
+
Do not print the full audit report unless `--show-audit` is passed. A one-line
|
|
77
|
+
score summary is enough.
|
|
78
|
+
|
|
79
|
+
### Step 3: Pick the rewrite plan
|
|
80
|
+
|
|
81
|
+
Without `--focus`, pick the lowest-scoring category as the primary focus and
|
|
82
|
+
apply light fixes to the others. With `--focus`, restrict most changes to that
|
|
83
|
+
category.
|
|
84
|
+
|
|
85
|
+
Rewrite plan is a short internal list: "change X here, replace Y there, add
|
|
86
|
+
sentence about Z". Keep it concrete. Prefer minimal edits.
|
|
87
|
+
|
|
88
|
+
### Step 4: Apply the rewrite
|
|
89
|
+
|
|
90
|
+
Edit the letter. Rules:
|
|
91
|
+
|
|
92
|
+
1. **Preserve sentences that work.** If a sentence is specific, grounded, and
|
|
93
|
+
not on the AI phrase list, leave it alone.
|
|
94
|
+
2. **Targeted replacements.** Rewrite only the sentences or paragraphs that
|
|
95
|
+
triggered the audit issues.
|
|
96
|
+
3. **Do not add facts.** If the audit flagged missing JD coverage and the
|
|
97
|
+
resume has evidence for it, add a clause referencing that evidence. If the
|
|
98
|
+
resume does not have evidence, do not invent any; surface the gap to the
|
|
99
|
+
user instead.
|
|
100
|
+
4. **Respect active persona.** Load `~/.config/cover-letter/active-persona`
|
|
101
|
+
and enforce its rules during the rewrite. The `--preserve-voice` flag
|
|
102
|
+
tightens this: changes outside flagged issues are forbidden.
|
|
103
|
+
5. **Length.** Keep the rewritten letter within the target band. If the
|
|
104
|
+
original was over length, the rewrite should cut. If under, it should add
|
|
105
|
+
only where evidence supports it.
|
|
106
|
+
|
|
107
|
+
### Step 5: Post-rewrite audit
|
|
108
|
+
|
|
109
|
+
Re-run the audit on the new letter. Compare scores. If the rewrite scored
|
|
110
|
+
lower than the original in any category (should be rare), revert to the
|
|
111
|
+
original for that section or ask the user to review the regression.
|
|
112
|
+
|
|
113
|
+
### Step 6: Emit outputs
|
|
114
|
+
|
|
115
|
+
Write markdown first; then derive DOCX and PDF via pandoc (same engine
|
|
116
|
+
fallback order as `cover-letter-write`).
|
|
117
|
+
|
|
118
|
+
If `--diff` is set, also write a unified diff at
|
|
119
|
+
`<out>/<slug>-rewrite.diff`.
|
|
120
|
+
|
|
121
|
+
### Step 7: Report
|
|
122
|
+
|
|
123
|
+
One terse summary:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
Rewrite complete.
|
|
127
|
+
- Files: acme-senior-fe-2026-04-24.md, .docx, .pdf
|
|
128
|
+
- Score: 72 -> 87 (+15)
|
|
129
|
+
- Focus: humanize
|
|
130
|
+
- Changes:
|
|
131
|
+
- Replaced generic opener with specific hook about the offline-first blog post
|
|
132
|
+
- Cut 3 AI phrases ("proven track record", "passionate about", "team player")
|
|
133
|
+
- Raised burstiness by adding one short sentence per paragraph
|
|
134
|
+
- Tightened close from 4 sentences to 2
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Focus modes
|
|
138
|
+
|
|
139
|
+
Each mode targets one category. The writer still performs a cleanup pass on
|
|
140
|
+
the others, but most edits concentrate in the focus area.
|
|
141
|
+
|
|
142
|
+
### humanize
|
|
143
|
+
|
|
144
|
+
Goal: raise the Voice and Humanness category score.
|
|
145
|
+
|
|
146
|
+
Actions:
|
|
147
|
+
|
|
148
|
+
- Replace every AI phrase hit with plain language. "Proven track record of
|
|
149
|
+
delivering results" becomes "Shipped three products to production in the
|
|
150
|
+
last two years" (or similar; use real resume content).
|
|
151
|
+
- Remove em-dashes; replace with period or comma or parentheses.
|
|
152
|
+
- Add burstiness: introduce at least one short sentence (under 10 words) per
|
|
153
|
+
paragraph, and ensure at least one long sentence (over 20 words) per letter.
|
|
154
|
+
- Raise TTR: replace repeated nouns and verbs with synonyms the applicant
|
|
155
|
+
would actually use.
|
|
156
|
+
- Cut hedging and throat-clearing ("I would like to", "I believe", "it is
|
|
157
|
+
fair to say", "arguably").
|
|
158
|
+
|
|
159
|
+
### align
|
|
160
|
+
|
|
161
|
+
Goal: raise Content and Fit + Correctness by matching claims to resume.
|
|
162
|
+
|
|
163
|
+
Actions:
|
|
164
|
+
|
|
165
|
+
- For each unsupported claim, either replace it with a supported one from the
|
|
166
|
+
resume or cut it.
|
|
167
|
+
- For each JD must-have not covered, add one clause referencing real resume
|
|
168
|
+
evidence. If no evidence exists, surface the gap to the user.
|
|
169
|
+
- Remove vague claims ("strong backend skills") and replace with specifics
|
|
170
|
+
("five years Go, two years Rust, shipped the payments gateway at Stripe").
|
|
171
|
+
|
|
172
|
+
### tighten
|
|
173
|
+
|
|
174
|
+
Goal: raise Structure + cut word count.
|
|
175
|
+
|
|
176
|
+
Actions:
|
|
177
|
+
|
|
178
|
+
- Cut redundant sentences.
|
|
179
|
+
- Merge paragraphs if they cover the same subject.
|
|
180
|
+
- Tighten wordy phrases ("in order to" becomes "to"; "due to the fact that"
|
|
181
|
+
becomes "because").
|
|
182
|
+
- Bring to length target.
|
|
183
|
+
- Remove filler sign-off lines.
|
|
184
|
+
|
|
185
|
+
### structure
|
|
186
|
+
|
|
187
|
+
Goal: raise Structure.
|
|
188
|
+
|
|
189
|
+
Actions:
|
|
190
|
+
|
|
191
|
+
- Reorder sections if motivation appears before evidence (put evidence
|
|
192
|
+
second; motivation usually lands better after the fit is established).
|
|
193
|
+
- Rebuild opening if it is a generic greeting or filler opener.
|
|
194
|
+
- Rewrite close to two sentences with a concrete next step, not "I hope to
|
|
195
|
+
hear from you soon".
|
|
196
|
+
|
|
197
|
+
### tone
|
|
198
|
+
|
|
199
|
+
Goal: match the active persona (or --tone override).
|
|
200
|
+
|
|
201
|
+
Actions:
|
|
202
|
+
|
|
203
|
+
- Adjust contraction frequency up or down per persona.
|
|
204
|
+
- Adjust sentence length distribution toward the persona's mean/std.
|
|
205
|
+
- Apply persona's do/don't rules.
|
|
206
|
+
- Swap vocabulary tier (consumer vs professional vs technical) to match.
|
|
207
|
+
|
|
208
|
+
## Examples
|
|
209
|
+
|
|
210
|
+
### humanize focus
|
|
211
|
+
|
|
212
|
+
**Before (AI-sounding):**
|
|
213
|
+
|
|
214
|
+
> Dear Hiring Manager,
|
|
215
|
+
>
|
|
216
|
+
> I am writing to express my strong interest in the Senior Frontend Engineer
|
|
217
|
+
> position at Acme Corp. With a proven track record of delivering cutting-edge
|
|
218
|
+
> solutions in dynamic environments, I am passionate about joining your
|
|
219
|
+
> world-class team and believe I would be a valuable asset.
|
|
220
|
+
|
|
221
|
+
**After (humanized):**
|
|
222
|
+
|
|
223
|
+
> Dear Hiring Team,
|
|
224
|
+
>
|
|
225
|
+
> Your post on offline-first editing in the Acme blog lined up with a problem
|
|
226
|
+
> I spent eighteen months on at Notion: making a collaborative editor survive
|
|
227
|
+
> a subway commute. I'd like to work on the rest of that problem with you.
|
|
228
|
+
|
|
229
|
+
### align focus
|
|
230
|
+
|
|
231
|
+
The JD lists "experience with Kafka" as a must-have. The original letter
|
|
232
|
+
doesn't mention it. The resume lists "migrated order service to Kafka-backed
|
|
233
|
+
event sourcing (2M events/day)". Rewrite adds a single clause:
|
|
234
|
+
|
|
235
|
+
**Before:**
|
|
236
|
+
|
|
237
|
+
> I have extensive backend experience and enjoy working on distributed
|
|
238
|
+
> systems.
|
|
239
|
+
|
|
240
|
+
**After:**
|
|
241
|
+
|
|
242
|
+
> I spent a year moving our order service to Kafka-backed event sourcing at
|
|
243
|
+
> Shopify; it now handles two million events a day.
|
|
244
|
+
|
|
245
|
+
### tighten focus
|
|
246
|
+
|
|
247
|
+
**Before (340 words, 4 paragraphs):**
|
|
248
|
+
|
|
249
|
+
> [Original letter with redundancy and filler]
|
|
250
|
+
|
|
251
|
+
**After (265 words, 3 paragraphs):**
|
|
252
|
+
|
|
253
|
+
> [Same content, cut to essentials, merged redundant paragraphs]
|
|
254
|
+
|
|
255
|
+
## Handling critical issues
|
|
256
|
+
|
|
257
|
+
If the audit finds a critical issue (fabrication, contradiction with resume,
|
|
258
|
+
or factual error about the company), do not auto-rewrite that section. Report
|
|
259
|
+
it to the user and ask how to resolve it:
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
Critical issue: the letter claims "five years at Stripe" but the resume shows
|
|
263
|
+
two years at Stripe (2022-2024). Options:
|
|
264
|
+
1. Change the letter to match the resume (recommended)
|
|
265
|
+
2. Change the resume (if the letter is correct)
|
|
266
|
+
3. Drop the claim
|
|
267
|
+
|
|
268
|
+
Which do you want?
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Wait for the user's answer before completing the rewrite.
|
|
272
|
+
|
|
273
|
+
## Preserve voice mode
|
|
274
|
+
|
|
275
|
+
With `--preserve-voice`, the rewrite must not:
|
|
276
|
+
|
|
277
|
+
- Change sentence structure outside flagged issues
|
|
278
|
+
- Change vocabulary choices outside the AI phrase list
|
|
279
|
+
- Reorder sections
|
|
280
|
+
- Adjust tone dimensions
|
|
281
|
+
|
|
282
|
+
It may only:
|
|
283
|
+
|
|
284
|
+
- Replace flagged AI phrases with plain substitutes
|
|
285
|
+
- Fix fabrications and contradictions
|
|
286
|
+
- Add clauses for uncovered JD must-haves (if resume supports them)
|
|
287
|
+
- Correct grammar and spelling
|
|
288
|
+
|
|
289
|
+
Use this mode for letters the user mostly likes but where one or two specific
|
|
290
|
+
problems need fixing.
|
|
291
|
+
|
|
292
|
+
## What this skill does not do
|
|
293
|
+
|
|
294
|
+
- Does not write a letter from scratch. Route to `cover-letter-write` if the
|
|
295
|
+
existing letter is too generic to save.
|
|
296
|
+
- Does not score the letter without applying changes. Route to
|
|
297
|
+
`cover-letter-audit` for pure scoring.
|
|
298
|
+
- Does not manage personas. Route to `cover-letter-persona`.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cover-letter-write
|
|
3
|
+
description: >
|
|
4
|
+
Generate a cover letter from a resume and a job description. Accepts resume and
|
|
5
|
+
JD as PDF, DOCX, markdown/MDX, URL, or pasted text. Produces markdown, DOCX, and
|
|
6
|
+
PDF outputs. Enforces human-sounding prose (varied sentence length, concrete
|
|
7
|
+
verbs, no filler openers), aligns every claim to a resume bullet, and covers the
|
|
8
|
+
top job-description requirements without keyword stuffing. Respects active
|
|
9
|
+
writing persona if one is set via /cover-letter persona use. Use when the user
|
|
10
|
+
says "write cover letter", "draft cover letter", "generate cover letter", "new
|
|
11
|
+
cover letter", "cover letter for <role>", or shares a resume and job description
|
|
12
|
+
together. Even if the user phrases it as "make me a cover letter" or "help me
|
|
13
|
+
apply to X", trigger this skill.
|
|
14
|
+
argument-hint: "--resume <file> --jd <file|url|text> [--length short|standard|long] [--out <dir>]"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Cover Letter Writer
|
|
18
|
+
|
|
19
|
+
Produce a cover letter that reads like a human wrote it, fits the specific job,
|
|
20
|
+
and only makes claims the resume actually supports.
|
|
21
|
+
|
|
22
|
+
## Inputs
|
|
23
|
+
|
|
24
|
+
Required:
|
|
25
|
+
|
|
26
|
+
- **Resume**: `.pdf`, `.docx`, `.md`, `.mdx`, or `.txt`. Passed as `--resume <path>`
|
|
27
|
+
or as the first file attached to the conversation.
|
|
28
|
+
- **Job description**: file (same formats), URL, or pasted text. Passed as
|
|
29
|
+
`--jd <path|url>` or pasted inline.
|
|
30
|
+
|
|
31
|
+
Optional:
|
|
32
|
+
|
|
33
|
+
- `--length short|standard|long` (180/300/420 words; default standard)
|
|
34
|
+
- `--out <dir>` (default `./cover-letters/`)
|
|
35
|
+
- `--tone <persona-name>` (override active persona for this run only)
|
|
36
|
+
- `--focus <keyword,keyword>` (emphasize specific JD themes)
|
|
37
|
+
- `--no-audit` (skip post-generation self-audit)
|
|
38
|
+
|
|
39
|
+
If either required input is missing, ask for it before proceeding. Do not
|
|
40
|
+
hallucinate resume content or JD requirements.
|
|
41
|
+
|
|
42
|
+
## Workflow
|
|
43
|
+
|
|
44
|
+
Run these steps in order. Report progress concisely after each.
|
|
45
|
+
|
|
46
|
+
### Step 1: Extract inputs
|
|
47
|
+
|
|
48
|
+
Resume parsing:
|
|
49
|
+
|
|
50
|
+
| Format | Command |
|
|
51
|
+
|--------|---------|
|
|
52
|
+
| `.md`, `.mdx`, `.txt` | Read tool, direct |
|
|
53
|
+
| `.pdf` | `pdftotext -layout <file> -` (poppler). Fall back to `pandoc <file> -t markdown` if not installed. |
|
|
54
|
+
| `.docx` | `pandoc <file> -t markdown` |
|
|
55
|
+
|
|
56
|
+
Job description parsing: same table. For URLs, use `WebFetch` and extract the
|
|
57
|
+
visible posting text (skip navigation, footers, "similar jobs" blocks).
|
|
58
|
+
|
|
59
|
+
If a required tool is missing, stop and report the install command
|
|
60
|
+
(`brew install poppler pandoc` on macOS, `apt-get install poppler-utils pandoc`
|
|
61
|
+
on Debian/Ubuntu).
|
|
62
|
+
|
|
63
|
+
### Step 2: Build the fact sheet
|
|
64
|
+
|
|
65
|
+
From the resume, extract:
|
|
66
|
+
|
|
67
|
+
- Full name, email, phone, location, link(s)
|
|
68
|
+
- Current role and company (if present)
|
|
69
|
+
- All past roles with dates, companies, titles
|
|
70
|
+
- Every bullet point, grouped by role
|
|
71
|
+
- Skills, tools, languages, certifications
|
|
72
|
+
- Education
|
|
73
|
+
- Quantified outcomes (numbers, percentages, revenue, users, latency wins)
|
|
74
|
+
|
|
75
|
+
From the job description, extract:
|
|
76
|
+
|
|
77
|
+
- Company name, role title, team (if given), location, work mode
|
|
78
|
+
- Company mission or product line (one sentence if the JD mentions it)
|
|
79
|
+
- Must-have requirements (usually the "Requirements" section)
|
|
80
|
+
- Nice-to-haves
|
|
81
|
+
- Responsibilities
|
|
82
|
+
- Tools, languages, frameworks, methodologies named
|
|
83
|
+
- Tone signals: does the JD read formal, casual, mission-driven, technical-deep?
|
|
84
|
+
|
|
85
|
+
Build an internal JSON scratchpad you can reason from. Do not show it to the
|
|
86
|
+
user unless they ask. Example shape:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"applicant": { "name": "...", "current_role": "...", "years": 7 },
|
|
91
|
+
"jd": { "company": "...", "role": "...", "tone": "casual-technical" },
|
|
92
|
+
"must_haves": ["Go", "distributed systems", "on-call"],
|
|
93
|
+
"evidence_map": {
|
|
94
|
+
"Go": "Payments team at Stripe, 3 years, refactored billing gateway in Go",
|
|
95
|
+
"distributed systems": "Led migration of order service to event-sourced architecture",
|
|
96
|
+
"on-call": null
|
|
97
|
+
},
|
|
98
|
+
"gaps": ["on-call"]
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Step 3: Decide fit strategy
|
|
103
|
+
|
|
104
|
+
From the evidence map, pick the top three to five matches where:
|
|
105
|
+
|
|
106
|
+
1. The requirement is explicitly in the JD (must-have preferred over nice-to-have).
|
|
107
|
+
2. The resume has a concrete, quantified bullet that maps to it.
|
|
108
|
+
3. The bullets are not redundant with each other. Prefer breadth: infra +
|
|
109
|
+
leadership + product sense beats three infra bullets.
|
|
110
|
+
|
|
111
|
+
For each gap (must-have with no resume evidence), decide:
|
|
112
|
+
|
|
113
|
+
- If the gap is important and the user has shown interest in learning, include
|
|
114
|
+
one honest line showing how the applicant bridges it ("I have not shipped Go
|
|
115
|
+
in production, but my Rust work translates closely and I have been writing
|
|
116
|
+
Go for side projects for the last six months") ONLY if the user confirmed
|
|
117
|
+
this background elsewhere. Do not invent.
|
|
118
|
+
- If unconfirmed, flag the gap to the user and ask how to handle it.
|
|
119
|
+
|
|
120
|
+
### Step 4: Load persona
|
|
121
|
+
|
|
122
|
+
Check `~/.config/cover-letter/active-persona`. If a persona is active and the
|
|
123
|
+
user did not override with `--tone`, load that persona JSON.
|
|
124
|
+
|
|
125
|
+
Without a persona, use these defaults:
|
|
126
|
+
|
|
127
|
+
| Setting | Default |
|
|
128
|
+
|---------|---------|
|
|
129
|
+
| Tone dimensions | funny_serious 0.7, formal_casual 0.55, respectful_irreverent 0.2, enthusiastic_matter_of_fact 0.55 |
|
|
130
|
+
| Sentence length mean | 16 |
|
|
131
|
+
| Sentence length std dev | 8 |
|
|
132
|
+
| Contraction frequency | 0.4 (moderate) |
|
|
133
|
+
| Passive voice cap | 10% |
|
|
134
|
+
| Readability | Flesch grade 8-10 |
|
|
135
|
+
|
|
136
|
+
If the JD signals a clear tone (a startup posting that uses "ya'll" and
|
|
137
|
+
emoji wants casual; a law firm posting that uses "the Firm" and
|
|
138
|
+
"heretofore" wants formal), nudge the defaults one step toward that tone
|
|
139
|
+
unless a persona explicitly locks them.
|
|
140
|
+
|
|
141
|
+
### Step 5: Draft the letter
|
|
142
|
+
|
|
143
|
+
Produce a single draft in markdown. Structure:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
[Date]
|
|
147
|
+
|
|
148
|
+
[Hiring Manager / Team name, if known; otherwise skip]
|
|
149
|
+
[Company name]
|
|
150
|
+
|
|
151
|
+
Dear [Name or "Hiring Team"],
|
|
152
|
+
|
|
153
|
+
[Opening hook - 2 sentences]
|
|
154
|
+
|
|
155
|
+
[Fit and evidence - 1 to 2 short paragraphs, 3 to 5 sentences]
|
|
156
|
+
|
|
157
|
+
[Motivation - 2 to 4 sentences]
|
|
158
|
+
|
|
159
|
+
[Close - 2 sentences + plain sign-off]
|
|
160
|
+
|
|
161
|
+
Sincerely,
|
|
162
|
+
[Applicant name]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Writing rules the draft must follow:
|
|
166
|
+
|
|
167
|
+
- **No filler openers.** Do not start with "I am writing to...", "It is with
|
|
168
|
+
great enthusiasm that...", "Please accept this letter as...". Start with a
|
|
169
|
+
specific observation about the role, company, or problem.
|
|
170
|
+
- **Evidence clause shape.** For each claim, pattern is `[specific outcome] at
|
|
171
|
+
[specific context]`. Example: "Cut p99 latency on the checkout API from
|
|
172
|
+
420ms to 95ms at Stripe by moving the pricing lookup into a Redis cache" not
|
|
173
|
+
"Strong backend performance experience".
|
|
174
|
+
- **Burstiness target.** Sentence lengths should vary. At least one sentence
|
|
175
|
+
under 10 words per paragraph and at least one over 20.
|
|
176
|
+
- **Concrete verbs.** Prefer shipped, cut, rewrote, owned, built, led, wrote,
|
|
177
|
+
scaled, debugged. Avoid leveraged, utilized, spearheaded, synergized,
|
|
178
|
+
orchestrated, empowered, facilitated, navigated.
|
|
179
|
+
- **No hollow superlatives.** Avoid "world-class", "cutting-edge",
|
|
180
|
+
"game-changing", "next-generation" unless quoting the company back to itself
|
|
181
|
+
from the JD (and then only once).
|
|
182
|
+
- **Do not repeat the resume.** The letter says what the resume cannot: why
|
|
183
|
+
these bullets matter for *this* role, and why the applicant wants it.
|
|
184
|
+
- **One "I" density check.** Fewer than 40% of sentences should start with "I".
|
|
185
|
+
|
|
186
|
+
### Step 6: Self-audit (unless --no-audit)
|
|
187
|
+
|
|
188
|
+
Before writing files, run the audit checks inline:
|
|
189
|
+
|
|
190
|
+
1. Word count within target band (default 250-400)
|
|
191
|
+
2. No AI phrases from the list in `cover-letter-audit` (50+ phrases)
|
|
192
|
+
3. Sentence length std dev >= 5 (burstiness proxy)
|
|
193
|
+
4. Passive voice <= persona cap (default 10%)
|
|
194
|
+
5. Every claim traceable to a resume bullet
|
|
195
|
+
6. Top 5 JD must-haves are either covered or explicitly acknowledged as gaps
|
|
196
|
+
7. Company name and role appear at least once each
|
|
197
|
+
8. No filler opener
|
|
198
|
+
|
|
199
|
+
If any check fails, revise the draft before emitting files. Report the
|
|
200
|
+
revisions in one line.
|
|
201
|
+
|
|
202
|
+
### Step 7: Emit outputs
|
|
203
|
+
|
|
204
|
+
Write markdown first. Derive DOCX and PDF from it.
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# from cwd or --out dir
|
|
208
|
+
pandoc cover-letter.md -o cover-letter.docx
|
|
209
|
+
pandoc cover-letter.md -o cover-letter.pdf --pdf-engine=weasyprint
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
PDF engine fallback order:
|
|
213
|
+
|
|
214
|
+
1. `weasyprint` (best typography out of the box)
|
|
215
|
+
2. `wkhtmltopdf`
|
|
216
|
+
3. `xelatex` (if a LaTeX distribution is installed)
|
|
217
|
+
4. Chromium headless (`google-chrome --headless --print-to-pdf=out.pdf input.html` after converting md to html with pandoc)
|
|
218
|
+
|
|
219
|
+
If no engine is available, emit only markdown and DOCX, and tell the user which
|
|
220
|
+
install (`brew install weasyprint` on macOS) would unlock the PDF.
|
|
221
|
+
|
|
222
|
+
### Step 8: Report
|
|
223
|
+
|
|
224
|
+
One terse summary: file paths, self-audit score, any acknowledged gaps. If the
|
|
225
|
+
self-audit score is below 85, suggest `/cover-letter rewrite <file> --focus
|
|
226
|
+
humanize` (or whichever category scored lowest).
|
|
227
|
+
|
|
228
|
+
## Handling edge cases
|
|
229
|
+
|
|
230
|
+
- **Resume has no quantified bullets.** Ask the user for one or two numbers
|
|
231
|
+
(team size, users served, revenue, latency, headcount). A bulletless letter
|
|
232
|
+
reads weak. If they cannot provide any, note it and write the letter with
|
|
233
|
+
qualitative evidence only.
|
|
234
|
+
- **JD is vague.** If the JD lacks concrete requirements, shift the letter's
|
|
235
|
+
weight from evidence to motivation, and lean on the company's public
|
|
236
|
+
product/mission. Ask the user for a company URL if none is supplied.
|
|
237
|
+
- **Multiple roles apply.** If the user has several target roles, produce one
|
|
238
|
+
letter per role; do not blend. Ask which one to start with.
|
|
239
|
+
- **Referral or recruiter.** If the user mentions a referrer by name, work
|
|
240
|
+
that into the opening hook in one line, not a paragraph.
|
|
241
|
+
- **Career change.** Lead with motivation and transferable evidence. The gap
|
|
242
|
+
acknowledgment rule applies more heavily here; do not paper over the change.
|
|
243
|
+
|
|
244
|
+
## Example: good opening vs bad opening
|
|
245
|
+
|
|
246
|
+
**Bad (filler, generic, AI-shaped):**
|
|
247
|
+
|
|
248
|
+
> I am writing to express my enthusiastic interest in the Senior Frontend
|
|
249
|
+
> Engineer position at Acme Corp. With over seven years of experience in the
|
|
250
|
+
> industry, I believe I would be a great fit for your dynamic team.
|
|
251
|
+
|
|
252
|
+
**Good (specific, grounded, human):**
|
|
253
|
+
|
|
254
|
+
> Your post on offline-first editing in the Acme blog lined up with a problem
|
|
255
|
+
> I spent eighteen months on at Notion: making a collaborative editor survive
|
|
256
|
+
> a subway commute. I'd like to work on the rest of that problem with you.
|
|
257
|
+
|
|
258
|
+
The first sentence in the good example mentions a specific company post, a
|
|
259
|
+
specific technical problem, a specific prior employer, and a specific duration.
|
|
260
|
+
The bad example says none of that. This difference is the whole point.
|
|
261
|
+
|
|
262
|
+
## Output rendering note
|
|
263
|
+
|
|
264
|
+
Cover letters should render well as PDF. Keep markdown simple: no tables, no
|
|
265
|
+
code blocks, no HTML. Just paragraphs, a date header, and a sign-off. Headers
|
|
266
|
+
and lists in a cover letter look wrong in most contexts, so avoid them unless
|
|
267
|
+
the user explicitly asks.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Catalogue fields for improve-my-codebase
|
|
2
|
+
|
|
3
|
+
The `improve-my-codebase` orchestrator reads `skills/index.json` and routes audits based on two fields:
|
|
4
|
+
|
|
5
|
+
## `applies: string[]`
|
|
6
|
+
|
|
7
|
+
Areas a skill is relevant to. The orchestrator runs an audit only when at least one of its `applies` values matches a detected stack signal (or `any`).
|
|
8
|
+
|
|
9
|
+
| Value | Meaning | Detection signal |
|
|
10
|
+
|-------|---------|------------------|
|
|
11
|
+
| `any` | Always applicable | Always matches |
|
|
12
|
+
| `ui` | Requires UI surface | `.tsx`/`.jsx`/`.vue`/`.svelte`/`.html`/`.css` files, or `react`/`vue`/`svelte`/`solid` in `package.json` deps |
|
|
13
|
+
| `domain` | Requires domain layer | Directory named `domain/`, `entities/`, `aggregates/`, or domain-driven naming |
|
|
14
|
+
| `integration` | Requires messaging/events | Directory named `events/`, `messaging/`, `queues/`, or deps `kafkajs`/`amqplib`/`bullmq` |
|
|
15
|
+
| `architecture` | Cross-cutting structural | Always matches in projects with > 5 files |
|
|
16
|
+
| `errors` | Error handling concerns | Always matches in any non-trivial codebase |
|
|
17
|
+
| `legacy` | Modifying existing code | Only fires when invoked with `diff` mode |
|
|
18
|
+
|
|
19
|
+
## `quick: boolean`
|
|
20
|
+
|
|
21
|
+
Whether the audit qualifies for the `quick` mode. Quick audits should:
|
|
22
|
+
- Be primarily structural or static (file structure, imports, naming).
|
|
23
|
+
- Avoid deep semantic reasoning over function bodies.
|
|
24
|
+
- Return findings within roughly 60 seconds on a medium repo.
|
|
25
|
+
|
|
26
|
+
If unsure, mark `quick: false`. Better to miss in quick mode than to blow the latency budget.
|