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

openclaw-quiubo

v2.4.0

Published

OpenClaw Quiubo channel plugin — chat with AI assistants through Quiubo

Readme

openclaw-quiubo

OpenClaw channel plugin for Quiubo — chat with AI assistants through Quiubo's SDK API.

Installation

npm install openclaw-quiubo

Setup

Quiubo is configured with:

openclaw channels add --channel quiubo

This launches the interactive setup wizard which will:

  1. Prompt for your SDK API Key (starts with qub_)
  2. Authenticate against the Quiubo API
  3. List your existing bot identities or create a new one
  4. Save the configuration

Prerequisites

You need a Quiubo SDK app with an API key. Get one from the Developer section in the Quiubo app settings.

What you'll need

| Item | Where to get it | |------|----------------| | SDK API Key | Quiubo app → Settings → Developer → API Keys | | Bot Identity | Created during setup wizard, or pre-create in Developer console |

Configuration

After running channels add, your OpenClaw config will contain:

channels:
  quiubo:
    accounts:
      default:
        enabled: true
        apiUrl: https://api.quiubo.io
        apiKey: qub_...
        botIdentityId: <uuid>
        pollIntervalMs: 5000

Config fields

| Field | Required | Default | Description | |-------|----------|---------|-------------| | apiKey | Yes | — | SDK API key (starts with qub_) | | botIdentityId | Yes | — | UUID of the bot's service identity | | enabled | No | true | Enable/disable this account | | apiUrl | No | https://api.quiubo.io | API base URL | | pollIntervalMs | No | 5000 | Polling fallback interval in ms |

Multiple accounts

You can configure multiple accounts by running the setup wizard again:

openclaw channels add --channel quiubo

When prompted for Account ID, enter a new name (e.g., support-bot, sales-bot).

Multi-Agent Setup

Run multiple AI agents on a single OpenClaw gateway — each with their own Quiubo chat, workspace, model, and cron jobs. For example: a personal assistant on Opus and an autonomous project manager on Sonnet, each in their own chat.

Step 1: Add the agent

In ~/.openclaw/openclaw.json, add a new agent to the list:

{
  "agents": {
    "list": [
      { "id": "main" },
      {
        "id": "project-manager",
        "model": "anthropic/claude-sonnet-4-5",
        "workspace": "~/.openclaw/workspace-project-manager"
      }
    ]
  }
}

Each agent can use a different model — useful for cost control when running autonomous agents.

Step 2: Add a Quiubo account for the agent

Add a second account under the Quiubo plugin config. You can reuse the same SDK API key — each account just needs its own bot identity:

{
  "plugins": {
    "quiubo": {
      "accounts": {
        "default": {
          "sdkApiKey": "qub_...",
          "botIdentityId": "<main-bot-uuid>"
        },
        "pm": {
          "sdkApiKey": "qub_...",
          "botIdentityId": "<pm-bot-uuid>"
        }
      }
    }
  }
}

Create additional bot identities through the Quiubo developer console or the setup wizard.

Step 3: Bind accounts to agents

Bindings tell OpenClaw which Quiubo account routes to which agent:

{
  "bindings": [
    {
      "match": { "channel": "quiubo", "accountId": "default" },
      "agentId": "main"
    },
    {
      "match": { "channel": "quiubo", "accountId": "pm" },
      "agentId": "project-manager"
    }
  ]
}

Without bindings, all messages route to the first agent. This is the most common setup issue — don't skip this step.

Step 4: Create the agent's workspace

mkdir -p ~/.openclaw/workspace-project-manager/memory

Seed it with the standard OpenClaw agent files:

  • SOUL.md — personality and purpose
  • AGENTS.md — operating instructions
  • USER.md — info about the human
  • IDENTITY.md — name, emoji, avatar
  • MEMORY.md — long-term memory (starts empty)

Step 5: Copy auth profiles (optional)

If the new agent needs access to the same services (web search, APIs, etc.):

mkdir -p ~/.openclaw/agents/project-manager/agent/
cp ~/.openclaw/agents/main/agent/auth-profiles.json ~/.openclaw/agents/project-manager/agent/

Step 6: Restart

openclaw gateway restart

The new agent is live. Messages to the PM bot identity route to project-manager, use Sonnet, and read from its own workspace.

How routing works

Quiubo Chat (You + Main Bot)  → account: default → binding → agent: main
Quiubo Chat (You + PM Bot)    → account: pm      → binding → agent: project-manager
  • Messages: The plugin passes AccountId to OpenClaw, which resolves the agent from bindings
  • Cron jobs: Filtered by agentId — each agent's chat only shows its own jobs
  • Sessions: Each agent gets its own session namespace, no cross-talk
  • Workspaces: Fully isolated — agents can't see or edit each other's files

Full config example

{
  "agents": {
    "list": [
      { "id": "main" },
      {
        "id": "project-manager",
        "model": "anthropic/claude-sonnet-4-5",
        "workspace": "~/.openclaw/workspace-project-manager"
      }
    ]
  },
  "bindings": [
    {
      "match": { "channel": "quiubo", "accountId": "default" },
      "agentId": "main"
    },
    {
      "match": { "channel": "quiubo", "accountId": "pm" },
      "agentId": "project-manager"
    }
  ],
  "plugins": {
    "quiubo": {
      "accounts": {
        "default": {
          "sdkApiKey": "qub_...",
          "botIdentityId": "<main-bot-uuid>"
        },
        "pm": {
          "sdkApiKey": "qub_...",
          "botIdentityId": "<pm-bot-uuid>"
        }
      }
    }
  }
}

Tips

  • Cost control: Use cheaper models for autonomous agents that run frequently
  • Workspace isolation: Agents should never edit each other's files — enforce this in their AGENTS.md
  • Permissions: Add rules about what agents can/can't do (e.g., "ask before spending money")
  • Scaling: Same pattern for any number of agents — new ID, new bot identity, new binding, new workspace

Markdown Attachments

Agents can send .md file attachments alongside their messages. Attachments appear as tappable cards in the Quiubo app with a full markdown viewer.

How it works

OpenClaw uses the MEDIA: token protocol. When an agent writes a file and includes a MEDIA: /path/to/file.md line in its response text, the dispatcher extracts it and passes the path to the plugin. The plugin reads the file from disk and sends it as an attachment via the Quiubo API.

Supported: .md files only, max 1MB each, max 5 per message.

Agent instructions

Add this to your agent's AGENTS.md so it knows how to send attachments:

## Sending File Attachments

When you want to attach a markdown file to your reply:
1. Write the file to disk (e.g. `/tmp/report.md`)
2. Include a `MEDIA:` token in your response text pointing to the file path

Example response:
  Here's your daily report:

  MEDIA: /tmp/daily-report.md

The file will be delivered as a tappable attachment card in the chat.
Only `.md` files are supported. Files over 1MB are skipped.

Cron job attachments

Cron jobs with delivery.channel already target the correct group. To send attachments from a cron job, the cron agent just needs to follow the same MEDIA: token protocol — write the .md file, then include the MEDIA: line in the output.

What the user sees

  • In chat: A compact card below the message text showing the filename, size, and source badge (agent/subagent/cron)
  • On tap: Full-screen markdown viewer with rendered content
  • In group details: A "Documents" tab listing all attachments in the group, filterable by source

How it works

Message delivery

The plugin uses a dual-mode gateway for receiving messages:

  • Primary: Pusher WebSocket — real-time push delivery
  • Fallback: Polling — automatic fallback when Pusher is unavailable

Outbound messages are sent via the Quiubo SDK REST API.

Auto-provisioning

On first gateway startup, if the bot has no groups, the plugin automatically:

  1. Creates a welcome group (type: agent_channel)
  2. Adds the bot as a member
  3. Sends a welcome message

This means users can start chatting immediately after setup — no manual group creation needed.

Inbound routing

Messages are routed through OpenClaw's agent pipeline using the standard finalizeInboundContext()dispatchReplyWithBufferedBlockDispatcher() pattern (same as openclaw-mqtt).

Session keys use the format quiubo:<groupId>. The AccountId field in the context payload tells OpenClaw which agent to route to via the bindings config.

Bot-Enabled Gating

The extension implements a multi-step gating pipeline to determine whether to respond to a message. This runs for every incoming message (both Pusher and polling paths).

Gating Pipeline

  1. Self-echo skip — Messages from the bot's own identity are ignored
  2. Agent channel bypassagent_channel groups always process messages (1:1 bot channels)
  3. Security mode check — Only PLAINTEXT_SDK groups are processed; E2EE groups are skipped
  4. Bot-enabled checksettings.bot.enabled must be true (with cache-miss fallback)
  5. Owner takeover — If the sender is the group owner, suppress bot for suppressionMinutes
  6. Suppression check — If currently suppressed, skip the message

Bot Config Cache

The extension maintains an in-memory cache of bot configuration per group:

interface BotConfig {
  enabled: boolean;
  suppressionMinutes: number;
  ownerIdentityId: string;
  groupType: string; // 'standard' | 'agent_channel'
}
  • Populated at startup from listGroups() + listGroupMembers() for each group
  • Updated on cache miss via onCacheMiss callback (5s timeout, fail-closed)
  • Hydrated from polls when Pusher is unavailable

Suppression Map

Owner takeover suppression uses a Map<groupId, suppressedUntil>:

  • When the group owner sends a message, suppressedUntil is set to now + suppressionMinutes * 60_000
  • Entries older than 1 hour are periodically evicted via clearStaleSuppression()

Cache-Miss Strategy

When a message arrives for a group not in the cache (e.g., newly created):

  • Extension calls onCacheMiss(groupId) which fetches group details + members from the API
  • 5-second timeout — if the fetch fails or times out, the message is skipped (fail-closed)
  • This is safer than fail-open: better to miss a message than respond incorrectly

Managing accounts

Disable an account

openclaw channels disable --channel quiubo

Remove an account

Delete the account entry from your OpenClaw config, or use the config editor.

Development

npm run build       # Compile TypeScript
npm run typecheck   # Type-check without emitting

Project structure

src/
  api.ts               # REST API client (QuiuboApiClient)
  channel.ts           # Channel plugin (config, setup, onboarding, outbound, gateway)
  realtime-gateway.ts  # Pusher WebSocket + polling fallback
  polling-gateway.ts   # Polling-only gateway
  webhook-handler.ts   # HTTP webhook server (alternative inbound)
  runtime.ts           # Plugin runtime singleton
  types.ts             # TypeScript type definitions

API coverage

The QuiuboApiClient wraps these SDK endpoints:

| Category | Methods | |----------|---------| | Auth | authenticate() | | Messages | sendMessage(), listMessages() | | Groups | createGroup(), listGroups(), getGroup(), addMembers(), removeMembers(), listGroupMembers(), updateGroupSettings() | | Identities | createIdentity(), listIdentities(), deleteIdentity() | | Join Tokens | createJoinToken(), listJoinTokens(), deleteJoinToken() | | Webhooks | configureWebhook() | | Pusher | pusherAuth() |

License

MIT