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

@engramx/client

v0.15.0

Published

Client SDK for EngramX — persistent, decentralized memory for AI agents on ICP

Readme

@engramx/client

TypeScript SDK for EngramX — persistent, decentralized memory for AI agents on the Internet Computer.

What is this

EngramX (Engram Externalized) stores your AI agent's memory, identity, session history, and wallet in an ICP canister. If the host machine dies, gets hacked, or moves — the agent resumes on a new machine with full state intact.

This package is the client SDK that agents use to read and write their engram.

Install

pnpm add @engramx/client

Quickstart

import { EngramClient } from '@engramx/client';

const engram = new EngramClient({
  canisterId: 'xxxxx-xxxxx-xxxxx-xxxxx-xxx',
  sessionKeyPath: '~/.engramx/session.key',
  clientLabel: 'my-agent', // identifies this host in the engram's cross-model reuse set
});

// At the START of a session: load everything the agent remembers, ready to inject as a
// system prompt. This is the "read me back" that continuity depends on — prefer it over a
// manual readMemoryBatch: it runs on the update path, so the read is recorded on-chain and
// counts toward reuse. (Query reads can't — the IC discards query-path state changes.)
const systemPrompt = await engram.sessionSystemPrompt();
// ...or get the structured files instead of a formatted string:
const ctx = await engram.startSession();
console.log(`loaded ${ctx.includedFiles}/${ctx.totalFiles} files`);

// AS THE AGENT WORKS: append (append-only; the canister concatenates the delta)
const version = await engram.appendMemory('memory/daily.md', '## Notes\nSomething happened.');

// Point reads: one file, or several at once
const file = await engram.readMemory('MEMORY.md');
const files = await engram.readMemoryBatch(['MEMORY.md', 'memory/daily.md']);

// Wallet reads need canReadWallet, which the DEFAULT operator grant does NOT include — the
// default is read + append memory, no wallet, deliberately. Ask the owner for a grant with
// wallet access before uncommenting:
// const balance = await engram.walletBalance();

Pairing

Register your machine as an operator:

# Pair this host — register as operator and install the OpenClaw plugin
pnpm dlx @engramx/client pair <invite-code> --engram <canister-id> --target openclaw

# Replacement host — after pairing, restore memory from the engram
pnpm dlx @engramx/client migrate --engram <canister-id> --recover

pair generates ~/.engramx/session.key, registers the operator, and installs the OpenClaw plugin. migrate then moves memory, saving a local checkpoint first — run npx @engramx/client rollback to undo. Its default direction pushes local memory files to the engram; --recover instead restores database backups, and memory files sync automatically on next OpenClaw startup.

Guardian API

Guardians are trusted principals who can take emergency actions. Adding/removing guardians is an owner-only operation done from the engramx.ai dashboard with Internet Identity authentication. The SDK exposes the read-only side:

// List guardians
const guardians = await engram.listGuardians();

The SDK runs on operator-credentialed agent hosts and intentionally does NOT expose owner-only methods (writeMemory, addGuardian, setProtectedPaths, setPaymentPolicy, resetMyEngram, etc.). Owner workflows belong in the dashboard at engramx.ai.

Backup API

Store and retrieve external database snapshots:

// Init a backup upload
const backupId = await engram.initBackup(
  'sqlite',
  { FullSnapshot: null },
  null,
  sha256,
  'daily-backup',
);

// Upload in chunks
await engram.pushBackupChunk(backupId, 0, chunkData);

// Finalize
await engram.finalizeBackup(backupId);

// List backups
const backups = await engram.listBackups('sqlite');

// Download a chunk
const data = await engram.pullBackupChunk(backupId, 0);

Verify canonical lineage

An engram's own getSpawnedBy() is a self-report — any fork can claim any spawner. The authoritative fact is the registry's testimony: its public, free getCustodyMode(engramId) query answers "managed"/"sovereign" only for engrams it actually spawned, and "unknown" for everything else. The SDK wraps the whole check — registry testimony plus a certified (subnet-signed, not self-reported) module_hash comparison against the registry's attested template — in one call:

import { verifyCanonicalLineage } from '@engramx/client';

const verdict = await verifyCanonicalLineage(engramId, agent);
// verdict.lineage:
//   'canonical'           — the canonical registry vouches for it (managed custody)
//   'canonical-sovereign' — canonical lineage, owner-held keys (code may lawfully differ)
//   'not-canonical'       — the registry does not know it (staging fleet or fork;
//                           verdict.spawnedBy hints which — an unverified self-report)
//   'indeterminate'       — the registry could not be asked; NOT evidence either way
// verdict.codeMatchesCanonicalTemplate: true | false | 'unknown'
//   certified live module hash vs the registry's current template. Lineage ≠ code:
//   false on a managed engram usually just means one release behind, not suspect.

The canonical registry id ships in the SDK as CANONICAL_REGISTRY_CANISTER_ID (empty until the production fleet is live — while empty, calls without an explicit registry report 'indeterminate' by design). Pass { registryId } to ask a different fleet (e.g. staging); the answer is then that fleet's testimony, not canonicity.

OpenClaw Integration

The --target openclaw option on pair handles plugin installation and openclaw.json configuration automatically. For manual setup or customization, see integrations/openclaw/README.md.

Roadmap

These features are stubbed and available in the canister interface but not yet fully implemented:

  • ERC-8004 Agent Identity — threshold ECDSA-derived Ethereum address
  • x402 Payment Protocol — autonomous HTTP-based payments
  • World ID — proof-of-personhood for engram owners

License

MIT