npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ilml-plugin-linkedin

v1.11.7

Published

Reference ilml plugin: keep a local mirror of your LinkedIn data and run AI-assisted workflows under your direction.

Downloads

2,517

Readme

Your LinkedIn data — finally on your machine

LinkedIn keeps your connections, conversations, and the notes you write about people locked inside their interface. You can't export message threads. You can't query an AI on your own contact history. You can't run batch operations from a script. You can't keep a personal database of who said what when.

This plugin pulls all of that onto your machine — into local JSON files that you fully own — and feeds derived signals (action plans, run reports, AI assistant context) into your iLiveMyLife knowledge graph for AI-driven follow-up. Even if you uninstall the plugin or switch ilml accounts, your accumulated data stays where you put it.

Common LinkedIn workflows become scriptable: AI fills Easy Apply forms using context from your profile and notes, drafts message replies for your review before sending, and queues recruiter outreach under daily limits you configure.

Note on intent and use. This plugin demonstrates patterns for keeping a local mirror of your own LinkedIn data — syncing message history and connection metadata to JSON files on your machine — and for using AI to assist with form filling and message drafting on your behalf. It is published as a reference implementation for developers building plugins on top of the ilml SDK. Automated interaction with LinkedIn may conflict with their User Agreement — review it and run this at your own risk. Provided AS-IS; the author makes no warranty and accepts no liability for account actions, data loss, or other consequences resulting from use.


What you get

  • A full local mirror of your LinkedIn data. Connections, conversation threads, message history, profile metadata, your private notes about people — stored in local JSON files you fully own; derived signals (action plans, AI context, run reports) flow into your iLiveMyLife graph for follow-up. Nothing stays trapped in linkedin.com.
  • AI-assisted messaging — drafts go through you. Lifebot reads the full context of each thread (history, your notes, tags) and drafts replies in your voice. You review the batch in one pass and push approved drafts as a group. On push, the bot re-scans every thread first — if a new incoming message arrived since you reviewed, it pauses that draft and flags it for re-review instead of sending blind. Never autopilot.
  • An auto-triaged inbox. Every conversation gets classified (recruiter / hiring manager / founder / investor / spam / event), tagged, prioritized, and stamped with a suggested next action. ilml linkedin today prints a no-browser daily plan: who to reply to, what to do, in priority order — before you've even opened LinkedIn.
  • Inbox sync that doesn't break your workflow. By default sync-all pulls the conversation list and metadata without "opening" unread threads — LinkedIn keeps showing the unread badges until you read them in the UI. The sync report ends with a list of what's still unread so you can scan it from the terminal first. Use the bot as an analyst without losing your own attention markers. (Pass --read-unread if you want to vacuum unread threads into the local DB.)
  • Terminal-first workflows. Common tasks run as scripts you control — batched drafts you review before sending, queued applications under daily limits you set, scheduled runs that log everything. Repeatable and auditable.
  • Easy Apply that actually thinks. Auto-fills LinkedIn job applications, with Lifebot answering custom questions ("Why are you interested in this role?") in your voice using context from your graph — not boilerplate.
  • Your data outlives the plugin. The connection database, conversation history, and your notes live in a directory you choose (DATA_DIR). Plugin updates don't wipe them. Logging out of ilml doesn't wipe them. Uninstalling the plugin doesn't wipe them. Only you decide when they go.

Prerequisites

  • Node.js 18+download (the LTS version is fine).
  • iLiveMyLife account — free signup at iLiveMyLife.io.
  • LinkedIn account — your personal one.

That's it. There's nothing to clone or compile.

Install

One-time, on your machine:

# 1. Install the ilml CLI (skip if already installed)
npm install -g @ilivemylife/graph-sdk

# 2. Log in to your iLiveMyLife account
ilml login

# 3. Install this plugin
ilml plugin install linkedin

The bare-name linkedin resolves to npm:ilml-plugin-linkedin via the ilml plugin convention. The CLI downloads the latest version from npm, extracts it under ~/.ilivemylife/plugins/linkedin/, and runs npm install for runtime dependencies (mainly Puppeteer's bundled Chromium — first install takes a couple of minutes).

Verify:

ilml plugin list
ilml linkedin

Configure

The first time you run ilml linkedin <command>, the CLI will prompt for required fields. You can also pre-configure:

ilml plugin config linkedin set LINKEDIN_NAME "Your Full Name"
ilml plugin config linkedin set NODE_EASY_APPLY_MAIN <node-id>
ilml plugin config linkedin set NODE_EASY_APPLY_ERRORS <node-id>

Inspect (secrets masked):

ilml plugin config linkedin

Change later or wipe:

ilml plugin config linkedin set LINKEDIN_NAME "New Name"
ilml plugin config linkedin unset OPTIONAL_KEY
ilml plugin config linkedin reset                  # re-prompt on next run

Configuration fields

| Section | Field | Required | What it is | |---|---|---|---| | LinkedIn account | LINKEDIN_NAME | yes | Your full name exactly as it appears on LinkedIn (used to identify your own messages in threads). | | | LINKEDIN_LOGIN | no | LinkedIn email — only used for auto-fill during one-time browser login. | | | LINKEDIN_PASS | no, secret | LinkedIn password — auto-fill only. Stored locally on disk; never sent anywhere. | | iLiveMyLife integration | NODE_EASY_APPLY_MAIN | yes | Node ID where job applications are tracked. See "Setting up your graph" below. | | | NODE_EASY_APPLY_ERRORS | yes | Node ID where Easy Apply errors are logged. | | | NODE_RUN_REPORTS | no | Node ID where end-of-session summaries are posted (enable notifications on it to get pings when long jobs finish). | | Data storage | DATA_DIR | no | Absolute path to a directory for your local databases (connections, conversations, profile cache). Strongly recommended — keeps your accumulated data outside the plugin install folder so it survives plugin updates, ilml logout, and reinstalls. | | Apply bot | City | no | Default city for filters. Default: Toronto. | | | MAX_APPLY_FOR_RUN | no | Stop after this many applications per run. Default: 50. | | | LINKEDIN_SEARCH_URL | no | Default LinkedIn jobs search URL. Open LinkedIn → Jobs, set your filters, make sure Easy Apply is on, copy the resulting URL from the address bar. | | Scouting | LINKEDIN_SCOUT_URLS | no | Comma-separated job search URLs to scan without applying. | | Resume / CV | CV_TEXT, RESUME_PDF_URL, RESUME_FILENAME | no | CV snippet, public PDF URL, suggested filename. Used in messages to recruiters. | | Funnel | FUNNEL_USE_CUSTOM_MESSAGE | no | Send a custom note with connection requests. Default: false. | | | FUNNEL_MAX_CONNECTIONS | no | Cap connection requests per run. Default: 20. | | | FUNNEL_MESSAGE | no | Note text. Use {name} placeholder, e.g. Hi {name}, I just applied for a role at your company. | | | FUNNEL_EXCLUDE_LOCATIONS | no | Comma-separated locations to skip. |

Setting up your graph

The Easy Apply bot uses iLiveMyLife's AI assistant (Lifebot) to answer custom application questions in your voice. Two graph nodes are required: a main tracking node with Lifebot enabled, and an errors node for failed applications.

  1. Open https://app.ilivemylife.io and create a node titled "LinkedIn Easy Apply" (or any name).

  2. Open the node's settings (right panel) and turn on AI assistant. This enables Lifebot for this node — without it, the bot can't answer questions and ilml linkedin apply will refuse to run.

  3. Copy the node ID from the URL: https://app.ilivemylife.io/item/THIS-IS-THE-ID.

  4. Set it: ilml plugin config linkedin set NODE_EASY_APPLY_MAIN <id>.

  5. In the node's description, write your answer rules — Lifebot reads this when filling forms. Example:

    Application question rules:
    - My full name: Ivan Petrov
    - City: Toronto, Ontario, Canada
    - Phone: +1-416-xxx-xxxx
    - Email: [email protected]
    - Experience: Senior software engineer, 8 years
    - Visa status: Permanent Resident, Canada
    - Salary expectations: $120-150K CAD
    - Notice period: 14 days
    - Preferred work mode: hybrid or remote
  6. (Optional but useful) Create child nodes inside "LinkedIn Easy Apply" with topical detail: Resume, Tech stack, Interview availability, etc. Lifebot reads the whole subtree and uses everything as context.

  7. Create a sibling node titled "Easy Apply Errors" (no AI needed). Copy its ID and set it: ilml plugin config linkedin set NODE_EASY_APPLY_ERRORS <id>.

Save AI tokens — tune the node settings

Lifebot uses AI tokens for every form question it answers. Two settings on the Easy Apply node let you tune cost vs. quality without touching the plugin:

# Use a cheaper, faster AI model (good enough for filling forms):
ilml editSettings <NODE_EASY_APPLY_MAIN> --intelligence disabled

# Skip whole-graph context lookup — just use this node's description:
ilml editSettings <NODE_EASY_APPLY_MAIN> --rootAccess disabled

intelligence: disabled switches Lifebot to a cheaper model (think GPT-3.5 / Claude Haiku tier instead of GPT-4 / Claude Opus). For application form filling, the cheap model is usually fine — questions are mechanical.

rootAccess: disabled stops Lifebot from searching your entire knowledge graph for context every time it answers. The Easy Apply node's description and child nodes already have everything Lifebot needs — extra context costs tokens for no benefit.

To switch back: pass --intelligence enabled or --rootAccess enabled. To reset to your account default: pass null.

First-time LinkedIn login

LinkedIn requires an authenticated browser session, so a one-time login is needed:

ilml linkedin login

A real browser window opens. Sign in to LinkedIn (manually solve any captcha or 2FA). When you see your feed, close the window — your session cookies are saved locally for future runs.

Sessions live in your active ilml scope (<scope>/.ilivemylife/plugins-state/linkedin/cookies.json), so:

  • Different ilml scopes (e.g. ilml login globally vs ilml login --local in a project folder) keep separate LinkedIn sessions — useful if you have multiple LinkedIn accounts.
  • Plugin updates do not wipe your session — you don't need to re-login after ilml plugin update linkedin.
  • ilml logout does wipe the session in that scope (alongside other user-tied data) — clean handoff between users on a shared machine.

Daily commands

| Command | What it does | |---|---| | ilml linkedin apply | Auto-apply to LinkedIn Easy Apply jobs from LINKEDIN_SEARCH_URL. Stops after MAX_APPLY_FOR_RUN. | | ilml linkedin sync-all | Pull the LinkedIn inbox into the local DB and the graph. By default it preserves LinkedIn's unread badges (unread threads aren't opened) and lists what's still unread at the end of the report. Pass --read-unread to vacuum unread threads into the DB too (loses the badges). --full for a full re-scan, --report for stats only with no browser. | | ilml linkedin today | No-browser daily plan: who to reply to, what to do, in priority order. Reads already-synced data — doesn't open LinkedIn. | | ilml linkedin enrich | Re-classify every conversation (recruiter / hiring manager / founder / investor / spam / event) and rebuild priorities, summaries, and suggested actions. Offline, no browser. | | ilml linkedin report | Print the summary of the latest session. | | ilml linkedin scout | Scan jobs from LINKEDIN_SCOUT_URLS and score them — without applying. Builds a queue for apply-queue. | | ilml linkedin apply-queue | Apply to the top-scored jobs from the latest scout run. | | ilml linkedin messages | Batch messaging — draft, review, then push. Nothing sends without your approval. Common forms: messages --review-drafts (review pending drafts) and messages --push-drafts (push approved). | | ilml linkedin funnel | Run the recruiter / founder / investor connection-request queue. | | ilml linkedin visit | Visit recruiter / target profiles so they see you in "who viewed your profile". | | ilml linkedin viewers | Pull the "who viewed your profile" list. | | ilml linkedin warm-scan | Find 1st-degree connections at target companies (offline, no browser). Reads your already-synced people / conversations and groups them by company so you know who you can message directly versus where you need cold outreach. Override the company list via --companies="Anthropic,OpenAI" or pick a named group with --group=topPaying. | | ilml linkedin daily | Full pipeline in one command: sync-allapplyscoutfunnelvisitviewers → run report. | | ilml linkedin login | Re-save LinkedIn cookies after a session expires. |

Run ilml linkedin (no subcommand) any time to see the list.

Common routines

A few patterns that string the daily commands together. Outgoing messages always require your explicit approval (via messages --push-drafts); commands like apply and funnel do submit Easy Apply forms and connection requests on their own, scoped by MAX_APPLY_FOR_RUN and FUNNEL_MAX_CONNECTIONS.

Morning triage — see what needs attention before opening LinkedIn:

ilml linkedin sync-all   # pull new messages; unread threads stay bold and are listed at the end
ilml linkedin today      # print prioritized day plan

Active job search — apply, scout, network on autopilot; you stay in the loop on outgoing messages:

ilml linkedin daily                       # apply + scout + funnel + visit + viewers + report
ilml linkedin messages --review-drafts    # later: review the AI's drafted replies
ilml linkedin messages --push-drafts      # push the ones you approved

Passive pipeline — keep the inbox synced and triaged without touching outgoing channels:

ilml linkedin sync-all
ilml linkedin enrich
ilml linkedin today

Targeted networking — figure out which target companies you can reach via existing connections before sending any cold outreach:

ilml linkedin warm-scan                       # default group
ilml linkedin warm-scan --group=topPaying     # broader (FAANG + tier-1 + high-comp)
ilml linkedin warm-scan --companies="Anthropic,OpenAI"   # one-off override

Compose your own from the commands above — each one is a standalone script.

Updating

Updates ship via npm. The CLI checks the registry and only downloads when a newer version is actually available:

ilml plugin update linkedin    # check this plugin
ilml plugin update             # check all installed plugins
ilml update                    # update the SDK and all plugins together

You'll see one of:

  • linkedin: already on latest version (1.3.0) — nothing downloaded
  • linkedin: 1.3.0 → 1.3.1 then re-install — newer version pulled

Your config and your data both survive updates. Only the plugin code dir gets refreshed; everything user-tied lives elsewhere.

Schema migrations

Some updates change the on-disk format of your local data. The plugin runs needed migrations automatically the first time you invoke any command after an update — you don't have to do anything. Several safety nets are in place every time:

  1. Pre-migration integrity check. Before anything else, every .json file in DATA_DIR/collected-profiles/ and DATA_DIR/market-research/ is parsed as JSON. If any file is corrupted (truncated, hand-edited and broken, hit by disk failure, etc.) the migration aborts before touching anything — you get a list of which files are broken so you can repair them first. We don't back up corrupted state and we don't try to migrate it.
  2. Pre-migration backup. Once integrity is confirmed, every regular file in both data dirs is atomically copied to <filename>.pre-vNNN.backup (where NNN is the migration version about to run). Originals are left untouched.
  3. Atomic write + crash-safe. Migrations and backup copies use a .tmp file + rename, so a crash mid-write never leaves a half-written file. If a migration throws, the runner exits with an error pointing at the backups; your originals are intact.

Manual operations:

ilml linkedin migrate-status              # what schema version you're on, what's pending, what backups exist, what leftovers can be cleaned
ilml linkedin data-cleanup                # remove orphan .tmp files + pre-rollback snapshots (does NOT touch pre-migration backups)
ilml linkedin rollback-data               # preview what a DATA rollback would do (read-only)
ilml linkedin rollback-data --confirm     # actually roll back DATA — does NOT touch plugin code

DATA_DIR is kept tidy automatically — orphan .tmp files (leftovers from a crashed atomic write) are swept on every plugin start. Pre-migration backups (.pre-vNNN.backup) are kept indefinitely because rollback-data needs them; you can remove them manually if you're sure you'll never roll back. Pre-rollback snapshots (.pre-rollback-vNNN.backup) are kept as a "I changed my mind" safety net after a rollback and can be removed with data-cleanup once you're confident the rollback is good.

Full rollback procedure (two steps)

rollback-data deliberately separates DATA rollback from CODE rollback. To fully revert to a previous plugin version you must do BOTH, in this order:

# Step 1 — roll back data (only run on the new plugin version; older versions don't have this command)
ilml linkedin rollback-data --confirm

# Step 2 — IMMEDIATELY downgrade the plugin code, BEFORE running any other ilml linkedin command
ilml plugin install linkedin@<previous-version>

Between step 1 and step 2: do not run any ilml linkedin command. The current plugin will see the rolled-back data, detect a "missing" migration, and immediately re-apply it — silently undoing your rollback.

rollback-data is destructive — it overwrites your current files with the backup taken before the last migration. Any data added after that migration (new conversations synced, drafts written, notes added) will be lost. Rollback uses an all-or-nothing strategy: every backup file is JSON-validated upfront; if any one is corrupted, rollback aborts before touching any original (avoids "half restored, half new" inconsistency). Once validation passes, your current state is also snapshotted into <filename>.pre-rollback-vNNN.backup files as a safety net before the atomic restore.

Just want to inspect old data? Don't roll back. Copy your DATA_DIR somewhere else and run a separate DATA_DIR=/copy/path plugin instance against that copy — your live setup stays untouched.

Where things live

| Path | What's there | Wiped on plugin update? | Wiped on ilml logout? | |---|---|---|---| | ~/.ilivemylife/plugins/linkedin/ | Plugin code | yes (re-extracted) | no | | <scope>/.ilivemylife/plugins-state/linkedin.json | Your configured values (LINKEDIN_NAME, node IDs, etc.) | no | yes (with that scope) | | <scope>/.ilivemylife/plugins-state/linkedin/cookies.json | LinkedIn session cookies | no | yes (with that scope) | | Directory you set as DATA_DIR | Local DBs, synced profile metadata, message history, your notes | no | no |

If you didn't set DATA_DIR, runtime data files default to inside the plugin's install dir — meaning a plugin reinstall wipes them. Setting DATA_DIR to a sibling folder like ~/linkedin-plugin-data/ is strongly recommended:

ilml plugin config linkedin set DATA_DIR /absolute/path/to/your/linkedin-data

Once set, you can sync DATA_DIR to a backup drive, a cloud folder, or another machine — the data is plain SQLite-style JSON, fully portable.

Removing the plugin

ilml plugin remove linkedin

This wipes the install dir. Your config in the active scope:

ilml plugin config linkedin reset

The data in DATA_DIR is yours — delete the folder manually if you want it gone, or keep it.


Feedback & support

Bug reports, feature requests, and general questions land in the plugin's Support node inside iLiveMyLife. Send a message there and we'll get back to you:

  • In any iLiveMyLife app (web / mobile / desktop): open https://app.ilivemylife.io/item/0000019dde81b04f-2e534bb8ebad0000 and use the messenger panel
  • From the terminal: ilml send 0000019dde81b04f-2e534bb8ebad0000 "your message"

Links

  • This plugin on npm: https://www.npmjs.com/package/ilml-plugin-linkedin
  • ilml CLI on npm: https://www.npmjs.com/package/@ilivemylife/graph-sdk
  • iLiveMyLife: https://ilivemylife.io

Maintained by

DigitalTwins.team — independent consultancy that builds and maintains ilml plugins, automation tools, and bespoke integrations. This plugin is one of several reference implementations published as part of that work.

For commercial integrations, custom plugin development, or contract engineering inquiries → [email protected].

For bug reports or plugin questions, use the in-graph Support node linked above.