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

mozartsh

v0.1.0

Published

An AI agent orchestrator that runs isolated, persistent agents defined in declarative `.soul` files. Each agent runs inside its own Podman container with resource limits, filesystem isolation, and a full toolkit for memory, scheduling, inter-agent messagi

Readme

Mozart

An AI agent orchestrator that runs isolated, persistent agents defined in declarative .soul files. Each agent runs inside its own Podman container with resource limits, filesystem isolation, and a full toolkit for memory, scheduling, inter-agent messaging, skill discovery, and web browsing.

Quick Start

# Install dependencies
bun install

# Install Podman, initialize the VM (macOS/Windows), and build the agent image
mozart setup

# Start agents from .soul files
export OPENROUTER_API_KEY=sk-or-...
mozart up agents/

# Open the chat UI
open http://localhost:4141

Architecture

graph TB
    subgraph cli [CLI]
        MozartCLI["mozart up / ps / send / ..."]
    end

    subgraph daemon [Daemon Process]
        HTTP["HTTP Server :4141"]
        Supervisor
        Scheduler["Cron Scheduler"]
    end

    subgraph containers [Podman Containers]
        subgraph c1 ["Container: lead"]
            W1["Bun + Agent"]
            T1["16 Tools"]
            M1["SQLite Memory"]
        end
        subgraph c2 ["Container: coder"]
            W2["Bun + Agent"]
            T2["16 Tools"]
            M2["SQLite Memory"]
        end
        subgraph c3 ["Container: reviewer"]
            W3["Bun + Agent"]
            T3["16 Tools"]
            M3["SQLite Memory"]
        end
    end

    subgraph external [External Services]
        OpenRouter["OpenRouter API"]
        SkillsSH["skills.sh Registry"]
        GitHub["GitHub Raw Content"]
    end

    subgraph ui [Chat UI]
        SvelteApp["Svelte 5 SPA"]
    end

    MozartCLI -->|HTTP| HTTP
    SvelteApp -->|SSE + REST| HTTP
    HTTP --> Supervisor
    Supervisor -->|"stdin/stdout JSON"| c1
    Supervisor -->|"stdin/stdout JSON"| c2
    Supervisor -->|"stdin/stdout JSON"| c3
    Scheduler -->|"triggers via stdin"| c1
    Scheduler -->|"triggers via stdin"| c2
    W1 --> OpenRouter
    W2 --> OpenRouter
    W3 --> OpenRouter
    W1 --> SkillsSH
    W1 --> GitHub
    Supervisor --> containers

How It Works

Agent Lifecycle

sequenceDiagram
    participant User
    participant CLI as mozart CLI
    participant Daemon as Daemon / Supervisor
    participant Podman
    participant Container as Agent Container

    User->>CLI: mozart up agents/
    CLI->>Daemon: POST /api/agents {soulfilePath}
    Daemon->>Daemon: Parse .soul file
    Daemon->>Podman: podman run --rm -i mozart-agent:latest
    Podman->>Container: Start worker.ts
    Container->>Container: Initialize Agent + tools
    Container-->>Daemon: {"type":"ready"}
    Daemon-->>CLI: 201 {id: "lead", state: "running"}
    CLI-->>User: lead (openai/gpt-4.1-mini)

Chat Message Flow

sequenceDiagram
    participant User
    participant UI as Chat UI
    participant Server as HTTP Server
    participant Sup as Supervisor
    participant Container as Agent Container
    participant LLM as OpenRouter

    User->>UI: Types message
    UI->>Server: POST /api/agents/lead/messages
    Server->>Sup: streamChat("lead", "user", message)
    Sup->>Container: stdin: {"type":"chat", message}
    Container->>LLM: Stream completion request
    LLM-->>Container: Delta chunks
    Container-->>Sup: stdout: {"type":"event", event}
    Sup-->>Server: yield StreamEvent
    Server-->>UI: SSE: data: {"type":"text", "text":"..."}
    UI-->>User: Renders streaming response
    Container-->>Sup: stdout: {"type":"chat_done"}

Inter-Agent Routing

Agents communicate using the send tool. The Supervisor mediates all messages between containers.

sequenceDiagram
    participant Lead as lead container
    participant Sup as Supervisor
    participant Coder as coder container

    Note over Lead: User asks for a new feature
    Note over Lead: IF rule triggers: route to coder
    Lead->>Sup: stdout: {"type":"route_request", toId:"coder", message:"Implement..."}
    Sup->>Coder: stdin: {"type":"route", fromId:"lead", message:"Implement..."}
    Coder->>Coder: Writes code via LLM
    Coder-->>Sup: stdout: {"type":"route_done", response:"Implementation..."}
    Sup-->>Lead: stdin: {"type":"route_response", response:"Implementation..."}
    Note over Lead: send tool returns the response

Event Delivery (Mailbox Architecture)

All events from a container's stdout flow through a single EventBus per agent. Consumers subscribe independently — each gets its own async-iterable mailbox. No callbacks, no polling, no single-slot stomping.

graph LR
    subgraph container [Agent Container]
        Worker["Worker stdout"]
    end

    subgraph supervisor [Supervisor]
        Parse["JSON line parser"]
        Bus["EventBus per agent"]
    end

    subgraph consumers [Subscribers]
        Chat1["streamChat #1"]
        Chat2["streamChat #2"]
        BGStream["Background SSE"]
    end

    Worker -->|"stdout JSON lines"| Parse
    Parse -->|"emit()"| Bus
    Bus -->|"subscribe()"| Chat1
    Bus -->|"subscribe()"| Chat2
    Bus -->|"subscribe()"| BGStream

Each subscriber filters for the event kinds it cares about:

flowchart TB
    Emit["EventBus.emit(event)"]

    Emit --> Sub1["Chat subscriber"]
    Emit --> Sub2["Background SSE subscriber"]

    Sub1 -->|"kind: stream"| Yield1["yield StreamEvent"]
    Sub1 -->|"kind: chat_done"| Done1["return"]
    Sub1 -->|"kind: bg*"| Skip1["ignore"]

    Sub2 -->|"kind: bg"| Yield2["enqueue SSE data"]
    Sub2 -->|"kind: bg_done"| Done2["enqueue SSE done"]
    Sub2 -->|"kind: stream"| Skip2["ignore"]

The primitives are two small classes (~100 LOC total):

| Primitive | Role | Pattern | |---|---|---| | Mailbox<T> | Async FIFO queue | Multi-producer, single-consumer. send() enqueues, for await dequeues | | EventBus<T> | Fan-out | Multi-producer, multi-consumer. Each subscribe() returns an independent Mailbox<T> |

This replaces three ad-hoc patterns (callback slot, promise map, listener set) with one unified mechanism. Multiple concurrent chat streams, background SSE connections, and agent-to-agent routes all coexist on the same bus without interference.

Container Isolation

graph LR
    subgraph host [Host Machine]
        Sup["Supervisor"]
        AgentDir["~/.mozart/agents/lead/"]
        Sanctum1["/Users/sean/projects/app"]
    end

    subgraph container ["Podman Container (per agent)"]
        Agent["Agent Process"]
        DataDir["/data/agents/lead/"]
        S1["/sanctum/app"]
    end

    AgentDir -.->|"--volume :rw"| DataDir
    Sanctum1 -.->|"--volume :rw or :ro"| S1
    Sup <-->|"stdin/stdout JSON"| Agent

Each container runs with:

| Flag | Purpose | |---|---| | --memory 256m | Hard RAM cap | | --cpus 0.5 | CPU limit | | --read-only | Immutable root filesystem | | --tmpfs /tmp:rw,noexec,size=64m | Writable temp without exec | | --network slirp4netns | User-mode networking for API calls | | --volume | Only explicitly declared directories |

The .soul File Format

A .soul file is a declarative agent definition. The filename (minus .soul) becomes the agent ID.

MODEL openai/gpt-4.1-mini
SANCTUM ~/projects/my-app
SANCTUM ~/data/shared:ro
SKILL vercel-labs/agent-skills@code-review

SOUL <<BLOCK
You are a code review assistant for my-app.
You analyze pull requests and provide actionable feedback.
BLOCK

IF "the change affects the database schema" THEN "flag it as high-risk and notify the backend team via send"
SCHEDULE "weekdays at 9am" "Check for open PRs that need review"

Instructions

| Instruction | Required | Description | |---|---|---| | MODEL <provider/model> | Yes | OpenRouter model ID (350+ models supported) | | SOUL <text> | Yes | Agent persona / system prompt. Use <<DELIM ... DELIM for multi-line | | SANCTUM <path>[:ro\|:rw] | No | Mount a host directory into the container. Defaults to read-write. Supports ~/ and relative paths. Every agent also gets a default sanctum at ~/.mozart/agents/<id>/sanctum/ mounted at /sanctum | | SKILL <owner/repo@name> | No | Install a skill from skills.sh | | IF "<condition>" THEN "<action>" | No | Conditional behavioral rule | | SCHEDULE "<timing>" "<task>" | No | Recurring task with natural-language timing |

Lines starting with # are comments. Blank lines are ignored.

Agent Tools

Every agent has access to 16 built-in tools:

| Tool | Description | |---|---| | search_memory | Full-text search over long-term memory (SQLite FTS5) | | save_to_memory | Persist facts, preferences, or decisions | | send | Send a message to another agent and receive the response | | schedule | Create a recurring task with natural-language timing | | list_schedules | List active cron schedules | | delete_schedule | Remove a schedule | | list_agents | See all running agents | | stop_agent | Stop another agent | | start_agent | Restart a stopped agent | | remove_agent | Permanently remove another agent | | spawn_agent | Create a new agent from .soul content at runtime | | search_skills | Search the skills.sh registry | | install_skill | Install a skill and add it to the system prompt | | list_skills | List installed skills | | read_skill | Read the full content of an active skill | | web_fetch | Fetch a URL and return clean markdown content |

Skills

Skills are reusable instruction sets from the skills.sh open registry. They're fetched from GitHub and injected into the agent's system prompt.

sequenceDiagram
    participant Agent
    participant SkillsMgr as SkillsManager
    participant Cache as ~/.mozart/agents/id/skills/
    participant SkillsSH as skills.sh API
    participant GH as GitHub Raw

    Agent->>SkillsMgr: search_skills("code review")
    SkillsMgr->>SkillsSH: GET /api/search?q=code+review
    SkillsSH-->>SkillsMgr: [{source, skillId, installs}]
    SkillsMgr->>GH: Fetch SKILL.md descriptions
    GH-->>SkillsMgr: SKILL.md content
    SkillsMgr-->>Agent: Ranked results with descriptions

    Agent->>SkillsMgr: install_skill("vercel-labs/agent-skills@code-review")
    SkillsMgr->>Cache: Check local cache
    alt Not cached
        SkillsMgr->>GH: Fetch SKILL.md
        GH-->>SkillsMgr: Content
        SkillsMgr->>Cache: Save to disk
    end
    SkillsMgr-->>Agent: Skill injected into system prompt

Skills are managed per-agent via the SKILL instruction in .soul files, or dynamically using the install_skill / search_skills tools at runtime.

Memory and Persistence

Each agent has its own SQLite database at ~/.mozart/agents/<id>/memory.db with WAL mode for concurrent access.

graph TB
    subgraph db ["SQLite Database (per agent)"]
        Messages["messages — full conversation history"]
        Memories["memories — long-term facts via FTS5"]
        Schedules["schedules — persistent cron jobs"]
    end

    subgraph tools [Agent Tools]
        SearchMem["search_memory → FTS5 MATCH query"]
        SaveMem["save_to_memory → INSERT into memories"]
        Sched["schedule → INSERT into schedules"]
    end

    subgraph host [Host APIs]
        HistoryAPI["GET /api/agents/:id/history"]
        SchedAPI["GET /api/agents/:id/schedules"]
    end

    SearchMem --> Memories
    SaveMem --> Memories
    Sched --> Schedules
    HistoryAPI --> Messages
    SchedAPI --> Schedules

Agent registrations are discovered from the filesystem — any directory under ~/.mozart/agents/ containing an agent.soul file is restored on daemon restart.

Scheduling

Two-layer scheduling system combining static declarations with runtime flexibility.

sequenceDiagram
    participant Soul as .soul file
    participant Sup as Supervisor
    participant LLM as OpenRouter
    participant Cron as CronScheduler
    participant Container as Agent Container

    Note over Soul: SCHEDULE "weekdays at 9am" "Send briefing"
    Soul->>Sup: Parse SCHEDULE instruction
    Sup->>LLM: "Convert 'weekdays at 9am' to cron"
    LLM-->>Sup: "0 9 * * 1-5"
    Sup->>Cron: Register cron job

    Note over Cron: 9:00 AM Monday
    Cron->>Sup: Job fires
    Sup->>Container: stdin: {"type":"chat", fromId:"scheduler", message:"Send briefing"}
    Container->>LLM: Process the task
    LLM-->>Container: Response

Agents can also create schedules dynamically using the schedule tool during conversation.

CLI Reference

# Setup
mozart setup              # Install Podman + build agent image
mozart setup --rebuild    # Force rebuild the container image

# Agent management
mozart up [path]          # Start agents from .soul files (default: current dir)
mozart up --foreground    # Run the daemon in foreground mode
mozart stop <id>          # Stop an agent (keeps registered)
mozart start <id>         # Restart a stopped agent
mozart rm <id>            # Permanently remove an agent
mozart rm --all           # Remove everything and kill the daemon
mozart ps                 # List agents with state, model, uptime
mozart logs [id]          # Tail agent logs (daemon logs if no id)

HTTP API

The daemon runs on http://localhost:4141.

| Method | Endpoint | Description | |---|---|---| | GET | /health | Health check | | GET | /api/agents | List all agents | | POST | /api/agents | Register a new agent | | DELETE | /api/agents | Remove all agents | | DELETE | /api/agents/:id | Remove an agent | | POST | /api/agents/:id/stop | Stop an agent | | POST | /api/agents/:id/start | Restart a stopped agent | | POST | /api/agents/:id/messages | Send a message (SSE stream response) | | POST | /api/agents/:id/talk | Agent-to-agent message (JSON response) | | POST | /api/agents/:id/intro | Trigger agent self-introduction | | GET | /api/agents/:id/history | Get conversation history | | GET | /api/agents/:id/schedules | Get active schedules | | DELETE | /api/agents/:id/schedules/:sid | Delete a schedule |

The Built-in Mozart Agent

Mozart ships with a meta-agent called mozart that creates other agents. When you ask it to build an agent, it:

  1. Identifies the domain and purpose
  2. Searches skills.sh for relevant skills
  3. Picks well-adopted skills that fit the use case
  4. Chooses an appropriate model tier
  5. Outputs a complete .soul file
  6. Can spawn the agent directly using the spawn_agent tool

Project Structure

mozart/
├── src/
│   ├── index.ts          # CLI entry point (Commander)
│   ├── server.ts         # HTTP daemon on :4141, serves UI + API
│   ├── supervisor.ts     # Agent lifecycle: spawn, stop, restart, route
│   ├── agent/
│   │   ├── agent.ts      # Agent class: LLM loop, tools, skills
│   │   ├── tools.ts      # 16 built-in agent tools
│   │   ├── skills.ts     # skills.sh registry client
│   │   ├── memory.ts     # SQLite persistence (messages, memories, schedules)
│   │   ├── parser.ts     # .soul file parser + Zod schema
│   │   └── paths.ts      # ~/.mozart/ directory path helpers
│   ├── worker.ts         # Runs inside Podman — stdin/stdout JSON protocol
│   ├── mailbox.ts        # Mailbox<T> + EventBus<T> async channel primitives
│   ├── podman.ts         # Container spawning, volume flags, image management
│   └── setup.ts          # mozart setup: install Podman, build image
├── agents/               # Default .soul files (mozart, lead, coder, reviewer, scout)
├── planck-claw/          # Embedded LLM provider library (OpenRouter)
├── ui/                   # Svelte 5 + Tailwind 4 + shadcn-svelte chat UI
├── Containerfile         # Agent container image definition
└── package.json

Runtime Data

All state lives under ~/.mozart/:

~/.mozart/
├── mozart.pid            # Daemon PID file
├── daemon.log            # Daemon-level log
└── agents/
    ├── mozart/
    │   ├── agent.soul    # Agent definition (copied on registration)
    │   ├── memory.db     # SQLite (messages, memories, schedules)
    │   ├── agent.log     # Agent-level log
    │   ├── skills/       # Cached skills from GitHub
    │   └── sanctum/      # Default read-write sanctum
    ├── lead/
    │   ├── agent.soul
    │   ├── memory.db
    │   ├── agent.log
    │   ├── skills/
    │   └── sanctum/
    └── ...

Example: Dev Team

Mozart ships with a four-agent dev team that showcases inter-agent routing, scheduling, multi-model orchestration, skills, memory, and agent spawning.

| Agent | Model | Role | |---|---|---| | lead | openai/gpt-4.1-mini | Triages requests and routes to specialists | | coder | anthropic/claude-sonnet-4 | Writes and iterates on code | | reviewer | google/gemini-2.5-pro | Reviews code and triages bugs | | scout | google/gemini-2.5-flash | Researches topics and monitors dependencies |

The agents form a collaborative loop: lead routes work to coder or reviewer, coder sends code to reviewer for feedback, and any agent can ask scout for research. Schedules keep things running autonomously — lead sends daily standups, scout monitors dependencies every 6 hours.

mozart up agents/
# Registers lead, coder, reviewer, scout + built-in mozart agent
# Open http://localhost:4141 and talk to lead to kick things off

Requirements

License

MIT