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

@zenalexa/unicli

v0.208.0

Published

The universal interface between AI agents and the world's software

Readme


Agents cannot draw in SolidWorks. Cannot design PCBs. Cannot run CFD simulations. Cannot send Outlook emails. Cannot access most websites.

Uni-CLI fixes this. One command, structured JSON output, self-repairing YAML adapters. ~80 tokens per invocation — two orders of magnitude cheaper than MCP.

npm install -g @zenalexa/unicli
unicli hackernews top --limit 5          # Public API
unicli bilibili hot                      # Chinese platform
unicli twitter search "AI agents"        # Authenticated
unicli blender render scene.blend        # Desktop software
unicli cursor ask "explain this code"    # Electron app

Compared to

Source-level honest comparison. Numbers are from a 2026-04-07 audit of cloned reference repos under ref/. Full breakdown in docs/COMPARE.md.

| Project | Shape | Best when | Where Uni-CLI fits | | ----------------------------- | ---------------------------------- | ----------------------------------- | ---------------------------------------------------- | | opencli (14K) | TypeScript adapter hub | The genome — Uni-CLI extends it | Uni-CLI = 35 pipeline steps vs 15, +eval, +repair | | CLI-Anything (29K, HKUDS) | Python adapter hub + skill gen | Desktop-app coverage (44 harnesses) | Uni-CLI = 134 sites web breadth, single-binary | | browser-use (86K) | Python library, LLM per step | Open-ended browser tasks | Different shape — embed vs invoke | | goose (38K, MCP-first) | MCP-host runtime | MCP-only environments | unicli mcp serve mounts as MCP server | | hermes-agent (30K) | Agent w/ memory + multi-platform | Long-running personal agent | Different category — hermes is agent, Uni-CLI = tool | | Stagehand | Browser-only observe/act/extract | Vision-grounded web tasks | Uni-CLI v0.208 ships unicli operate observe |

Why CLI

| Criterion | MCP | CLI (Uni-CLI) | | ------------------- | --------------------------------------- | ---------------------------------------- | | Cost per invocation | 550–1,400 tokens (tool definition) | ~80 tokens | | Context overhead | 3 servers = 72% of 200K window consumed | Zero | | Composability | Single-tool calls | Unix pipes, jq, shell scripts | | Self-repair | Agents cannot read server source | Agent reads 20-line YAML, edits, retries | | Universality | Requires MCP client support | Every agent has Bash | | Auth reuse | Per-server configuration | Chrome login sessions via daemon |

CLI is: universal, composable, self-repairable, and context-efficient. MCP is a protocol for tool registration. They solve different problems. Uni-CLI supports both — use unicli mcp for MCP-only environments.

Architecture

                         unicli <site> <command> [args]
                                    │
                    ┌───────────────┼───────────────┐
                    ▼               ▼               ▼
              YAML Adapter    TS Adapter      Bridge (passthrough)
              (20 lines)      (complex logic)   (gh, docker, vercel)
                    │               │               │
                    ▼               ▼               ▼
              ┌─────────────────────────────────────────┐
              │          Pipeline Engine (30 steps)      │
              │  fetch · navigate · evaluate · click     │
              │  type · press · scroll · wait · tap      │
              │  intercept · snapshot · download          │
              │  websocket · exec · write_temp · ...      │
              └─────────┬───────────────┬───────────────┘
                        │               │
              ┌─────────▼─────┐ ┌───────▼───────┐
              │  Direct CDP   │ │    Daemon      │
              │  (fast, local)│ │  (persistent,  │
              │               │ │  reuses Chrome │
              │               │ │  login state)  │
              └───────────────┘ └───────────────┘
                        │               │
              ┌─────────▼───────────────▼───────┐
              │       Output Formatter           │
              │  table · json · yaml · csv · md  │
              │  (auto-JSON when piped)          │
              └─────────────────────────────────┘

Self-Repair

This is the core differentiator. When a command fails:

unicli <site> <cmd> fails
  → structured error JSON: { adapter_path, step, action, suggestion }
  → agent reads the 20-line YAML at that path
  → agent edits the YAML (selector changed, API versioned, auth rotated)
  → agent retries → fixed
  → fix persists in ~/.unicli/adapters/ (survives npm update)

Verification: unicli repair <site> <command> diagnoses, unicli test [site] validates.

Coverage

Web Platforms (67 sites)

| Category | Sites | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | Tech / Dev | hackernews, stackoverflow, devto, lobsters, producthunt, hf, github-trending, substack, lesswrong | | Social — International | twitter (25 cmds), reddit (16), instagram (19), tiktok (15), facebook (10), bluesky, medium | | Social — Chinese | bilibili (13), weibo, zhihu, xiaohongshu (13), douyin (13), jike, douban, weread, tieba, v2ex, linux-do, zsxq, xiaoyuzhou | | Video / Media | youtube (5), bilibili, douyin, tiktok | | Finance | xueqiu, sinafinance, barchart, yahoo-finance | | News | bbc, bloomberg (10), reuters, 36kr, google news | | Shopping | amazon (8), xianyu, coupang, smzdm, jd | | Jobs | boss (14), linkedin | | AI Platforms | gemini (5), grok, doubao-web (9), notebooklm (15), yollomi (12), jimeng, yuanbao | | Education | chaoxing, arxiv, wikipedia | | Other | ones (11), band, xiaoe, pixiv (6), hupu (7), ctrip, sinablog, steam, lobsters |

Desktop Software (28 apps)

| Category | Apps | | ---------------- | ----------------------------------------------------------- | | 3D / CAD | blender (13 cmds), freecad (15), cloudcompare (4), openscad | | Image | gimp (12), inkscape, imagemagick (6), krita (4) | | Video | ffmpeg (11), kdenlive (3), shotcut (3), musescore (5) | | Diagram | drawio, mermaid | | Document | libreoffice, pandoc | | Audio | audacity (8) | | Streaming | obs (8, WebSocket) | | Productivity | zotero (8) | | Dev Services | wiremock (5), adguardhome (5), novita (3) | | Game | slay-the-spire-ii (6, HTTP bridge mod) | | Design | sketch (3) |

Electron Apps (8 apps, 66 commands)

| App | Commands | Method | | --------------- | ---------------------------------------------------------------------------------------------- | --------- | | Cursor | ask, send, read, model, composer, extract-code, new, status, screenshot, dump, history, export | CDP :9226 | | Codex | ask, send, read, model, extract-diff, new, status, screenshot, dump, history, export | CDP :9222 | | ChatGPT | ask, send, read, model, new, status, screenshot, dump | CDP :9236 | | Notion | search, read, write, new, status, sidebar, favorites, export, screenshot | CDP :9230 | | Discord | servers, channels, read, send, search, members, status | CDP :9232 | | ChatWise | ask, send, read, model, new, status, screenshot, dump | CDP :9228 | | Doubao | ask, send, read, new, status, screenshot, dump | CDP :9225 | | Antigravity | ask, send, read, model, new, status, screenshot, dump | CDP :9234 |

Bridge (passthrough to existing CLIs)

docker, gh, jq, yt-dlp, vercel, supabase, wrangler, lark, dingtalk, hf, claude-code, codex-cli, opencode, aws, gcloud, az, doctl, netlify, railway, flyctl, pscale, neonctl, slack

Pipeline Engine

30 steps execute in sequence. Each YAML adapter is a pipeline of these steps.

| Step | Type | What it does | | ------------ | --------- | ----------------------------------------------------------------------------- | | fetch | API | HTTP JSON with retry, backoff, cookie injection, concurrent fan-out (limit=5) | | fetch_text | API | HTTP raw text (RSS, HTML, XML) | | parse_rss | API | RSS 2.0 + Atom feed parser | | html_to_md | API | HTML → Markdown via Turndown | | select | Transform | Navigate JSON by dot-path (data.items[]) | | map | Transform | Transform each item via ${{ }} templates | | filter | Transform | Keep items matching expression | | sort | Transform | Sort by field (numeric-aware) | | limit | Transform | Cap result count | | exec | Desktop | Run subprocess with stdin, env, file output | | write_temp | Desktop | Create ephemeral script file | | navigate | Browser | Navigate Chrome to URL via CDP | | evaluate | Browser | Execute JS in page context | | click | Browser | Click element by CSS selector | | type | Browser | Type text into input | | press | Browser | Keyboard key with modifiers (Ctrl+A, Enter) | | wait | Browser | Wait for time, selector, or text | | scroll | Browser | Direction scroll, auto-scroll to bottom | | intercept | Browser | Capture fetch + XHR responses (dual-patched, stealthed) | | snapshot | Browser | DOM accessibility tree with interactive refs | | tap | Browser | Vue Store Action Bridge (Pinia/Vuex → capture network) | | download | Media | HTTP + yt-dlp, batch concurrent, skip_existing | | websocket | Service | WebSocket connect/send/receive (OBS auth support) | | set | Control | Store variables into vars context for templates | | if | Control | Conditional execution of sub-pipeline branches | | append | Control | Push ctx.data into vars array for accumulation | | each | Control | Loop sub-pipeline with do-while + max iteration limit | | parallel | Control | Run sub-pipelines concurrently with merge strategies | | rate_limit | Control | Per-domain token bucket request throttling |

Template Expressions

29 pipe filters: join, urlencode, urldecode, slice, replace, lowercase, uppercase, trim, default, split, first, last, length, strip_html, truncate, slugify, sanitize, ext, basename, keys, json, abs, round, ceil, floor, int, float, str, reverse, unique

${{ item.title | truncate(50) }}
${{ item.tags | join(', ') }}
${{ args.query | urlencode }}
${{ item.url | basename | sanitize }}
${{ item.score > 100 ? 'hot' : 'normal' }}

VM sandbox with null-prototype isolation, 50ms timeout, forbidden pattern blocklist.

Authentication Strategies

| Strategy | Auth | How | | ----------- | ------------- | -------------------------------------------------------- | | public | None | Direct HTTP fetch | | cookie | Cookie file | ~/.unicli/cookies/<site>.json injected into headers | | header | Cookie + CSRF | Cookie + auto-extracted CSRF token (ct0, bili_jct, etc.) | | intercept | Browser | Navigate page, capture XHR/fetch responses | | ui | Browser | Direct DOM interaction (click, type, submit) |

Strategy cascade: auto-probes PUBLIC → COOKIE → HEADER on first run.

Browser Daemon

Persistent background process that bridges CLI commands to Chrome tabs. Reuses existing Chrome login sessions — no cookie files, no extension install required for basic operation.

unicli daemon status              # Check daemon state
unicli daemon stop                # Graceful shutdown (auto-exits after 4h idle)

unicli operate open <url>         # Navigate browser
unicli operate state              # DOM snapshot (accessibility tree)
unicli operate click <ref>        # Click by ref from snapshot
unicli operate type <ref> <text>  # Type into element
unicli operate eval <js>          # Execute JavaScript
unicli operate screenshot [path]  # Capture page
unicli operate network            # View captured requests

unicli record <url>               # Auto-generate adapter from page traffic

Plugin System

unicli plugin install github:user/repo     # From GitHub
unicli plugin install /local/path          # From local directory
unicli plugin list                         # Show installed
unicli plugin update                       # Update all

Plugins can register custom pipeline steps via registerStep() and lifecycle hooks:

import { onBeforeExecute, onAfterExecute } from "unicli/hooks";
onBeforeExecute(async (ctx) => {
  /* rate limiting, logging */
});
onAfterExecute(async (ctx, result) => {
  /* analytics, caching */
});

Shell Completion

unicli completion bash >> ~/.bashrc
unicli completion zsh >> ~/.zshrc
unicli completion fish > ~/.config/fish/completions/unicli.fish

Anti-Detection

13-layer stealth injection for browser automation:

  1. navigator.webdriver removal
  2. window.chrome.runtime mock
  3. Plugin array normalization
  4. Language header consistency
  5. Permissions API notification fix
  6. Function.prototype.toString spoofing
  7. CDP global cleanup (cdc_, __playwright, __puppeteer)
  8. Error.stack frame filtering
  9. outerWidth/outerHeight normalization
  10. Performance API entry filtering
  11. Document-level CDP marker cleanup
  12. iframe contentWindow.chrome consistency
  13. Reserved (debugger trap neutralization)

Exit Codes

Following sysexits.h:

| Code | Meaning | When | | ---- | ----------- | ----------------------------- | | 0 | Success | Command completed | | 1 | Error | Unexpected failure | | 2 | Usage | Bad arguments | | 66 | Empty | No data returned | | 69 | Unavailable | Browser/service not connected | | 75 | Temporary | Timeout — retry | | 77 | Auth | Not logged in | | 78 | Config | Missing credentials |

Development

git clone https://github.com/olo-dot-io/Uni-CLI.git && cd Uni-CLI
npm install
npm run dev -- list                   # Test adapter loading
npm run verify                        # format + typecheck + lint + test + build
npm run test:adapter                  # Validate all 601 YAML/TS adapters

| Command | Purpose | | ---------------------- | ----------------------- | | npm run dev | Development run | | npm run build | Production build | | npm run typecheck | TypeScript strict check | | npm run lint | Oxlint | | npm run test | Unit tests (753) | | npm run test:adapter | Adapter validation | | npm run verify | Full pipeline |

Technology

| Layer | Technology | | -------- | ---------------------------------------------------------- | | Language | TypeScript (strict) | | Runtime | Node.js ≥ 20 | | CLI | Commander | | Browser | Raw CDP via ws (WebSocket) — no Puppeteer, no Playwright | | Test | Vitest | | Lint | Oxlint | | Format | Prettier | | Template | VM sandbox (null-prototype, 50ms timeout) |

Zero production dependencies beyond: chalk, cli-table3, commander, js-yaml, turndown, undici, ws.

Contributing

See CONTRIBUTING.md. The fastest way to contribute: write a 20-line YAML adapter for a site you use.

License

Apache-2.0