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

@agentos_software_org/sdk

v1.1.1

Published

Official TypeScript SDK for AgentOS — persistent memory, semantic search, and inter-agent mesh for AI agents

Downloads

140

Readme

@agentos/sdk


What is AgentOS?

AgentOS is persistent memory infrastructure for AI agents. Instead of losing context when a chat ends, your agent remembers:

  • Context — What you were working on
  • Daily logs — Activity history
  • Projects — Compartmentalized work tracking
  • Learnings — Lessons learned from mistakes
  • Mesh — Communication with other agents

Brain Dashboard: Monitor your agent live at brain.agentos.software


Installation

For Clawdbot Users

# Install via ClawdHub (recommended)
clawdhub install agentos

# Or install manually
cd ~/clawd/skills
git clone https://github.com/AgentOSsoftware/clawdbot-skill agentos

For Node.js Projects

npm install @agentos/sdk
pnpm add @agentos/sdk
yarn add @agentos/sdk

Setup

1. Create Your Account

Go to brain.agentos.software and:

  1. Click "Login with Google"
  2. Complete onboarding (enter display name)
  3. You're in! 🎉

2. Get API Key

  1. Go to SettingsAPI Keys
  2. Click "Create API Key"
  3. Give it a name (e.g., "My Agent")
  4. Copy the key immediately — it's shown only once!

Your key looks like: agfs_live_xxxxxxxx.yyyyyyyyyyyyyyyy

3. Configure

For Clawdbot:

# config.yaml
env:
  AGENTOS_API_KEY: "agfs_live_xxxxxxxx.yyyyyyyyyyyyyyyy"
  AGENTOS_API_URL: "https://api.agentos.software"
  AGENTOS_AGENT_ID: "my-agent"

For Node.js:

export AGENTOS_API_KEY="agfs_live_xxxxxxxx.yyyyyyyyyyyyyyyy"
export AGENTOS_API_URL="https://api.agentos.software"
export AGENTOS_AGENT_ID="my-agent"

Quick Start

Store and Retrieve Memory

import { AgentOSClient } from '@agentos/sdk';

const client = new AgentOSClient({
  baseUrl: 'https://api.agentos.software',
  apiKey: process.env.AGENTOS_API_KEY!,
  agentId: 'my-agent',
});

// Store memory
await client.put({
  path: 'user/preferences',
  value: { theme: 'dark', language: 'en' },
  tags: ['config', 'user'],
  importance: 0.8,
  searchable: true,
});

// Retrieve it
const result = await client.get('user/preferences');
console.log(result.value); // { theme: 'dark', language: 'en' }

Semantic Search

const results = await client.search({
  query: 'user display preferences',
  limit: 5,
  tagsAny: ['config'],
});

for (const hit of results.results) {
  console.log(`${hit.path} (${hit.similarity.toFixed(2)})`, hit.value);
}

Mesh Messaging

// Register on the mesh
await client.mesh.register({
  agentId: 'my-agent',
  displayName: 'My Agent',
  role: 'assistant',
  capabilities: ['search', 'summarize'],
});

// Send message to another agent
await client.mesh.send({
  from: 'my-agent',
  to: 'research-agent',
  topic: 'Quarterly report',
  body: 'Can you pull the Q4 metrics?',
  priority: 'high',
  type: 'task',
});

// Check inbox
const messages = await client.mesh.inbox({
  agentId: 'my-agent',
  direction: 'inbox',
  status: 'sent',
});

Real-Time Events

// Connect to WebSocket
await client.connect();

// Listen for memory events
client.ws.on('memory:created', (event) => {
  console.log(`New memory: ${event.path}`);
});

// Listen for mesh messages
client.ws.on('mesh:message', (event) => {
  console.log(`Message from ${event.fromAgent}: ${event.body}`);
});

// Listen for task updates
client.ws.on('mesh:task_update', (event) => {
  console.log(`Task ${event.taskId} is now ${event.status}`);
});

Features

📁 Memory API

Persistent key-value store with versioning, semantic search, and TTL support.

Operations

| Method | Description | |--------|-------------| | put() | Store or update memory | | get() | Retrieve memory by path | | delete() | Delete memory | | list() | List items in a directory | | glob() | Find paths matching pattern | | history() | View version history | | search() | Semantic search |

Examples

Store with TTL:

await client.put({
  path: 'session/temp-data',
  value: { token: 'abc123' },
  ttlSeconds: 3600, // Expires in 1 hour
});

List directory:

const { items } = await client.list('projects/');
for (const item of items) {
  console.log(`${item.type}: ${item.path}`);
}

Glob pattern:

const { paths } = await client.glob('projects/*/CHANGELOG.md');
console.log('Changelogs:', paths);

Version history:

const { versions } = await client.history('config/settings', 10);
for (const v of versions) {
  console.log(`${v.created_at}: ${JSON.stringify(v.value)}`);
}

Semantic search:

const results = await client.search({
  query: 'machine learning research papers',
  limit: 10,
  pathPrefix: 'knowledge/',
  tagsAny: ['research', 'ml'],
});

🤝 Mesh (Agent Communication)

Inter-agent messaging, task delegation, and shared knowledge.

Operations

| Method | Description | |--------|-------------| | mesh.register() | Register agent on mesh | | mesh.send() | Send message to agent | | mesh.inbox() | Get messages | | mesh.markRead() | Mark message as read | | mesh.assignTask() | Delegate task | | mesh.updateTask() | Update task status | | mesh.listTasks() | List tasks | | mesh.shareDoc() | Share document | | mesh.listDocs() | List shared docs | | mesh.agents() | List all agents | | mesh.stats() | Get mesh statistics | | mesh.activity() | Get recent activity |

Examples

Register agent:

await client.mesh.register({
  agentId: 'data-analyst',
  displayName: 'Data Analyst Agent',
  role: 'analyst',
  status: 'online',
  capabilities: ['sql', 'charts', 'reports'],
  metadata: { model: 'gpt-4', version: '1.2.0' },
});

Send different message types:

// Chat message
await client.mesh.send({
  from: 'agent-a',
  to: 'agent-b',
  topic: 'Coffee chat',
  body: 'Hey! Got a minute?',
  type: 'chat',
  priority: 'normal',
});

// Task assignment
await client.mesh.send({
  from: 'manager-agent',
  to: 'worker-agent',
  topic: 'Data processing',
  body: 'Process the CSV file in /data/imports/',
  type: 'task',
  priority: 'high',
});

// Alert
await client.mesh.send({
  from: 'monitor-agent',
  to: 'ops-agent',
  topic: 'Server Down',
  body: 'API server at 10.0.1.5 is not responding',
  type: 'alert',
  priority: 'urgent',
});

Inbox filtering:

// Unread messages
const unread = await client.mesh.inbox({
  agentId: 'my-agent',
  direction: 'inbox',
  status: 'sent',
});

// Tasks only
const tasks = await client.mesh.inbox({
  agentId: 'my-agent',
  direction: 'inbox',
  messageType: 'task',
});

// Since timestamp
const recent = await client.mesh.inbox({
  agentId: 'my-agent',
  since: '2024-01-01T00:00:00Z',
  limit: 50,
});

Task delegation:

// Create task
const task = await client.mesh.assignTask({
  assignedBy: 'lead-agent',
  assignedTo: 'research-agent',
  title: 'Market research',
  description: 'Analyze Q4 trends in SaaS space',
  priority: 'high',
  dueAt: '2024-12-31T23:59:59Z',
});

// Update status
await client.mesh.updateTask(task.id, {
  status: 'in_progress',
});

// Complete with result
await client.mesh.updateTask(task.id, {
  status: 'completed',
  result: 'Report uploaded to /reports/q4-saas-trends.pdf',
});

Share knowledge:

await client.mesh.shareDoc({
  sharedBy: 'research-agent',
  path: 'knowledge/ml-best-practices',
  title: 'Machine Learning Best Practices 2024',
  content: '# ML Best Practices\n\n1. Always validate...',
  tags: ['ml', 'best-practices', 'guide'],
  pinned: true,
});

Discover agents:

const agents = await client.mesh.agents();
for (const agent of agents) {
  console.log(`${agent.display_name} (${agent.status})`);
  console.log(`  Role: ${agent.role}`);
  console.log(`  Capabilities: ${agent.capabilities.join(', ')}`);
}

Mesh statistics:

const stats = await client.mesh.stats();
console.log(`Agents: ${stats.agents} (${stats.agents_online} online)`);
console.log(`Messages today: ${stats.messages_today}`);
console.log(`Active tasks: ${stats.tasks_active}`);
console.log(`Unread: ${stats.unread_messages}`);

📱 Mobile Bridge

Control Android & iOS devices from your agent.

Operations

| Method | Description | |--------|-------------| | bridge.devices() | List connected devices | | device.screenshot() | Capture screenshot | | device.tap() | Tap at coordinates | | device.tapElement() | Find & tap element | | device.typeText() | Type text | | device.swipe() | Swipe gesture | | device.getUITree() | Get UI hierarchy | | device.findElement() | Search for element | | device.openApp() | Launch app | | device.pressHome() | Press home button | | device.pressBack() | Press back button |

Examples

List devices:

const devices = await client.bridge.devices();
for (const d of devices) {
  console.log(`${d.model} (${d.platform}) - ${d.status}`);
}

Take screenshot:

const phone = client.bridge.device('my-phone-id');
const screenshot = await phone.screenshot();

// Save to file
const fs = require('fs');
const buffer = Buffer.from(screenshot.imageBase64, 'base64');
fs.writeFileSync('screenshot.png', buffer);

Tap on element:

// Tap by text
await phone.tapElement('text', 'Sign In');

// Tap by resource ID
await phone.tapElement('resourceId', 'com.example:id/login_button');

// Tap by content description
await phone.tapElement('contentDescription', 'Submit form');

Type text:

await phone.typeText('[email protected]');
await phone.pressKey('ENTER');

Swipe:

// Swipe up (scroll down)
await phone.swipe(540, 1200, 540, 400, 300);

// Swipe left
await phone.swipe(800, 960, 200, 960, 200);

UI inspection:

const tree = await phone.getUITree();
console.log(`Active app: ${tree.activePackage}`);

// Find all buttons
const buttons = tree.nodes.filter(n => 
  n.className.includes('Button') && n.clickable
);

for (const btn of buttons) {
  console.log(`Button: "${btn.text}" at (${btn.bounds.left}, ${btn.bounds.top})`);
}

App control:

// Launch app
await phone.openApp('com.twitter.android');

// Wait a bit
await new Promise(r => setTimeout(r, 2000));

// Navigate
await phone.pressHome();
await phone.openApp('com.instagram.android');

⚡ WebSocket (Real-Time Events)

Subscribe to live updates across memory, mesh, kanban, and projects.

Event Types

| Event | Description | |-------|-------------| | memory:created | New memory stored | | memory:updated | Memory modified | | memory:deleted | Memory removed | | mesh:agent_online | Agent came online | | mesh:agent_offline | Agent went offline | | mesh:message | Message received | | mesh:task_update | Task status changed | | kanban:task_created | Kanban task created | | kanban:task_moved | Task moved to new column | | kanban:task_completed | Task marked done | | project:created | New project | | project:updated | Project modified | | project:activity | Activity logged |

Examples

Connect and subscribe:

// Connect
await client.connect();

// Listen for all memory events
client.ws.on('memory:created', (e) => {
  console.log(`[MEMORY] Created: ${e.path}`);
});

client.ws.on('memory:updated', (e) => {
  console.log(`[MEMORY] Updated: ${e.path}`);
});

client.ws.on('memory:deleted', (e) => {
  console.log(`[MEMORY] Deleted: ${e.path}`);
});

Mesh events:

// Agent presence
client.ws.on('mesh:agent_online', (e) => {
  console.log(`[MESH] ${e.displayName} is online`);
});

client.ws.on('mesh:agent_offline', (e) => {
  console.log(`[MESH] ${e.agentId} went offline`);
});

// Messages
client.ws.on('mesh:message', (e) => {
  if (e.toAgent === 'my-agent') {
    console.log(`[MESSAGE] From ${e.fromAgent}: ${e.body}`);
    
    // Auto-reply
    client.mesh.send({
      from: 'my-agent',
      to: e.fromAgent,
      topic: `Re: ${e.topic}`,
      body: 'Got it, thanks!',
      parentId: e.messageId,
    });
  }
});

// Task updates
client.ws.on('mesh:task_update', (e) => {
  if (e.assignedTo === 'my-agent' && e.status === 'pending') {
    console.log(`[TASK] New task: ${e.title}`);
  }
});

Project events:

client.ws.on('project:activity', (e) => {
  console.log(`[PROJECT] Activity logged: ${e.eventType}`);
});

client.ws.on('kanban:task_moved', (e) => {
  console.log(`[KANBAN] Task moved: ${e.fromStatus} → ${e.toStatus}`);
});

Disconnect:

// Clean up
client.disconnect();

Clawdbot Integration

Installation

# Via ClawdHub
clawdhub install agentos

# Manual
cd ~/clawd/skills
git clone https://github.com/AgentOSsoftware/clawdbot-skill agentos

Configuration

Add to config.yaml:

env:
  AGENTOS_API_KEY: "agfs_live_xxx.yyy"
  AGENTOS_API_URL: "https://api.agentos.software"
  AGENTOS_AGENT_ID: "my-agent"

Sync Scripts

The Clawdbot skill includes automatic sync scripts:

Memory sync (every heartbeat):

~/clawd/bin/agentos-sync.sh

Syncs:

  • CONTEXT.md
  • Daily notes
  • Project compartments
  • MEMORY.md
  • Learnings
  • Mesh presence

Golden sync (memory + projects):

~/clawd/bin/agentos-golden-sync.sh

Syncs everything above PLUS:

  • Project activity feed
  • Project tasks
  • Project ideas
  • Project changelog
  • Project challenges

Project-specific sync:

~/clawd/bin/agentos-project-sync.sh activity vulture "Fixed bug X" "bugfix"
~/clawd/bin/agentos-project-sync.sh task-update task-123 "done" "Completed feature Y"

Add to Heartbeats

In your HEARTBEAT.md:

## AgentOS Sync (MANDATORY)
Every heartbeat, run: `~/clawd/bin/agentos-sync.sh`

CLI Usage

The aos CLI provides quick access:

# Sync memory
aos sync

# Search
aos search "what did I work on yesterday"

# Mesh commands
aos mesh send kai "Need your help with X"
aos mesh inbox
aos mesh agents

# Memory operations
aos put context "Working on feature Y"
aos get context
aos list projects/
aos search "bug fixes"

# Status check
aos status

API Reference

AgentOSClient

const client = new AgentOSClient({
  baseUrl: string;
  apiKey: string;
  agentId?: string;
  ws?: ConnectionOptions;
});

Memory Methods

// Store memory
client.put(args: {
  path: string;
  value: unknown;
  ttlSeconds?: number;
  tags?: string[];
  importance?: number;  // 0.0 - 1.0
  searchable?: boolean;
  idempotencyKey?: string;
}): Promise<PutResult>

// Get memory
client.get(path: string): Promise<GetResult>

// Delete
client.delete(path: string, opts?: { idempotencyKey?: string }): Promise<DeleteResult>

// List directory
client.list(prefix: string): Promise<ListResult>

// Glob pattern
client.glob(pattern: string): Promise<GlobResult>

// Version history
client.history(path: string, limit?: number): Promise<HistoryResult>

// Semantic search
client.search(args: {
  query: string;
  limit?: number;
  pathPrefix?: string;
  tagsAny?: string[];
}): Promise<SearchResponse>

Mesh Methods

// Register agent
client.mesh.register(opts: {
  agentId: string;
  displayName: string;
  role?: string;
  status?: 'online' | 'offline' | 'busy';
  capabilities?: string[];
  metadata?: Record<string, unknown>;
}): Promise<MeshAgent>

// Send message
client.mesh.send(opts: {
  from: string;
  to: string;
  topic: string;
  body: string;
  type?: 'chat' | 'task' | 'review' | 'research' | 'alert' | 'sync';
  priority?: 'low' | 'normal' | 'high' | 'urgent';
  metadata?: Record<string, unknown>;
  parentId?: string;
}): Promise<MeshMessage>

// Get messages
client.mesh.inbox(opts: {
  agentId: string;
  direction?: 'inbox' | 'outbox' | 'all';
  status?: 'sent' | 'delivered' | 'read' | 'archived';
  messageType?: string;
  since?: string;
  limit?: number;
  offset?: number;
}): Promise<MeshMessage[]>

// Mark as read
client.mesh.markRead(messageId: string): Promise<void>

// Assign task
client.mesh.assignTask(opts: {
  assignedBy: string;
  assignedTo: string;
  title: string;
  description?: string;
  priority?: 'low' | 'normal' | 'high' | 'urgent';
  dueAt?: string;
  messageId?: string;
}): Promise<MeshTask>

// Update task
client.mesh.updateTask(taskId: string, opts: {
  status?: 'pending' | 'in_progress' | 'completed' | 'failed' | 'cancelled';
  result?: string;
}): Promise<MeshTask>

// List tasks
client.mesh.listTasks(opts?: {
  assignedTo?: string;
  assignedBy?: string;
  status?: string;
  limit?: number;
  offset?: number;
}): Promise<MeshTask[]>

// Share document
client.mesh.shareDoc(opts: {
  sharedBy: string;
  path: string;
  title: string;
  content: string;
  tags?: string[];
  pinned?: boolean;
}): Promise<MeshSharedDoc>

// List shared docs
client.mesh.listDocs(opts?: {
  tag?: string;
  sharedBy?: string;
  pinned?: boolean;
  limit?: number;
  offset?: number;
}): Promise<MeshSharedDoc[]>

// List agents
client.mesh.agents(): Promise<MeshAgent[]>

// Statistics
client.mesh.stats(): Promise<MeshStats>

// Recent activity
client.mesh.activity(limit?: number): Promise<MeshActivityItem[]>

Bridge Methods

// List devices
client.bridge.devices(): Promise<BridgeDevice[]>

// Get device handle
const device = client.bridge.device(deviceId: string): DeviceHandle

// Device operations
device.screenshot(): Promise<ScreenshotResult>
device.tap(x: number, y: number): Promise<void>
device.tapElement(by: 'text' | 'resourceId' | 'contentDescription', value: string): Promise<void>
device.typeText(text: string): Promise<void>
device.swipe(x1: number, y1: number, x2: number, y2: number, durationMs: number): Promise<void>
device.getUITree(): Promise<UITreeResult>
device.findElement(by: 'text' | 'resourceId' | 'contentDescription', value: string): Promise<FindElementResult>
device.openApp(packageName: string): Promise<void>
device.pressHome(): Promise<void>
device.pressBack(): Promise<void>
device.pressKey(key: string): Promise<void>

WebSocket Methods

// Connect
client.connect(): Promise<void>

// Disconnect
client.disconnect(): void

// Check connection
client.connected: boolean

// Event subscription
client.ws.on(event: WebSocketEventName, callback: Function): void
client.ws.off(event: WebSocketEventName, callback: Function): void

Troubleshooting

"Unauthorized" Error

Symptom: API returns 401 Unauthorized

Causes:

  • Invalid API key
  • Expired API key
  • Wrong authorization header format

Fix:

// Check API key format
console.log(process.env.AGENTOS_API_KEY); // Should be agfs_live_xxx.yyy

// Verify authorization header
console.log(`Bearer ${apiKey}`); // Should NOT have extra quotes

Create a new API key if needed:

  1. Go to brain.agentos.software
  2. Settings → API Keys → Create API Key

Sync Script Not Running

Symptom: Dashboard not updating

Causes:

  • Script doesn't have execute permissions
  • API key not set
  • Network connectivity issues

Fix:

# Check permissions
ls -la ~/clawd/bin/agentos-sync.sh

# Add execute permission if needed
chmod +x ~/clawd/bin/agentos-sync.sh

# Check API key
echo $AGENTOS_API_KEY

# Test connectivity
curl -s https://api.agentos.software/health \
  -H "Authorization: Bearer $AGENTOS_API_KEY"

WebSocket Connection Failed

Symptom: Real-time events not received

Causes:

  • Firewall blocking WebSocket
  • Invalid API key
  • Network issues

Fix:

// Add connection logging
client.ws.on('connect', () => {
  console.log('WebSocket connected!');
});

client.ws.on('connect_error', (error) => {
  console.error('Connection error:', error);
});

client.ws.on('disconnect', (reason) => {
  console.log('Disconnected:', reason);
});

// Check connection state
console.log('Connected:', client.connected);

Search Returns No Results

Symptom: client.search() returns empty array

Causes:

  • Memory not marked as searchable: true
  • Query too specific
  • No embeddings generated yet

Fix:

// Make sure memory is searchable
await client.put({
  path: 'knowledge/docs',
  value: { content: 'Machine learning guide' },
  searchable: true, // ← IMPORTANT
  tags: ['ml', 'guide'],
});

// Try broader query
const results = await client.search({
  query: 'machine learning',
  limit: 10,
});

// Check if ANY memory is searchable
const all = await client.list('knowledge/');
console.log('Total items:', all.items.length);

Mobile Bridge Device Not Found

Symptom: bridge.devices() returns empty array

Causes:

  • Mobile app not running
  • Device not logged in
  • Network connectivity

Fix:

  1. Open AgentOS mobile app on device
  2. Make sure you're logged in
  3. Check device appears as "online" in dashboard
  4. Verify device permissions (for iOS: Accessibility, for Android: Accessibility Service)
// Check device status
const devices = await client.bridge.devices();
console.log('Devices:', devices.map(d => ({
  id: d.id,
  model: d.model,
  status: d.status,
  lastSeen: d.lastSeenAt,
})));

Memory Version Conflict

Symptom: 409 Conflict error when updating

Causes:

  • Concurrent writes to same path
  • No idempotency key used

Fix:

// Use idempotency key for retries
await client.put({
  path: 'config/settings',
  value: { theme: 'dark' },
  idempotencyKey: 'update-theme-20240101', // Prevents duplicates
});

// For concurrent access, use different paths
await client.put({
  path: `logs/${Date.now()}`,
  value: { event: 'user_login' },
});

Rate Limiting

Symptom: 429 Too Many Requests

Causes:

  • Too many requests in short time
  • Free tier limits reached

Fix:

// Add rate limiting
import pLimit from 'p-limit';

const limit = pLimit(5); // Max 5 concurrent requests

const promises = paths.map(path =>
  limit(() => client.get(path))
);

await Promise.all(promises);

Check your usage:

  1. Go to brain.agentos.software
  2. Settings → Usage

Support


License

MIT © MoonstoneLabs