careerclaw-js 0.11.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/CHANGELOG.md +362 -0
- package/README.md +348 -0
- package/SECURITY.md +156 -0
- package/SKILL.md +463 -0
- package/dist/adapters/hackernews.d.ts +36 -0
- package/dist/adapters/hackernews.d.ts.map +1 -0
- package/dist/adapters/hackernews.js +164 -0
- package/dist/adapters/hackernews.js.map +1 -0
- package/dist/adapters/index.d.ts +10 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +9 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/remoteok.d.ts +35 -0
- package/dist/adapters/remoteok.d.ts.map +1 -0
- package/dist/adapters/remoteok.js +212 -0
- package/dist/adapters/remoteok.js.map +1 -0
- package/dist/briefing.d.ts +81 -0
- package/dist/briefing.d.ts.map +1 -0
- package/dist/briefing.js +152 -0
- package/dist/briefing.js.map +1 -0
- package/dist/cli.d.ts +22 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +235 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +91 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +126 -0
- package/dist/config.js.map +1 -0
- package/dist/core/text-processing.d.ts +62 -0
- package/dist/core/text-processing.d.ts.map +1 -0
- package/dist/core/text-processing.js +187 -0
- package/dist/core/text-processing.js.map +1 -0
- package/dist/drafting.d.ts +28 -0
- package/dist/drafting.d.ts.map +1 -0
- package/dist/drafting.js +116 -0
- package/dist/drafting.js.map +1 -0
- package/dist/gap.d.ts +27 -0
- package/dist/gap.d.ts.map +1 -0
- package/dist/gap.js +90 -0
- package/dist/gap.js.map +1 -0
- package/dist/license.d.ts +40 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +122 -0
- package/dist/license.js.map +1 -0
- package/dist/llm-enhance.d.ts +69 -0
- package/dist/llm-enhance.d.ts.map +1 -0
- package/dist/llm-enhance.js +376 -0
- package/dist/llm-enhance.js.map +1 -0
- package/dist/matching/engine.d.ts +31 -0
- package/dist/matching/engine.d.ts.map +1 -0
- package/dist/matching/engine.js +51 -0
- package/dist/matching/engine.js.map +1 -0
- package/dist/matching/index.d.ts +8 -0
- package/dist/matching/index.d.ts.map +1 -0
- package/dist/matching/index.js +8 -0
- package/dist/matching/index.js.map +1 -0
- package/dist/matching/scoring.d.ts +84 -0
- package/dist/matching/scoring.d.ts.map +1 -0
- package/dist/matching/scoring.js +184 -0
- package/dist/matching/scoring.js.map +1 -0
- package/dist/models.d.ts +221 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +28 -0
- package/dist/models.js.map +1 -0
- package/dist/requirements.d.ts +22 -0
- package/dist/requirements.d.ts.map +1 -0
- package/dist/requirements.js +30 -0
- package/dist/requirements.js.map +1 -0
- package/dist/resume-intel.d.ts +40 -0
- package/dist/resume-intel.d.ts.map +1 -0
- package/dist/resume-intel.js +111 -0
- package/dist/resume-intel.js.map +1 -0
- package/dist/sources.d.ts +32 -0
- package/dist/sources.d.ts.map +1 -0
- package/dist/sources.js +72 -0
- package/dist/sources.js.map +1 -0
- package/dist/tracking.d.ts +68 -0
- package/dist/tracking.d.ts.map +1 -0
- package/dist/tracking.js +140 -0
- package/dist/tracking.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# careerclaw-js
|
|
2
|
+
|
|
3
|
+
[](https://github.com/orestes-garcia-martinez/careerclaw-js/actions/workflows/ci.yml)
|
|
4
|
+
|
|
5
|
+
**Privacy-first job search automation for OpenClaw — Node.js / TypeScript.**
|
|
6
|
+
|
|
7
|
+
CareerClaw turns your AI agent into a structured daily workflow:
|
|
8
|
+
fetch listings → rank matches → draft outreach → track applications.
|
|
9
|
+
|
|
10
|
+
- **Local-first:** your resume and results stay on your machine
|
|
11
|
+
- **No subscription:** one-time purchase for Pro
|
|
12
|
+
- **Bring your own LLM API key (optional):** use OpenAI or Anthropic to enhance drafts
|
|
13
|
+
- **Works everywhere:** Node.js is natively available in every OpenClaw deployment
|
|
14
|
+
|
|
15
|
+
> **Why a Node.js rewrite?** The OpenClaw gateway ships Node.js v22 and npm natively,
|
|
16
|
+
> but has no Python package manager — making the original Python package's self-healing
|
|
17
|
+
> installation impossible in Docker-based deployments. careerclaw-js resolves this permanently.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## How It Works
|
|
22
|
+
|
|
23
|
+
1. **Fetches** job listings from RemoteOK RSS and Hacker News Who's Hiring
|
|
24
|
+
2. **Ranks** them against your profile using keyword overlap, experience alignment, salary fit, and work-mode preference
|
|
25
|
+
3. **Drafts** outreach for each top match (deterministic template on Free; LLM-enhanced on Pro)
|
|
26
|
+
4. **Tracks** your application pipeline locally in `.careerclaw/`
|
|
27
|
+
|
|
28
|
+
One command. Everything is local.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Quickstart
|
|
33
|
+
|
|
34
|
+
### 1. Install
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install -g careerclaw-js
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Verify:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
careerclaw-js --version
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Set up via OpenClaw (recommended)
|
|
47
|
+
|
|
48
|
+
If you are running CareerClaw through OpenClaw/ClawHub, the agent guides you through
|
|
49
|
+
setup automatically. Upload your resume and it will extract your profile, ask two questions
|
|
50
|
+
(work mode + salary floor), and run your first briefing.
|
|
51
|
+
|
|
52
|
+
### 3. Set up manually
|
|
53
|
+
|
|
54
|
+
Create the runtime directory and profile:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
mkdir -p ~/.careerclaw
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Create `~/.careerclaw/profile.json`:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"skills": ["typescript", "python", "react", "sql"],
|
|
65
|
+
"target_roles": ["senior engineer", "staff engineer"],
|
|
66
|
+
"experience_years": 7,
|
|
67
|
+
"work_mode": "remote",
|
|
68
|
+
"resume_summary": "Senior engineer with 7 years building distributed systems and developer tools.",
|
|
69
|
+
"location": "Austin, TX",
|
|
70
|
+
"salary_min": 150000
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 4. Run your first briefing
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Dry run first — no files written, safe to preview
|
|
78
|
+
careerclaw-js --dry-run
|
|
79
|
+
|
|
80
|
+
# With your resume for better match quality (recommended)
|
|
81
|
+
careerclaw-js --resume-txt ~/.careerclaw/resume.txt --dry-run
|
|
82
|
+
|
|
83
|
+
# Full run when you're happy with the results
|
|
84
|
+
careerclaw-js --resume-txt ~/.careerclaw/resume.txt
|
|
85
|
+
|
|
86
|
+
# JSON output for agent/script consumption
|
|
87
|
+
careerclaw-js --resume-txt ~/.careerclaw/resume.txt --json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Sample Output
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
=== CareerClaw Daily Briefing ===
|
|
96
|
+
Fetched jobs: 289 | Sources: remoteok: 98 | hackernews: 191
|
|
97
|
+
Duration: 1887ms fetch + 24ms rank
|
|
98
|
+
|
|
99
|
+
Top Matches:
|
|
100
|
+
|
|
101
|
+
1) Senior Full-Stack Engineer @ Instinct Science [hackernews]
|
|
102
|
+
score: 0.2329 | fit: 8%
|
|
103
|
+
matches: react, typescript, design, aws, senior
|
|
104
|
+
gaps: elixir, postgresql, emr
|
|
105
|
+
location: REMOTE (US)
|
|
106
|
+
url: https://news.ycombinator.com/item?id=47233919
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Free vs Pro
|
|
112
|
+
|
|
113
|
+
| Feature | Free | Pro ($39 lifetime) |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| Daily briefing | ✅ | ✅ |
|
|
116
|
+
| Top 3 ranked matches | ✅ | ✅ |
|
|
117
|
+
| Application tracking | ✅ | ✅ |
|
|
118
|
+
| Outreach email draft (template) | ✅ | ✅ |
|
|
119
|
+
| LLM-enhanced outreach email | — | ✅ |
|
|
120
|
+
| Resume gap analysis | — | ✅ |
|
|
121
|
+
| Cover letter (tailored, <300 words) | — | ✅ coming soon |
|
|
122
|
+
|
|
123
|
+
**Pro tier: $39 one-time (lifetime license).**
|
|
124
|
+
|
|
125
|
+
Purchase: https://ogm.gumroad.com/l/careerclaw-pro
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Pro: Activating
|
|
130
|
+
|
|
131
|
+
Purchase a license key on Gumroad. The key is emailed immediately after payment.
|
|
132
|
+
|
|
133
|
+
### Docker / self-hosted
|
|
134
|
+
|
|
135
|
+
Add to your `.env`:
|
|
136
|
+
|
|
137
|
+
```env
|
|
138
|
+
CAREERCLAW_PRO_KEY=YOUR-KEY-HERE
|
|
139
|
+
CAREERCLAW_GUMROAD_PRODUCT_ID=YOUR-PRODUCT-ID
|
|
140
|
+
CAREERCLAW_OPENAI_KEY=sk-...
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### OpenClaw managed users
|
|
144
|
+
|
|
145
|
+
Tell your agent:
|
|
146
|
+
|
|
147
|
+
> "Set my CAREERCLAW_PRO_KEY to YOUR-KEY-HERE"
|
|
148
|
+
|
|
149
|
+
The key is validated against Gumroad on first use and cached locally as a SHA-256 hash.
|
|
150
|
+
Re-validation happens every 7 days (requires internet).
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Pro: LLM-Enhanced Drafts
|
|
155
|
+
|
|
156
|
+
With a valid Pro license and an LLM API key, CareerClaw writes personalised outreach emails
|
|
157
|
+
using your actual resume signals mapped to each job's specific requirements. Falls back to
|
|
158
|
+
the deterministic template silently on any LLM failure.
|
|
159
|
+
|
|
160
|
+
Failover chain example (tries Anthropic first, falls back to OpenAI):
|
|
161
|
+
|
|
162
|
+
```env
|
|
163
|
+
CAREERCLAW_ANTHROPIC_KEY=sk-ant-...
|
|
164
|
+
CAREERCLAW_OPENAI_KEY=sk-...
|
|
165
|
+
CAREERCLAW_LLM_CHAIN=anthropic/claude-haiku-4-5-20251001,openai/gpt-4o-mini
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Estimated cost per run: ~$0.003 at claude-haiku-4-5-20251001 pricing (3 drafts).
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## All CLI Options
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
careerclaw-js [OPTIONS]
|
|
176
|
+
|
|
177
|
+
Options:
|
|
178
|
+
-p, --profile PATH Path to profile.json
|
|
179
|
+
(default: .careerclaw/profile.json)
|
|
180
|
+
--resume-txt PATH Plain-text resume for enhanced matching
|
|
181
|
+
(default: .careerclaw/resume.txt if present)
|
|
182
|
+
-k, --top-k INT Number of top matches to return (default: 3)
|
|
183
|
+
-d, --dry-run Run without writing tracking or run log
|
|
184
|
+
-j, --json Machine-readable JSON output (no colour, no headers)
|
|
185
|
+
-h, --help Show this help message
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Application Tracking
|
|
191
|
+
|
|
192
|
+
Tracking is written automatically on each non-dry-run. Status lifecycle:
|
|
193
|
+
|
|
194
|
+
`saved` → `applied` → `interviewing` → `offer` → `rejected`
|
|
195
|
+
|
|
196
|
+
Runtime files — all stored under `.careerclaw/`:
|
|
197
|
+
|
|
198
|
+
| File | Contents |
|
|
199
|
+
|---|---|
|
|
200
|
+
| `profile.json` | Career profile |
|
|
201
|
+
| `resume.txt` | Plain-text resume (optional) |
|
|
202
|
+
| `tracking.json` | Saved jobs keyed by stable `job_id` |
|
|
203
|
+
| `runs.jsonl` | Append-only run log (one line per run) |
|
|
204
|
+
| `.license_cache` | Pro license validation cache (SHA-256 hash only) |
|
|
205
|
+
|
|
206
|
+
> **File format compatibility:** careerclaw-js uses the same JSON formats as the Python
|
|
207
|
+
> `careerclaw` package. `profile.json`, `tracking.json`, and `runs.jsonl` are fully
|
|
208
|
+
> interchangeable between both implementations.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Environment Variables
|
|
213
|
+
|
|
214
|
+
| Variable | Description |
|
|
215
|
+
|---|---|
|
|
216
|
+
| `CAREERCLAW_PRO_KEY` | Pro license key (Gumroad) |
|
|
217
|
+
| `CAREERCLAW_GUMROAD_PRODUCT_ID` | Gumroad product ID for license validation |
|
|
218
|
+
| `CAREERCLAW_ANTHROPIC_KEY` | Anthropic API key for LLM draft enhancement |
|
|
219
|
+
| `CAREERCLAW_OPENAI_KEY` | OpenAI API key for LLM draft enhancement |
|
|
220
|
+
| `CAREERCLAW_LLM_KEY` | Legacy single-provider key fallback |
|
|
221
|
+
| `CAREERCLAW_LLM_CHAIN` | Ordered failover chain, e.g. `anthropic/claude-haiku-4-5-20251001,openai/gpt-4o-mini` |
|
|
222
|
+
| `CAREERCLAW_LLM_MODEL` | Override default LLM model |
|
|
223
|
+
| `CAREERCLAW_LLM_PROVIDER` | `anthropic` or `openai` (inferred from key when not set) |
|
|
224
|
+
| `CAREERCLAW_DIR` | Override runtime directory (default: `.careerclaw`) |
|
|
225
|
+
| `HN_WHO_IS_HIRING_ID` | Override HN thread ID (updated monthly) |
|
|
226
|
+
|
|
227
|
+
Copy `.env.example` to `.env` and fill in your values.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Roadmap
|
|
232
|
+
|
|
233
|
+
| Phase | Scope | Status |
|
|
234
|
+
|---|---|---|
|
|
235
|
+
| 1 | Models + config | ✅ v0.1.0 |
|
|
236
|
+
| 2 | RemoteOK + HN adapters | ✅ v0.2.0 |
|
|
237
|
+
| 3 | Source aggregation + text processing | ✅ v0.3.0 |
|
|
238
|
+
| 4 | Matching engine + scoring | ✅ v0.4.0 |
|
|
239
|
+
| 5 | Requirements + resume intelligence + gap analysis | ✅ v0.5.0 |
|
|
240
|
+
| 6 | Deterministic drafting | ✅ v0.6.0 |
|
|
241
|
+
| 7 | Tracking + run log | ✅ v0.7.0 |
|
|
242
|
+
| 8–9 | Briefing pipeline + CLI + npm publish | ✅ v0.8.0–v0.8.1 |
|
|
243
|
+
| 10 | LLM draft enhancement (Pro) | ✅ v0.10.0 |
|
|
244
|
+
| 11 | Gumroad license validation + offline cache | ✅ v0.11.0 |
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Development
|
|
250
|
+
|
|
251
|
+
### Prerequisites
|
|
252
|
+
|
|
253
|
+
- Node.js ≥ 20
|
|
254
|
+
- npm ≥ 10
|
|
255
|
+
|
|
256
|
+
### Setup
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
git clone https://github.com/orestes-garcia-martinez/careerclaw-js
|
|
260
|
+
cd careerclaw-js
|
|
261
|
+
npm install
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Running tests
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
# All tests (offline, no network)
|
|
268
|
+
npm test
|
|
269
|
+
|
|
270
|
+
# Watch mode
|
|
271
|
+
npm run test:watch
|
|
272
|
+
|
|
273
|
+
# Type-check only
|
|
274
|
+
npm run lint
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Smoke tests (live network — run before release)
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
npm run smoke:sources # RemoteOK + HN connectivity
|
|
281
|
+
npm run smoke:briefing # Full pipeline end-to-end
|
|
282
|
+
npm run smoke:llm # LLM keys + Pro license validation
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Project structure
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
careerclaw-js/
|
|
289
|
+
├── src/
|
|
290
|
+
│ ├── adapters/ # RemoteOK RSS + HN Firebase adapters
|
|
291
|
+
│ ├── core/ # Shared text processing
|
|
292
|
+
│ ├── matching/ # Scoring engine
|
|
293
|
+
│ ├── tests/ # Vitest test suite (270 tests, fully offline)
|
|
294
|
+
│ ├── briefing.ts # Pipeline orchestrator
|
|
295
|
+
│ ├── cli.ts # CLI entry point
|
|
296
|
+
│ ├── config.ts # Environment and source configuration
|
|
297
|
+
│ ├── drafting.ts # Deterministic draft templates (Free tier)
|
|
298
|
+
│ ├── gap.ts # Gap analysis engine
|
|
299
|
+
│ ├── license.ts # Pro license validation (Gumroad)
|
|
300
|
+
│ ├── llm-enhance.ts # LLM draft enhancement (Pro)
|
|
301
|
+
│ ├── models.ts # Canonical data schemas
|
|
302
|
+
│ ├── requirements.ts # Job requirements extraction
|
|
303
|
+
│ ├── resume-intel.ts # Resume intelligence
|
|
304
|
+
│ ├── sources.ts # Source aggregation
|
|
305
|
+
│ └── tracking.ts # Tracking repository
|
|
306
|
+
├── scripts/ # Smoke + debug scripts (not published)
|
|
307
|
+
├── SKILL.md # OpenClaw skill definition
|
|
308
|
+
├── CHANGELOG.md
|
|
309
|
+
├── SECURITY.md
|
|
310
|
+
├── package.json
|
|
311
|
+
└── tsconfig.json
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Security & Privacy
|
|
317
|
+
|
|
318
|
+
careerclaw-js is built on a local-first architecture.
|
|
319
|
+
|
|
320
|
+
- **No backend.** No telemetry. No analytics endpoint.
|
|
321
|
+
- **API keys never stored.** Keys are read from the environment at runtime only.
|
|
322
|
+
- **License cache is hash-only.** Only SHA-256 of the license key is written to disk.
|
|
323
|
+
- **LLM privacy.** Only extracted keyword signals sent to the LLM — never raw resume text.
|
|
324
|
+
- **External calls:** `remoteok.com`, `hacker-news.firebaseio.com`, `api.gumroad.com`,
|
|
325
|
+
and your configured LLM provider (using your own key).
|
|
326
|
+
|
|
327
|
+
See [SECURITY.md](SECURITY.md) for the vulnerability disclosure policy.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Changelog
|
|
332
|
+
|
|
333
|
+
See [CHANGELOG.md](CHANGELOG.md) for the full version history.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## License
|
|
338
|
+
|
|
339
|
+
MIT — see [LICENSE](LICENSE)
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## Support
|
|
344
|
+
|
|
345
|
+
- **GitHub Issues:** bug reports and feature requests
|
|
346
|
+
- **Response SLA:** critical bugs < 48h · general questions < 72h
|
|
347
|
+
- **Security disclosures:** see [SECURITY.md](SECURITY.md)
|
|
348
|
+
- **Pro support:** orestes.garcia.martinez@gmail.com
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a Vulnerability
|
|
4
|
+
|
|
5
|
+
If you discover a security vulnerability in CareerClaw, please report it
|
|
6
|
+
responsibly. **Do not open a public GitHub issue** for security matters.
|
|
7
|
+
|
|
8
|
+
**Contact:** orestes.garcia.martinez@gmail.com
|
|
9
|
+
**Subject line:** `[SECURITY] CareerClaw JS — <brief description>`
|
|
10
|
+
|
|
11
|
+
Include as much detail as you can:
|
|
12
|
+
- Description of the vulnerability
|
|
13
|
+
- Steps to reproduce
|
|
14
|
+
- Potential impact
|
|
15
|
+
- Affected version(s)
|
|
16
|
+
|
|
17
|
+
### Response SLA
|
|
18
|
+
|
|
19
|
+
| Severity | First response | Resolution target | Release vehicle |
|
|
20
|
+
|-----------------------------------------------------------|----------------|------------------------|------------------------|
|
|
21
|
+
| Critical (data exposure, key leakage) | < 24 hours | < 72 hours | Immediate patch |
|
|
22
|
+
| High (pipeline hijack, file write outside `.careerclaw/`) | < 48 hours | < 1 week | Patch release |
|
|
23
|
+
| Medium / Low | < 1 week | Next scheduled release | Patch or minor release |
|
|
24
|
+
|
|
25
|
+
You will receive an acknowledgement within the first response window. If
|
|
26
|
+
you do not hear back within 48 hours, follow up directly.
|
|
27
|
+
|
|
28
|
+
We do not currently offer a bug bounty program, but we will credit
|
|
29
|
+
responsible disclosures in the CHANGELOG unless you prefer to remain
|
|
30
|
+
anonymous.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Security Architecture
|
|
35
|
+
|
|
36
|
+
CareerClaw is designed with a local-first, minimal-footprint security
|
|
37
|
+
model. The threat surface is intentionally small.
|
|
38
|
+
|
|
39
|
+
### What runs locally
|
|
40
|
+
|
|
41
|
+
Everything. CareerClaw has no backend server, no cloud endpoint, and
|
|
42
|
+
no telemetry pipeline. All computation — fetching, ranking, drafting,
|
|
43
|
+
and persistence — runs on the user's machine.
|
|
44
|
+
|
|
45
|
+
### External network calls
|
|
46
|
+
|
|
47
|
+
CareerClaw makes exactly two categories of outbound network requests:
|
|
48
|
+
|
|
49
|
+
| Destination | Protocol | Auth | Purpose |
|
|
50
|
+
|------------------------------------------------|----------|--------------------|----------------------------|
|
|
51
|
+
| `remoteok.com/remote-jobs.rss` | HTTPS | None | Job ingestion |
|
|
52
|
+
| `hacker-news.firebaseio.com/v0/item/{id}.json` | HTTPS | None | Job ingestion |
|
|
53
|
+
| User's configured LLM provider (optional) | HTTPS | User's own API key | Pro draft enhancement only |
|
|
54
|
+
| `api.polar.sh` (optional) | HTTPS | License key hash | Pro license validation only |
|
|
55
|
+
|
|
56
|
+
No other network calls are made. No analytics endpoints. No version-check
|
|
57
|
+
beacons. No callback URLs.
|
|
58
|
+
|
|
59
|
+
### Credential handling
|
|
60
|
+
|
|
61
|
+
CareerClaw touches four credential types. None are ever written to disk raw.
|
|
62
|
+
|
|
63
|
+
| Credential | Source | Stored on disk? | Logged? |
|
|
64
|
+
|-------------------------------|-------------|------------------------------|---------|
|
|
65
|
+
| `CAREERCLAW_PRO_KEY` | Env var | SHA-256 hash only | Never |
|
|
66
|
+
| `CAREERCLAW_ANTHROPIC_KEY` | Env var | Never | Never |
|
|
67
|
+
| `CAREERCLAW_OPENAI_KEY` | Env var | Never | Never |
|
|
68
|
+
| `CAREERCLAW_LLM_KEY` (legacy) | Env var | Never | Never |
|
|
69
|
+
|
|
70
|
+
Additional guarantees:
|
|
71
|
+
- Keys are never written to `tracking.json`, `runs.jsonl`, or any structured output
|
|
72
|
+
- Keys are never passed as CLI arguments (always environment variables)
|
|
73
|
+
- Exception messages are sanitised before propagation — keys are stripped
|
|
74
|
+
- `src/tests/config.test.ts` contains a dedicated test asserting that no key
|
|
75
|
+
value appears in any structured output field
|
|
76
|
+
|
|
77
|
+
### License cache
|
|
78
|
+
|
|
79
|
+
When `CAREERCLAW_PRO_KEY` is first validated, only a SHA-256 hash of the key
|
|
80
|
+
is written to `.careerclaw/.license_cache`. The raw key is never stored.
|
|
81
|
+
Subsequent runs compare against the cached hash to avoid repeated network
|
|
82
|
+
validation calls.
|
|
83
|
+
|
|
84
|
+
### Local data
|
|
85
|
+
|
|
86
|
+
All runtime state is stored under `.careerclaw/` in the user's home directory.
|
|
87
|
+
This folder is gitignored by default.
|
|
88
|
+
|
|
89
|
+
| File | Contents | Sensitive? |
|
|
90
|
+
|-----------------------|----------------------------------------------|---------------------|
|
|
91
|
+
| `profile.json` | Skills, roles, experience, salary range | Yes — do not commit |
|
|
92
|
+
| `resume.txt` | Full resume text | Yes — do not commit |
|
|
93
|
+
| `resume.pdf` | Full resume (PDF) | Yes — do not commit |
|
|
94
|
+
| `tracking.json` | Job IDs and application statuses | Moderate |
|
|
95
|
+
| `runs.jsonl` | Anonymous run metrics (job counts, duration) | No |
|
|
96
|
+
| `.license_cache` | SHA-256 hash of Pro key only | No |
|
|
97
|
+
|
|
98
|
+
**Never commit `.careerclaw/` to version control.** The `.gitignore`
|
|
99
|
+
entry is present by default — verify it before pushing.
|
|
100
|
+
|
|
101
|
+
### Source code transparency
|
|
102
|
+
|
|
103
|
+
- No obfuscated code
|
|
104
|
+
- No Base64-encoded URLs or network targets
|
|
105
|
+
- No minified scripts in the repository
|
|
106
|
+
- No `postinstall` hooks that execute network calls
|
|
107
|
+
- All dependencies declared explicitly in `package.json`
|
|
108
|
+
|
|
109
|
+
Every release is scanned with VirusTotal before publishing to ClawHub.
|
|
110
|
+
|
|
111
|
+
### Permissions
|
|
112
|
+
|
|
113
|
+
CareerClaw requests only the permissions it actually uses:
|
|
114
|
+
|
|
115
|
+
| Permission | Used for |
|
|
116
|
+
|--------------|-----------------------------------------------|
|
|
117
|
+
| `read` | `profile.json`, `tracking.json`, resume files |
|
|
118
|
+
| `write` | `tracking.json`, `runs.jsonl` |
|
|
119
|
+
| `exec` | Running the Node.js pipeline |
|
|
120
|
+
| `web_search` | Fetching RemoteOK RSS and HN Firebase API |
|
|
121
|
+
|
|
122
|
+
No `notification`, `cron`, or elevated permissions are requested in
|
|
123
|
+
the free tier.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Known Limitations
|
|
128
|
+
|
|
129
|
+
**HN thread ID is manually maintained.** The Hacker News "Who is Hiring?"
|
|
130
|
+
thread ID in `src/config.ts` must be updated monthly. An outdated ID will
|
|
131
|
+
result in stale or missing results — not a security issue, but worth noting
|
|
132
|
+
for transparency.
|
|
133
|
+
|
|
134
|
+
**Resume text is stored in plaintext.** `.careerclaw/resume.txt` is
|
|
135
|
+
unencrypted. Users in shared environments should ensure appropriate
|
|
136
|
+
filesystem permissions on the `.careerclaw/` directory.
|
|
137
|
+
|
|
138
|
+
**LLM provider data handling.** When an LLM key is set and Pro is active,
|
|
139
|
+
job description excerpts and resume signal keywords are sent to the configured
|
|
140
|
+
provider. CareerClaw never sends the full resume text to any LLM — only the
|
|
141
|
+
extracted keyword signals from `ResumeIntelligence`. Review your provider's
|
|
142
|
+
data retention policy if this is a concern:
|
|
143
|
+
- Anthropic: https://www.anthropic.com/legal/privacy
|
|
144
|
+
- OpenAI: https://openai.com/policies/privacy-policy
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Supported Versions
|
|
149
|
+
|
|
150
|
+
Security fixes are applied to the latest release only. We do not backport
|
|
151
|
+
fixes to older versions.
|
|
152
|
+
|
|
153
|
+
| Version | Supported |
|
|
154
|
+
|----------------------|-----------|
|
|
155
|
+
| Latest (main branch) | ✅ |
|
|
156
|
+
| Older releases | ❌ |
|