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

lituanic

v0.1.8

Published

AI coworker for solo founders. Picks up Linear issues, writes code, sends email, and reports back to Slack.

Readme

Lituanic

AI coworker for solo founders. Picks up Linear issues, writes code, sends email, and reports back to Slack — autonomously.

Named after the 1933 transatlantic flight by Steponas Darius and Stasys Girenas — two people, one plane, crossing the Atlantic with what they had.

Thesis

Most agent frameworks build orchestration for teams of humans managing fleets of agents. Lituanic solves the opposite: one person running an entire company through one agent.

This is what smart contracts promised — code-first, zero-human operations. Lituanic delivers it with LLMs: an AI coworker that manages projects, writes code, ships products, handles email, and reports back to Slack.

Lituanic is a thin wiring layer on the Claude Agent SDK. The SDK does all the hard work — agent loop, tool calling, sessions, compaction, subagents, sandboxing. Lituanic wires it to Slack and adds opinionated defaults. When Anthropic ships an SDK update, Lituanic gets better for free.

~1,600 lines of TypeScript. 6 built-in integrations. 3 dependencies.

Built-in integrations

| Integration | How | Env vars | |---|---|---| | Slack | Typed MCP tools (reply, react, upload) + Bolt gateway | SLACK_BOT_TOKEN, SLACK_APP_TOKEN | | Linear | SKILL.md + GraphQL API via curl | LINEAR_API_KEY | | 1Password | SKILL.md + op CLI via Bash | OP_SERVICE_ACCOUNT_TOKEN | | Google Workspace | SKILL.md + gws CLI via Bash | GWS_CLIENT_ID + credentials | | Browser | SKILL.md + agent-browser CLI via Bash | None (optional: KERNEL_API_KEY) | | GitHub | SKILL.md + gh CLI via Bash | GH_TOKEN |

Slack is the only typed MCP tool because mistakes are visible to humans. The other 5 use CLI tools or APIs via Bash, which the SDK provides for free.

Adding an integration = writing one SKILL.md file + adding env checks to doctor.ts.

Slack app setup

Create a Slack app at api.slack.com/apps:

  1. Create New App → From scratch → pick your workspace
  2. Socket Mode → Enable Socket Mode → generate an app-level token with connections:write scope → save as SLACK_APP_TOKEN (starts with xapp-)
  3. OAuth & Permissions → add Bot Token Scopes:
    • app_mentions:read — receive @mentions
    • chat:write — send messages
    • im:history — read DM history
    • im:read — open DMs
    • reactions:write — add emoji reactions
    • files:write — upload files (screenshots, PDFs)
  4. Event Subscriptions → Enable Events → Subscribe to bot events:
    • app_mention — triggers on @mentions in channels
    • message.im — triggers on direct messages
  5. Install to Workspace → copy Bot User OAuth Token → save as SLACK_BOT_TOKEN (starts with xoxb-)
  6. App Home → enable "Messages Tab" so users can DM the bot

Quick start

bunx lituanic init my-agent
cd my-agent
// lituanic.config.ts
import { defineConfig } from "lituanic";

export default defineConfig({
  name: "my-agent",
  model: "claude-sonnet-4-6",
  slack: {
    botToken: process.env.SLACK_BOT_TOKEN!,
    appToken: process.env.SLACK_APP_TOKEN!,
  },
});
bun start

Your agent is live in Slack with access to: file system, shell, web search, subagents, and any CLI tool installed on the host.

Check your setup

$ lituanic doctor

  ✓ Claude auth: OAuth token set (Claude Pro/Max subscription)
  ✓ op CLI: Installed
  ✓ OP_SERVICE_ACCOUNT_TOKEN: Set — 1Password secrets available
  ✓ Slack bot token: Set
  ✓ Slack app token: Set
  ✓ Linear API key: Set
  ✓ gh CLI: Installed
  ✓ GH_TOKEN: Set
  ! agent-browser CLI: Not found — install: npm i -g agent-browser && agent-browser install
  ! gws CLI: Not found — install: npm i -g @googleworkspace/cli
  ! GWS credentials: Missing — Google Workspace disabled
  ✓ Backup: Last backup 6h ago

  9 ok, 3 warnings, 0 failures

Add a skill

mkdir -p .claude/skills/deploy
cat > .claude/skills/deploy/SKILL.md << 'EOF'
---
name: deploy
description: Deploy to production. Use when asked to "deploy", "ship it", or "push to prod".
---

1. Run tests: `bun test`
2. Push: `git push origin main`
3. Wait for CI, then check health
4. Report status in Slack
EOF

No code change. No restart. The agent immediately knows how to deploy.

Add an MCP server

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
    }
  }
}

Architecture

┌──────────────────────────────────────────────────────────────┐
│                       lituanic (~1,600 LOC)                   │
│                                                              │
│  ┌─────────────┐  ┌─────────────┐  ┌──────────────────────┐ │
│  │ gateway.ts  │  │ sessions.ts │  │ Claude Agent SDK     │ │
│  │             │  │             │  │ query()              │ │
│  │ Slack Bolt  │  │ thread →    │  │                      │ │
│  │ Webhooks    │──│ session_id  │─▶│ Built-in tools:      │ │
│  │ Cron        │  │ resume      │  │ Bash Read Write Edit │ │
│  │ Chan queue  │  │             │  │ Glob Grep WebFetch   │ │
│  └─────────────┘  └─────────────┘  │ WebSearch Agent Skill│ │
│                                    │                      │ │
│  ┌─────────────┐  ┌─────────────┐  │ SDK handles:         │ │
│  │ tools.ts    │  │ doctor.ts   │  │ • Agent loop         │ │
│  │             │  │             │  │ • Session persist     │ │
│  │ slack_reply │  │ env checks  │  │ • Compaction          │ │
│  │ slack_react │  │ CLI checks  │  │ • Subagents           │ │
│  │ slack_up.. │  │ 1P + backup │  │ • Sandbox             │ │
│  └──────┬──────┘  └─────────────┘  │ • File checkpointing │ │
│         │                          │ • Thinking            │ │
│  ┌──────┴──────┐                   │ • Permissions         │ │
│  │ format.ts   │                   │ • Notifications       │ │
│  │ md → mrkdwn │                   │ • Cost tracking       │ │
│  └─────────────┘                   └──────────────────────┘ │
│                                                              │
│  .claude/skills/ (loaded by SDK)                             │
│  ├── slack/SKILL.md                                          │
│  ├── linear/SKILL.md                                         │
│  ├── op/SKILL.md                                             │
│  ├── gws/SKILL.md                                            │
│  ├── browser/SKILL.md                                       │
│  └── github/SKILL.md                                        │
└──────────────────────────────────────────────────────────────┘

What Lituanic owns (the wiring)

| File | LOC | Purpose | |---|---|---| | gateway.ts | 300 | Slack Bolt + webhooks (Linear state machine) + cron + per-channel queue | | think.ts | 262 | query() wrapper: session resume, effort routing, cost optimization, canUseTool, progress, debug logging | | index.ts | 210 | Daemon boot, typing indicator, notification forwarding | | init.ts | 184 | lituanic init scaffolding (config, .env, .env.op, .gitignore) | | doctor.ts | 175 | Integration health checks (env vars, CLIs, 1Password, backup status) | | config.ts | 137 | Zod config with opinionated defaults | | cli.ts | 87 | CLI: start, init, doctor, health, version | | sessions.ts | 75 | Slack thread to SDK session_id mapping | | memory.ts | 65 | Daily logs + per-channel state | | tools.ts | 63 | Slack MCP tools: reply, react, upload (only typed integration) | | format.ts | 23 | Markdown → Slack mrkdwn converter (shared by index + tools) | | Total | ~1,581 | |

What the Agent SDK owns (delegated)

Every time Anthropic ships an SDK update, Lituanic gets better for free.

| SDK capability | What we skip building | |---|---| | Agent loop + tool calling | No custom loop code | | Built-in Bash, Read, Write, Edit, Glob, Grep | No tool reimplementation | | Built-in WebSearch, WebFetch | No HTTP wrappers | | Skill tool + .claude/skills/ loading | No skill discovery code | | CLAUDE.md loading via settingSources | No system prompt assembly | | System prompt (claude_code preset) | No prompt engineering | | Session persistence + resume + fork | Just store the session_id | | Context compaction | No manual context management | | Subagent orchestration (Agent tool) | No multi-agent plumbing | | Sandbox (filesystem + network isolation) | No Docker code | | canUseTool callback | Inline security, no separate module | | File checkpointing + rewind | Free rollback on error | | Adaptive thinking | Automatic on Opus/Sonnet 4.6 | | Effort control (low/medium/high/max) | One line: effort: "medium" | | Environment passthrough | env: process.env | | Model fallback | fallbackModel: "claude-haiku-4-5" | | Notification hooks | Forward to Slack | | Cost tracking + budget limits | maxBudgetUsd: 5.0 | | MCP server management | Connect any MCP server |

Integration philosophy

                    Typed MCP tools              SKILL.md + CLI via Bash
                    (mistakes are costly)        (CLI teams maintain their tools)
                    ────────────────────         ──────────────────────────────
Slack               ✓ slack_reply
                    ✓ slack_react
                    ✓ slack_upload_file
Linear                                           ✓ GraphQL API via curl
1Password                                        ✓ op CLI
Google Workspace                                 ✓ gws CLI
Browser                                          ✓ agent-browser CLI
GitHub                                           ✓ gh CLI

Why Slack gets typed tools: wrong-channel prevention, thread enforcement, mrkdwn formatting, file uploads. Mistakes are immediately visible to humans.

Why everything else is SKILL.md + CLI: the linear CLI, op CLI, and googleworkspace CLI are well-designed, typed, maintained by their respective companies. When they ship updates, our agent uses new features immediately with zero code changes. We maintain knowledge (SKILL.md), not integration code.

Session continuity

Slack thread = Agent SDK session. Follow-ups resume with full context.

User:  @agent set up the new API endpoint
Agent: [reads code, creates files, runs tests, reports back]
       └── session stored: channel:thread → sess_abc123

User:  (same thread) now add rate limiting
Agent: [resumes sess_abc123 — knows what was built, adds rate limiting]

The SDK handles context window management, compaction, and session persistence to disk. Lituanic just maps Slack threads to session IDs.

Subagents

Claude spawns parallel workers via the built-in Agent tool:

User: @agent research competitors, build the landing page, and set up CI

Agent: Working on these in parallel.
  ├── [Subagent] Researching competitors via WebSearch...
  ├── [Subagent] Building landing page with Read/Write/Edit...
  └── [Subagent] Setting up CI with Bash...

Agent: All three done. Here's the summary.

Claude decides when to parallelize. No orchestration code needed.

Skills

Skills are SKILL.md files in .claude/skills/. The SDK loads them via settingSources: ["project"] and invokes them via the Skill tool when the task matches the description.

.claude/skills/
├── slack/SKILL.md       # When to use Slack tools, formatting rules
├── linear/SKILL.md      # CLI commands, workpad pattern, autonomous work
├── op/SKILL.md          # Secret reading, security rules, patterns
├── gws/SKILL.md         # Email, calendar, drive commands
├── browser/SKILL.md     # Web browsing, screenshots, form filling
└── github/SKILL.md      # PRs, issues, CI, releases

Add your own:

.claude/skills/
└── deploy/SKILL.md      # Your deployment procedure

The description in frontmatter is how Claude decides whether to load the skill. Write it like a search result — specific, with trigger phrases.

Configuration

// lituanic.config.ts
import { defineConfig } from "lituanic";

export default defineConfig({
  name: "my-agent",
  model: "claude-sonnet-4-6",
  fallbackModel: "claude-haiku-4-5",
  cwd: "/home/agent/workspace",

  slack: {
    botToken: process.env.SLACK_BOT_TOKEN!,
    appToken: process.env.SLACK_APP_TOKEN!,
    channel: "C0AKA6Y53D2",  // ops channel for errors + notifications
  },

  webhook: {
    port: 9100,
    routes: {
      "/webhook/linear": {
        secret: process.env.LINEAR_WEBHOOK_SECRET,
        verify: "hmac-sha256",
      },
    },
  },

  schedule: [
    { cron: "0 9,15 * * *", prompt: "Run the x-post skill.", timezone: "Europe/Madrid" },
    { cron: "*/15 * * * *", prompt: "Check Linear for assigned issues and work on them." },
  ],

  maxBudgetUsd: 5.0,
  maxTurns: 50,
  sandbox: false,
});

Authentication

Two options — use either one:

Option A: Claude Pro/Max subscription (recommended)

Uses your existing subscription. No per-token API costs.

# On a machine with a browser (laptop), generate a 1-year token:
claude setup-token
# → Your OAuth token (valid for 1 year): sk-ant-oat01-...

# Store in 1Password, then reference in .env.op:
# CLAUDE_CODE_OAUTH_TOKEN=op://Lituanic/Claude/oauth-token

# Or set directly:
export CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...
bun start

Option B: API key (pay-per-use)

export ANTHROPIC_API_KEY=sk-ant-...
bun start

Both options work with 1Password on VPS: op run --env-file=.env.op -- bun start

Other secrets

export SLACK_BOT_TOKEN=xoxb-...
export SLACK_APP_TOKEN=xapp-...

Deploy

Everything lives in deploy/ — systemd unit, backup cron, bootstrap script, and 1Password templates.

# On a fresh Ubuntu/Debian VPS
bash deploy/setup.sh

# Set the 1Password bootstrap token (root-only)
sudo mkdir -p /etc/systemd/system/lituanic.service.d
sudo tee /etc/systemd/system/lituanic.service.d/override.conf <<EOF
[Service]
Environment=OP_SERVICE_ACCOUNT_TOKEN=ops_YOUR_TOKEN
EOF
sudo chmod 600 /etc/systemd/system/lituanic.service.d/override.conf
sudo systemctl daemon-reload && sudo systemctl start lituanic

The systemd unit (deploy/lituanic.service) runs op run --env-file=.env.op -- bun start with hardened security: NoNewPrivileges, ProtectSystem=strict, ProtectHome=read-only, PrivateTmp.

Daily backups via deploy/backup.sh sync data/ to Google Drive with rclone. lituanic doctor warns if the last backup is older than 48 hours.

Health check built in: GET :9200/health returns JSON.

Comparisons

vs. Pi-mom

| | Pi-mom | Lituanic | |---|---|---| | Codebase | Closed-source npm + 8 monkey patches | ~1,600 LOC, open source | | Concurrency | Serial per channel, no subagents | SDK subagents, parallel work | | Sessions | context.jsonl (custom, fragile) | SDK session persist + resume | | Integrations | Custom extensions in host process | Skills + CLI via Bash | | Config | Undocumented settings.json | Zod-validated TypeScript |

vs. NanoClaw

| | NanoClaw | Lituanic | |---|---|---| | Runtime | Node.js + Docker per group | Bun, single process | | Parallelism | 5 containers, per-group serial | SDK subagents, Claude decides | | Storage | SQLite | Filesystem | | Channels | WhatsApp, Telegram, Discord, Slack, Gmail | Slack + webhooks | | Design | Multi-group multi-container | Single operator |

vs. OpenClaw

| | OpenClaw | Lituanic | |---|---|---| | Scope | 20+ channels, 5400+ skills, voice, canvas | Slack + 6 built-in skills | | Codebase | 19,800+ commits | ~1,600 LOC | | Security | 500+ open issues | Minimal surface, single tenant | | Design | Everything for everyone | One founder, one company |

Design decisions

Why Claude only. When you bet on one model, you use every feature: adaptive thinking, Agent SDK, skills, sessions, subagents, compaction. Multi-provider abstraction means lowest-common-denominator.

Why Slack only. Slack IS the control plane. Every founder already has it open. Adding 20 messaging platforms is OpenClaw's problem, not ours.

Why no database. Files are inspectable, portable, diffable, git-native. Directory structure = schema. The SDK persists sessions to ~/.claude/projects/. We persist daily logs and thread mappings to data/.

Why skills over typed tools. CLI tools (op, gws) and APIs (Linear GraphQL) are maintained by their respective companies. When they ship updates, our agent benefits immediately. We maintain knowledge (SKILL.md), not integration code. Zero maintenance surface for 3 of 4 integrations.

Why parasite architecture. The Claude Agent SDK is backed by a $10B+ company investing heavily in making agents work. Every improvement to the SDK — better compaction, faster loop, new tools, improved sandbox — flows directly to Lituanic with a version bump. We write the thinnest possible wiring layer and get out of the way.

Principles

  1. Parity. Whatever a human can do through a UI, the agent achieves through tools.
  2. Atomic primitives. Bash, Read, Write, Edit — not analyze_and_publish.
  3. Knowledge over code. New capabilities = new SKILL.md files, not new TypeScript.
  4. Maximum parasitism. Delegate everything possible to the Agent SDK. Own only the wiring.
  5. Files as interface. Inspectable, portable, diffable, versioned.
  6. Single operator. One agent, one owner, one Slack. Won't scale to 100 users. Doesn't need to.
  7. Timeless. Small surface area. Version 1.0 should last years.

License

MIT