@arkone_ai/offer-letter 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/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # @arkone_ai/offer-letter
2
+
3
+ A [Claude Code](https://claude.ai/code) skill that generates branded offer letters as PDF/DOCX and optionally emails them to candidates.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g @arkone_ai/offer-letter
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ In any Claude Code session:
14
+
15
+ ```
16
+ /offer-letter
17
+ ```
18
+
19
+ ## What it does
20
+
21
+ - Generates a professional offer letter from candidate details (name, role, comp, start date)
22
+ - Applies company branding — logo, colors, fonts — from a brand config file or reference document
23
+ - Supports regional templates (US, EU, APAC) and employment types (FTE, contractor)
24
+ - Converts to PDF via Puppeteer/wkhtmltopdf or saves as DOCX
25
+ - Optionally emails the offer to the candidate via SendGrid, Resend, or SES
26
+
27
+ ## License
28
+
29
+ MIT
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { copyFileSync, mkdirSync, existsSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { homedir } from 'os';
6
+
7
+ const root = join(import.meta.dirname, '..');
8
+ const home = homedir();
9
+
10
+ const agents = [
11
+ { name: 'Claude Code', dir: join(home, '.claude', 'skills') },
12
+ { name: 'Codex', dir: join(home, '.codex', 'skills') },
13
+ { name: 'Kiro', dir: join(home, '.kiro', 'skills') },
14
+ ];
15
+
16
+ const files = [
17
+ { src: join(root, 'skill.md'), dest: 'offer-letter.md' },
18
+ ];
19
+
20
+ let installed = 0;
21
+ for (const agent of agents) {
22
+ if (!existsSync(agent.dir)) continue;
23
+ for (const file of files) {
24
+ copyFileSync(file.src, join(agent.dir, file.dest));
25
+ }
26
+ console.log(`✓ ${agent.name}: ${agent.dir}`);
27
+ installed++;
28
+ }
29
+
30
+ if (installed === 0) {
31
+ mkdirSync(agents[0].dir, { recursive: true });
32
+ for (const file of files) {
33
+ copyFileSync(file.src, join(agents[0].dir, file.dest));
34
+ }
35
+ console.log(`✓ Claude Code: ${agents[0].dir}`);
36
+ }
37
+
38
+ console.log('\nUse /offer-letter in any supported AI session.');
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@arkone_ai/offer-letter",
3
+ "version": "1.0.0",
4
+ "description": "Claude Code skill: generate branded offer letters as PDF/DOCX and optionally email them to candidates",
5
+ "type": "module",
6
+ "scripts": {
7
+ "postinstall": "node install/install.js"
8
+ },
9
+ "bin": {
10
+ "offer-letter": "install/install.js"
11
+ },
12
+ "files": [
13
+ "skill.md",
14
+ "install/"
15
+ ],
16
+ "keywords": [
17
+ "claude",
18
+ "claude-code",
19
+ "arkone",
20
+ "hr-ops",
21
+ "offer-letter"
22
+ ],
23
+ "license": "MIT",
24
+ "engines": {
25
+ "node": ">=18"
26
+ }
27
+ }
package/skill.md ADDED
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: offer-letter
3
+ description: "Generate a branded offer letter as PDF/DOCX and optionally email it to the candidate. Use this skill when: 'create offer letter', 'generate offer', 'send offer to candidate', 'draft offer letter', 'make an offer'. Also trigger for: 'employment offer', 'offer package', 'job offer document'."
4
+ license: MIT
5
+ compatibility: Designed for Claude Code
6
+ ---
7
+
8
+ # Skill: offer-letter
9
+
10
+ Generate a professional, branded offer letter and optionally send it to the candidate via email.
11
+
12
+ ## When to use
13
+
14
+ - User wants to create an offer letter for a candidate
15
+ - User wants to send an offer letter via email
16
+ - User wants to generate offer letters in batch
17
+
18
+ ## Step 1: Gather inputs
19
+
20
+ Ask the user for any missing required fields. Use sensible defaults where possible.
21
+
22
+ ### Required fields
23
+
24
+ | Field | Example |
25
+ |---|---|
26
+ | Candidate full name | Jane Smith |
27
+ | Role / job title | Senior Software Engineer |
28
+ | Department | Engineering |
29
+ | Start date | 2026-04-15 |
30
+ | Base salary | $180,000/year |
31
+ | Currency | USD |
32
+
33
+ ### Optional fields
34
+
35
+ | Field | Default |
36
+ |---|---|
37
+ | Signing bonus | — |
38
+ | Equity / stock options | — |
39
+ | Annual bonus target | — |
40
+ | Benefits summary | Standard company benefits |
41
+ | Employment type | Full-time |
42
+ | Location / remote status | — |
43
+ | Reporting manager | — |
44
+ | Offer expiry date | 7 days from generation |
45
+ | Candidate email | — (needed only if sending) |
46
+
47
+ ### Brand assets (optional)
48
+
49
+ | Asset | How to provide |
50
+ |---|---|
51
+ | Company logo | File path to PNG/SVG |
52
+ | Brand colors | Hex codes (primary, secondary) or reference doc |
53
+ | Company name | Text |
54
+ | Reference document | Path to an existing offer letter PDF/DOCX to match style |
55
+ | Brand config | Path to JSON/YAML with all brand settings |
56
+
57
+ Check for a brand config file at these locations (in order):
58
+ 1. Path provided by user
59
+ 2. `./brand-config.json` in current directory
60
+ 3. `~/.claude/hr-brand.json` global config
61
+
62
+ Brand config format:
63
+ ```json
64
+ {
65
+ "company_name": "Acme Corp",
66
+ "logo_path": "/path/to/logo.png",
67
+ "primary_color": "#1a73e8",
68
+ "secondary_color": "#174ea6",
69
+ "accent_color": "#34a853",
70
+ "font": "Inter",
71
+ "footer_text": "Confidential — Acme Corp"
72
+ }
73
+ ```
74
+
75
+ ## Step 2: Choose template
76
+
77
+ Based on inputs, select the appropriate template variant:
78
+
79
+ | Variant | When to use |
80
+ |---|---|
81
+ | US Full-time | Default for US-based FTE roles |
82
+ | US Contractor | When employment type is contractor/1099 |
83
+ | EU Full-time | When location is EU — include GDPR notice, probation period |
84
+ | APAC Full-time | When location is APAC — adjust for local norms |
85
+ | Remote | When fully remote — include remote work terms |
86
+
87
+ If a reference document was provided, extract its layout, tone, section order, and formatting to match instead of using a default template.
88
+
89
+ ## Step 3: Generate the document
90
+
91
+ ### HTML → PDF approach (default)
92
+
93
+ 1. Create an HTML file with inline CSS for the offer letter
94
+ 2. Apply brand assets:
95
+ - Logo in header (right-aligned or centered based on reference doc)
96
+ - Primary color for headings and horizontal rules
97
+ - Secondary color for subheadings
98
+ - Company name in header and footer
99
+ - Footer with confidentiality notice and page numbers
100
+ 3. Structure the letter with these sections:
101
+ - **Header** — company logo + name + date
102
+ - **Greeting** — personalized to candidate
103
+ - **Position details** — role, department, reporting line, start date, location
104
+ - **Compensation** — base salary, bonus, equity (formatted as a clean table)
105
+ - **Benefits summary** — bullet list of key benefits
106
+ - **Terms** — employment type, at-will notice (US), probation (EU), offer expiry
107
+ - **Signature block** — hiring manager + candidate signature lines with date fields
108
+ - **Footer** — confidentiality notice
109
+ 4. Convert to PDF using one of these methods (try in order):
110
+ - `npx puppeteer` — headless Chrome HTML→PDF
111
+ - `wkhtmltopdf` — if installed
112
+ - `prince` — if installed
113
+ - Fall back to saving as HTML and tell the user to print to PDF
114
+
115
+ ### DOCX approach (if user requests)
116
+
117
+ 1. Use `python-docx` or a Node DOCX library (`docx` npm package)
118
+ 2. Apply same structure and branding as above
119
+ 3. Save as .docx
120
+
121
+ ### Output file
122
+
123
+ Save to: `./offer-letter-<candidate-last-name>-<date>.pdf` (or `.docx`)
124
+
125
+ ## Step 4: Send via email (optional)
126
+
127
+ Only if the user provides a candidate email or asks to send.
128
+
129
+ ### Check for email config
130
+
131
+ Look for email API keys in this order:
132
+ 1. Environment variable: `SENDGRID_API_KEY`, `RESEND_API_KEY`, or `SES_ACCESS_KEY`
133
+ 2. Config file: `~/.claude/hr-email.json`
134
+
135
+ Email config format:
136
+ ```json
137
+ {
138
+ "provider": "sendgrid",
139
+ "api_key": "SG.xxxx",
140
+ "from_email": "hr@company.com",
141
+ "from_name": "HR Team",
142
+ "reply_to": "hiring-manager@company.com"
143
+ }
144
+ ```
145
+
146
+ ### Send the email
147
+
148
+ 1. Compose email:
149
+ - **To**: candidate email
150
+ - **Subject**: `Offer Letter — <Role> at <Company>`
151
+ - **Body**: brief, warm message congratulating the candidate, noting the attached offer, and asking them to review and sign by the expiry date
152
+ - **Attachment**: the generated PDF/DOCX
153
+ 2. Send via the configured provider using `curl` or a Node/Python script
154
+ 3. Report success or failure to the user
155
+
156
+ If no email config is found, skip sending and tell the user:
157
+ > "Offer letter generated. To enable email delivery, set `SENDGRID_API_KEY` or create `~/.claude/hr-email.json`."
158
+
159
+ ## Step 5: Output summary
160
+
161
+ After generation (and optional sending), show:
162
+
163
+ ```
164
+ ✅ Offer Letter Generated
165
+ ━━━━━━━━━━━━━━━━━━━━━━━━
166
+ Candidate: Jane Smith
167
+ Role: Senior Software Engineer
168
+ Comp: $180,000 base + $30,000 signing
169
+ Start: 2026-04-15
170
+ Expires: 2026-04-22
171
+ File: ./offer-letter-smith-2026-03-23.pdf
172
+ Email: ✓ Sent to jane@email.com (or ✗ Not configured)
173
+ ```
174
+
175
+ ## Error handling
176
+
177
+ | Issue | What to do |
178
+ |---|---|
179
+ | Missing required field | Ask the user before proceeding |
180
+ | No PDF tool available | Save as HTML, instruct user to `npm i -g puppeteer` |
181
+ | Logo file not found | Generate without logo, warn user |
182
+ | Email send fails | Show error, save the letter locally, suggest manual send |
183
+ | Reference doc unreadable | Fall back to default template, warn user |