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

@kkodo/bettersync

v0.10.1

Published

Drop any chat export — WhatsApp, Telegram, Facebook Messenger, more — into your S16 Brain. Run any Brain agent locally with your own LLM (Groq, OpenAI, Ollama, etc.).

Readme

BetterSync

Drop any chat export — WhatsApp, Telegram, Facebook Messenger, more — into your S16 Brain. Then run any of your Brain's agents locally with your own free LLM key. Pluggable parsers, no LLM in the data path, no S16 wallet charges for AI.

$ npm install -g bettersync
$ bettersync init                              # one-time S16 token setup
$ bettersync auth llm --provider groq --key gsk_...   # any LLM you want
$ bettersync config defaultMode local           # or platform | auto

# Ingest any chat export
$ bettersync ingest ~/Downloads/facebook-export/
Parsed: 40 conversations, 2657 messages (0.1s)
✓ Ingested 2657/2657 in 38.2s

# Run any agent in your Brain — interactive picker if you don't pass args
$ bettersync run
? Pick an agent (type to filter):  Conversation Insight Extractor
? Where is the target page?  💬 Conversations
? Pick a page in "Conversations":  Aime Sien
▸ Conversation Insight Extractor  ·  local  ·  https://api.groq.com/openai/v1
status: success (1.59s)

What's new in v0.3.0

  • Interactive pickerbettersync run with no args opens a fuzzy-search menu of your agents and target pages. No more remembering names or typing UUIDs.
  • Shell completionsbettersync completions bash | zsh | fish prints a script to source for tab-complete on agent and database names. One-time install per shell.

Why

Two problems BetterSync solves:

  1. Bulk data ingest into S16 was awkward. Every chat platform has its own export format, and LLM-based ingest tools choke on bulk data because the LLM becomes the data conduit. BetterSync talks directly to your S16 workspace's MCP-over-HTTP endpoint with your API token — no model in the loop, just HTTP at network speed.

  2. Running S16 agents costs $$. S16's built-in s16.ai() goes through their gateway and charges your workspace wallet. BetterSync's local runner fetches an agent's compiled script via MCP, executes it on your machine in a Node sandbox, and intercepts every s16.ai() call to route it to any LLM you choose — Groq's free tier, a paid OpenAI/Anthropic key via OpenRouter, fully-local Ollama, your own self-hosted endpoint, anything that speaks the OpenAI Chat Completions protocol. Same agent, same script, same output — your AI bill, your rules.

Install

npm install -g bettersync
bettersync init

init walks you through getting an API token from your Brain (Settings → Development → API Tokens) and verifies the connection.

If you want to use the local agent runner, point it at any LLM you like:

# Free, fast — Groq's free tier
bettersync auth llm --provider groq --key gsk_...        # console.groq.com/keys

# Free, fully local
bettersync auth llm --provider ollama                    # ollama pull llama3.3 first
bettersync auth llm --provider lmstudio

# Bring your own paid keys
bettersync auth llm --provider openai     --key sk-...
bettersync auth llm --provider openrouter --key sk-or-v1-...
bettersync auth llm --provider together   --key tgp_v1_...
bettersync auth llm --provider fireworks  --key fw_...
bettersync auth llm --provider cerebras   --key csk-...
bettersync auth llm --provider deepinfra  --key ...

# Or any OpenAI-compatible endpoint at all
bettersync auth llm --base-url https://my-internal-llm/v1 --key xxx --model my-model

If you prefer not to install globally, use npx:

npx bettersync ingest ~/Downloads/whatsapp-export/

Supported chat formats

| ID | Source | |---|---| | facebook-messenger | Facebook DYI Messenger HTML export | | whatsapp | WhatsApp text export (iOS _chat.txt and Android WhatsApp Chat with X.txt) | | telegram | Telegram Desktop JSON export (single chat or whole-account) |

Auto-detect picks the right one:

$ bettersync detect ~/Downloads/some-export/
whatsapp  (WhatsApp (text export))

Want a different format? Adding one is one file under src/parsers/. See CONTRIBUTING.md.

Commands

bettersync init                              Interactive first-time setup

bettersync auth login --token <token>            Save your S16 API token
bettersync auth llm --provider <id> --key <key>  Configure your LLM provider
                                                  (groq | openai | openrouter |
                                                   together | fireworks | cerebras |
                                                   deepinfra | ollama | lmstudio)
bettersync auth llm --base-url <url> [--key]     Or any OpenAI-compatible URL
                    [--model <id>]
bettersync auth groq --key <key>                 Shortcut for `auth llm --provider groq`
bettersync auth status                           Show saved credentials (masked)
bettersync auth logout                           Clear all saved credentials

bettersync formats                           List supported source formats
bettersync detect <folder>                   Auto-detect a folder's format
bettersync ingest <folder>                   Parse + push to Brain
                  [--dry-run] [--format <id>]

bettersync extract-insights                  Extract structured insights from
                  [--limit <n>]               your Conversations using your LLM

bettersync run <name>                        Run an agent (mode from config:
                  [--input <json>]            local | platform | auto)
                  [--input-file <path>]
                  [--mode <mode>]             override defaultMode for this call

bettersync config                            Show all settings (secrets masked)
bettersync config <key>                      Get one value (dotted path ok)
bettersync config <key> <value>              Set one value
bettersync config edit                       Open the config file in $EDITOR

bettersync agents list                       List all agents in your Brain
bettersync agents run <name>                 (advanced) explicit platform run
bettersync agents run-local <name>           (advanced) explicit local run

How it works under the hood

Ingest pipeline

[your machine]                                       [api.team-brain.com]
  bettersync ingest ./folder                              MCP HTTP
       │                                                    server
       ├── parser/<source>.mjs   →  uniform schema   ───►  s16_create_page
       │      (one of 3 today)                                   ↓
       │                                                       database
       └── pipeline                                              row
            • bootstrap schema (idempotent)
            • dedupe Conversations by handle
            • bulk-insert Messages (concurrency 12)
            • progress + retry

Local agent runner

bettersync agents run-local "X"
       │
       ├── 1. fetch agent.compiledScript via s16_get_agent
       │
       ├── 2. spin up a Node sandbox with a custom `s16` global:
       │        s16.ai(...)         → your configured LLM (Groq / OpenAI /
       │                              Ollama / OpenRouter / etc.)
       │        s16.httpRequest(...) → native fetch
       │        s16.createPage(...)  → MCP call to your workspace
       │        s16.readDatabase(...) → MCP call to your workspace
       │        s16.getCredential('groq') → returns local key only when
       │                                    provider is groq (so existing
       │                                    Groq-hardcoded agents still work)
       │        s16.store / sharedStore   → in-memory KV (this run only)
       │
       └── 3. execute the script. Same agent, your chosen LLM, no S16 wallet.

The CLI speaks MCP-over-HTTP (JSON-RPC 2.0 on a single endpoint) using your bearer token. Same surface that Claude Desktop / Claude Code use, just called from a regular HTTP client. No tunnel, no intermediate storage.

Limitations of the local runner

  • Workspace credentials/secrets other than Groq aren't auto-forwarded — your agent's s16.getCredential('telegram') returns null locally.
  • s16.store and sharedStore are in-memory for the run only; no persistence.
  • Webhook/event/cron triggers obviously don't apply — run-local is on-demand.
  • File uploads (s16.uploadFile) aren't implemented yet.

For these cases, fall back to bettersync agents run <name> which triggers the agent on the platform.

Adding a parser

See CONTRIBUTING.md. Short version: write one file under src/parsers/, register it in src/parsers/index.mjs, done. Each parser is ~150 lines and ~30 minutes of work.

License

MIT — see LICENSE.