skills/linkedin-voyager/SKILL.md
Read LinkedIn profile data (bio, headline, experience, education, skills, contacts) via the unofficial Voyager API. Uses your browser session cookies — NO password. Sibling to the official-API `linkedin` skill. Use when user wants to see or export their own (or a public) profile content not available in the official API.
npx skillsauth add RonanCodes/ronan-skills linkedin-voyagerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Read-side sibling to ro:linkedin. Hits LinkedIn's internal Voyager API (same API the linkedin.com web app uses) via the linkedin-api Python library (tomquirk). Gives access to profile sections the official OAuth API doesn't expose: About, Headline, Experience, Education, Skills, Certifications, Contact info, Connections, etc.
This skill uses an undocumented internal API and authenticates with your session cookies. Per LinkedIn's User Agreement §8.2, automated access that is not through their public API is prohibited. Aggressive or high-volume usage has resulted in account restrictions or bans. Use sparingly:
/ro:linkedin (official API) for anything it covers./ro:linkedin (official API) when possible./ro:linkedin-voyager profile ronanconnolly # your own profile (bio/headline/experience/skills)
/ro:linkedin-voyager profile satyanadella # any public profile slug
/ro:linkedin-voyager contact ronanconnolly # email/phone/twitter if the viewer can see them
/ro:linkedin-voyager search "staff engineer" # people search (limited)
/ro:linkedin-voyager connections # the viewer's own 1st-degree connections
On every run, scripts/voyager.py extracts li_at + JSESSIONID from the browser set by ROBROWSER in ~/.config/ro/defaults.env (or --browser <name>), using browser_cookie3. No password is ever prompted or stored. Cookies stay in memory.
If the library rejects the cookies (LinkedIn sometimes requires challenges), log into linkedin.com once in the browser and retry.
Profile output (default — compact human-readable):
# <Full Name> — <Headline>
<location> · <industry>
linkedin.com/in/<slug>
## About
<bio text>
## Experience
- <Title> @ <Company> (<start> – <end or Present>) <location>
<description if any>
- ...
## Education
- <School> — <Degree> <Field> (<years>)
## Skills
skill1, skill2, skill3, ...
Add --json for raw Voyager JSON (huge — useful for wiki ingest or diffs).
| Arg | Function |
|-----|----------|
| profile <slug> | get_profile(public_id=slug) + pretty-printer |
| contact <slug> | get_profile_contact_info(public_id=slug) |
| search <terms> | search_people(keywords=terms, limit=10) |
| connections | get_profile_connections(<viewer>) |
uv run --with 'linkedin-api>=2.3' --with browser-cookie3 python3 \
/path/to/skills/linkedin-voyager/scripts/voyager.py <cmd> <args...>
uv provisions the deps on first run; subsequent runs are fast.
profileFullProfile-138 which returns the top card only: name, headline, summary (About/bio), location, profile picture./identity/dash/profilePositions?viewee=<urn>&...). Not yet wired. Add as a second call chained after the top card if the caller wants the full profile.get_profile() hits /identity/profiles/<slug>/profileView which returns 410 Gone as of 2026-Q1. Don't use it — this skill's cmd_profile calls the dash endpoint directly.linkedin-api is usually patched within weeks. uv auto-picks the latest compatible version per run.Set-Cookie: li_at=delete me + infinite 302 loops to the same URL, LinkedIn has invalidated the session server-side. Log back into the browser and wait ~30 min before retrying..www.linkedin.com and quoted JSESSIONID values like "ajax:...". requests' cookiejar won't send .www.linkedin.com-scoped cookies to host www.linkedin.com, and the quoted JSESSIONID won't match the csrf-token header (which is set unquoted). Both caused 403 "CSRF check failed" until get_cookies() rebuilt the jar with .linkedin.com domain + stripped JSESSIONID quotes./ro:linkedin — official OAuth API: posts + draft-mode profile edits. Start there./ro:linkedin-scan — light scraping of the public-facing HTML (even safer, less structured)./ro:browser-cookies — the underlying cookie path this skill uses.testing
--- name: linear-pipeline description: The Fable orchestrator for a single dispatched Linear ticket. Holds almost no context itself; it receives `--issue <ID> --detached`, decides the stage sequence, and fans out a sub-agent per stage, passing forward only each stage's artifact (never re-derived, never inlined into its own context). Step zero, before any planning or stage routing, is a boundary triage against `canon/security-boundary.md` (#199): a match tags Ronan Connolly and stops the run, no
development
--- name: in-your-face description: Capture a chat-only answer into a durable artifact (markdown + HTML, PDF when cheap) and launch it automatically so the user cannot miss it. Use when user says "in your face", "don't let me lose this", "save that answer", "make that durable", or right after answering a substantive side question (a recipe, comparison, how-to, or generated prompt) that would otherwise die with the context. category: workflow argument-hint: [--no-open] [--vault <short>] [hint of
tools
One-shot headless OpenAI Codex CLI calls for background/admin AI tasks — summaries, classification, extraction, admin glue. The default engine for anything that runs AI constantly in the background (daemon-driven, per-event), because it bills the flat ChatGPT subscription instead of Claude usage or per-token API spend, and it keeps working while Claude is rate-limited. NEVER for coding — coding stays Claude. Use when a skill or daemon needs a cheap always-on AI call, when the user says "use codex", "ask codex", "codex as backup", or when building a background summarizer/classifier into a listener or loop. Reads auth from ~/.codex/auth.json (ChatGPT account, no API key).
research
Turn a warranty rejection, repair quote, or RMA email into a cited decision brief — legal read (NL/EU consumer law), is the part user-serviceable, live part and new-unit prices, repair-vs-DIY-vs-new economics, before-you-send-it checklist, deadlines. Use when the user pastes or screenshots a repair quote, warranty rejection, "not covered" email, onderzoekskosten fee, or asks "should I repair or replace this".