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

@cleocode/runtime

v2026.4.11

Published

Long-running process layer for CLEO — agent polling, SSE connections, heartbeat, key rotation

Readme

@cleocode/runtime

Long-running process layer for CLEO. Provides the daemon services that let an agent stay resident on a host: message polling, SSE connection management, heartbeat reporting, and credential key rotation.

This package powers cleo agent start — when an operator starts an autonomous agent, this is the runtime that keeps it alive between human interactions.

Install

pnpm add @cleocode/runtime

Public API

import {
  createRuntime,
  type RuntimeConfig,
  type RuntimeHandle,
  AgentPoller,
  HeartbeatService,
  KeyRotationService,
  SseConnectionService,
} from '@cleocode/runtime';

createRuntime(registry, config)

Top-level entry point. Resolves an agent credential from the registry, configures the poller and ancillary services, opens the transport, and starts polling. Returns a RuntimeHandle for registering message handlers and stopping the runtime cleanly.

import { createRuntime } from '@cleocode/runtime';
import { AgentRegistryAPI } from '@cleocode/core/internal';

const registry = new AgentRegistryAPI(/* ... */);
const handle = await createRuntime(registry, {
  agentId: 'cleo-prime',
  pollIntervalMs: 5000,
  heartbeatIntervalMs: 30000,
  groupConversationIds: ['general', 'announcements'],
});

handle.poller.onMessage(async (msg) => {
  // handle inbound messages
});

// later
handle.stop();

RuntimeConfig

interface RuntimeConfig {
  agentId?: string;              // defaults to most recently active agent
  pollIntervalMs?: number;       // default: 5000
  groupConversationIds?: string[];
  groupPollLimit?: number;       // default: 15
  heartbeatIntervalMs?: number;  // default: 30000, 0 to disable
  maxKeyAgeMs?: number;          // default: 30 days, 0 to disable
  sseEndpoint?: string;
  createSseTransport?: () => Transport;
  transport?: Transport;         // pre-created, bypasses auto-resolution
}

RuntimeHandle

interface RuntimeHandle {
  poller: AgentPoller;
  heartbeat: HeartbeatService | null;
  keyRotation: KeyRotationService | null;
  sseConnection: SseConnectionService | null;
  transport: Transport;
  agentId: string;
  stop: () => void;
}

stop() cleanly shuts down all services in order: SSE connection, heartbeat, key rotation, poller, transport.

Services

AgentPoller

The core polling loop. Fetches direct messages and group-mention messages on a configurable interval, deduplicates against a high-water mark, and dispatches each new message to registered handlers.

HeartbeatService

Periodic agent presence reporting. Tells the SignalDock backend that the agent is alive so other agents can route messages to it without hitting offline timeouts. Disabled when heartbeatIntervalMs === 0.

KeyRotationService

Watches the agent's transport credential age and rotates the API key before it expires. Maintains zero-downtime rotation by overlapping the old and new keys for one poll cycle. Disabled when maxKeyAgeMs === 0.

SseConnectionService

Optional persistent Server-Sent Events connection for sub-second message delivery. When configured, the poller throttles down to a slower interval and SSE handles the realtime path. Falls back automatically to pure polling on connection loss.

Architecture

┌──────────────────────────────────────────┐
│ cleo agent start  (CLI entry)            │
└────────────────┬─────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────┐
│ @cleocode/runtime  createRuntime()       │
│   ┌────────────────────────────────┐     │
│   │ AgentPoller        (poll loop) │     │
│   │ HeartbeatService   (presence)  │     │
│   │ KeyRotationService (creds)     │     │
│   │ SseConnectionService (realtime)│     │
│   └────────────────────────────────┘     │
└────────────────┬─────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────┐
│ @cleocode/contracts  Transport interface │
│   resolves to Local | SSE | HTTP         │
└────────────────┬─────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────┐
│ SignalDock backend (local or cloud)      │
└──────────────────────────────────────────┘

The runtime is transport-agnostic: it works with the local napi-rs SignalDock binding (in-process), SSE realtime, or HTTP polling against api.signaldock.io. The transport layer is selected by createRuntime() based on whether sseEndpoint and transport are present in the config.

CANT profile execution

createRuntime() does not execute .cant workflow profiles directly. Profile-driven workflow execution lives in the cant-bridge.ts Pi extension and runs inside a Pi session, not the daemon. Operators who want profile-driven behaviour should start a Pi session and use /cant:load <file> followed by /cant:run <file> <workflow>.

This boundary was set in ADR-035 §D5 "single engine, cant-bridge.ts as canonical" — runtime stays simple and profile semantics live in one place.

Testing

pnpm --filter @cleocode/runtime test

Tests use mocked transports from @cleocode/contracts to exercise the poller and service lifecycle without hitting a real backend.

Related

License

MIT