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

livmem

v0.4.0-beta.4

Published

A memory for AI agents that learns which facts actually helped, from task outcomes alone.

Readme

Living Spatial Memory

npm version GitHub release

MVP documentation: Read the complete installation, agent integration, operation, security, and evaluation guide.

Two layers, built and measured together:

  • A memory for AI agents that learns which facts actually helped — from task outcomes alone, with no labelling.
  • A packed 3D spatial field underneath it, where a cell is two bytes, links become geometry, and a corrupted cell is located and repaired by the shape of the lattice itself.

Either can be used on its own. Together they are one system: the memory learns what belongs near what, and the field is where that lives.

Vector search answers "what looks similar to this?". That is a good question, and it is not the one an agent needs. An agent needs "what has actually helped me before in a situation like this?" — and the only honest source for that answer is whether the task worked.

Install the current research alpha from the public npm registry:

npm install livmem

Global agent CLI

Install one command for Codex, Claude Code, and other coding agents:

npm install -g livmem

Global installation makes the CLI available everywhere; it does not merge repository data. Every initialized project keeps its own .living-memory/memory.json. This isolation is the recommended MVP model. Install with --save-dev instead when a team also needs the exact CLI version pinned in that project's lockfile.

Then enter any repository and connect every supported agent convention:

livmem init --target all

The shorter lm command is an alias for livmem. Initialization creates an inspectable .living-memory/memory.json, writes the universal protocol to .living-memory/AGENT.md, and adds an idempotent managed section to AGENTS.md for Codex and to CLAUDE.md for Claude Code. It also registers a required project MCP server in .codex/config.toml and an always-loaded server in .mcp.json. Existing instructions and unrelated MCP servers are preserved.

Restart the agent once after initialization and approve the project MCP server when prompted. Then verify the complete integration:

livmem doctor
livmem status
livmem log --action "Ran the complete test suite" --kind verification --actor codex
livmem actions --limit 20
livmem remember --fact "Use server authority for competitive balances" --related "economy"
livmem recall --query "server economy" --limit 5
livmem recall --query "database migration" --track
livmem outcome --episode-id <id> --success

Commands are non-interactive and return JSON by default so any agent can call them reliably. Use --human for formatted output, livmem --help for the machine-readable command contract, or livmem --brief for a compact description. For tools that do not read AGENTS.md or CLAUDE.md, point the agent at .living-memory/AGENT.md.

The generated protocol and first-party MCP server tell compatible agents to run a task loop: tracked recall at the start, concise action logging during work, durable-fact writeback after verification, and a real success/failure outcome at the end. Actions live in a separate journal inside the same project memory and never pollute recalled facts. Codex and Claude Code receive both repository instructions and discoverable memory tools. Another agent must support MCP or project instructions; livmem cannot silently control an agent that ignores both.

Use npx livmem init --target all instead if you prefer a repository-local installation.

Installation summary:

| Goal | Command | |---|---| | Global CLI for many repositories | npm install -g livmem | | Current beta channel | npm install -g livmem@beta | | Exact released version | Choose a version from GitHub Releases and run npm install -g livmem@<version> | | Team-pinned developer dependency | npm install --save-dev livmem | | One-time setup | npx --yes livmem@latest init --target all | | JavaScript/TypeScript library | npm install livmem | | Public GitHub source | npm install git+https://github.com/Huliichuk/living-spatial-memory.git |

See the MVP guide for individual Codex, Claude Code, and generic-agent setup, the JSON CLI contract, tracked outcome workflow, data model, security boundaries, troubleshooting, and a suggested personal evaluation plan. Public version history is recorded in the changelog and GitHub Releases.

After merging approved work into main, one local command performs the complete release without GitHub Actions:

npm run release:beta

It requires authenticated npm and gh CLIs, verifies that local main exactly matches origin/main, runs the complete test suite and build, increments 0.4.0-beta.N, commits the version, pushes an immutable tag, publishes both the npm latest and beta channels, and marks the matching GitHub Release as Latest. Re-running it repairs an incomplete release instead of inventing another version.

Any release can also be installed from its exact public GitHub tag. For example:

npm install git+https://github.com/Huliichuk/living-spatial-memory.git#v0.4.0-beta.3

It works in any Node.js 20-or-newer ESM project. The local MCP transport uses the official Model Context Protocol server library and requires no hosted service, database, account, or API key.

Agent-visible MCP tools

livmem mcp serves project memory over stdio. Agent hosts discover these tools after initialization:

| MCP tool | Agent behavior | |---|---| | memory_start_task | Required tracked recall at the beginning of a task. | | memory_recall | Read-only lookup without opening an outcome episode. | | memory_log / memory_actions | Write or read meaningful observable work history. | | memory_remember | Store a durable verified fact with routing topics. | | memory_complete_task | Close the tracked episode with its real success or failure. | | memory_status | Inspect facts, actions, pending episodes, outcomes, and misses. |

The MCP initialization response carries server-wide workflow instructions. Codex supports project-scoped MCP configuration and reads server instructions; Claude Code loads the project server from .mcp.json. Project trust approval remains controlled by the agent host.

Three verbs

import { AgentMemory } from "livmem";

const memory = AgentMemory.open();          // .living-memory/memory.json

// 1. Store what happened.
memory.remember("stripe webhooks need the raw body, not parsed json", {
  topics: ["billing", "stripe"],
});

// Keep observable work history separate from reusable knowledge.
memory.recordAction("Verified the webhook tests", {
  kind: "verification",
  actor: "custom-agent",
});

// 2. Retrieve what might help, before doing the work.
const facts = memory.recall("billing");
//  -> [{ id, text, relevance }, ...]

// 3. Say whether it worked. This is the part that makes it learn.
memory.recordOutcome(true);

memory.save();

Facts that keep appearing before successes become easier to reach. Facts that appear before failures fade. Nobody labels anything.

When recalls can overlap, keep their episode ids so each outcome teaches the right activation path:

const first = memory.recallEpisode("billing");
const second = memory.recallEpisode("deploy");

memory.recordOutcome(true, first.id);
memory.recordOutcome(false, second.id);
memory.save();

The recent outcome history and still-open episodes are stored with the graph, so this correlation survives a save and process restart. Plain recall() plus recordOutcome(worked) remains the simple single-task API.

An exact known topic remains the preferred seed. If a query is not an exact topic, the memory now uses an IDF-weighted lexical fallback to find up to five starting cells; this makes ordinary questions usable without pretending that word overlap is semantic understanding.

Why the third verb matters

remember and recall alone are an index. recordOutcome is what turns an index into a memory:

  • Credit is contrasted between the recalls that preceded successes and those that preceded failures — so a fact that is merely popular gains nothing.
  • Credit is written along the activation path, not just onto the query's own links. This is what lets one task's lesson help a different task that reaches the same shared structure.
  • A small amount of exploration is built into recall. A memory whose answer never varies produces outcomes that never differ, and can never learn it was wrong. Set explore: 0 if you need a strictly deterministic reader.

Every one of those three choices is the result of a measurement, not a preference. The experiments that produced them — including the ones that failed — are in docs/research-log.md.

API

| Method | What it does | |---|---| | AgentMemory.open({ path?, learningRate?, explore?, seed? }) | Opens or creates a memory file. | | remember(fact, { relatedTo?, topics?, strength?, importance? }) | Stores a fact; topics are routing-only and never returned. | | markTopic(topic) | Reclassifies a legacy routing cell so it is no longer returned as a fact. | | recall(about, { limit?, depth?, explore? }) | Returns related facts, strongest first. | | recallEpisode(about, options?) | Returns { id, facts } for concurrent or restartable work. | | recordOutcome(worked, episodeId?) | Reports whether the named episode, or otherwise the last recall, helped. | | recordAction(action, { kind?, actor?, at? }) | Appends observable work to the separate project action journal. | | recentActions(limit?) | Reads the newest journal entries in chronological order. | | forget(rate?) | Weakens what has not been used. Call occasionally. | | save() | Atomically writes the graph, learning history and open episodes as readable JSON. | | size | { facts, topics, links, actions }. |

The memory file is plain JSON you can open, read and diff. A memory you cannot inspect is a memory you cannot trust with your project's history.

Honest scope

What this is. An episodic memory layer and local MCP server for agents, plus a packed spatial field to lay it on. Both are measured, inspectable, and local-first.

What this is not. It is not a language model and does not understand text — it stores the strings you give it and reasons over their connections. It is not a replacement for vector search when you genuinely need semantic similarity; the two answer different questions and compose well.

What the current evidence says. Prediction tasks split into three bands: trivial (raw frequency already answers), impossible (the past never contained the answer), and a middle band where the answer is present but buried. On the frozen project-history corpus, untaught memory ties Adamic–Adar in that middle band (23% hit@5 each), while the current outcome-learning rule lowers the score to 16%. This is a useful retrieval substrate, not yet a demonstrated learning advantage. Details in docs/lsm-experiment-020.md.

The spatial layer

SpatialField3D is a packed three-dimensional field: one Uint16Array where every cell carries six fields — value, strength, energy, weight, route class and control — in two bytes.

import { SpatialField3D, packSpatialSymbol16 } from "livmem";

const open = packSpatialSymbol16({
  value: 1, strength: 7, energy: 15, weight: 15, routeClass: 0, control: true,
});
const field = SpatialField3D.filled(32, 32, 32, open);   // 64 KB, 32768 cells

field.setBlocked({ x: 5, y: 5, z: 5 }, true);
const path = field.findPath({ x: 0, y: 0, z: 0 }, { x: 31, y: 31, z: 31 },
  { x: 1, y: 1, z: 1, xy: 0.9, xz: 0.9, yz: 0.9, xyz: 0.8 },
  { algorithm: "a-star", cornerPolicy: "require-clearance" });

const reachable = field.runProgram("reachability", DIRECTIONS);
const influence = field.runProgram("sum-product", DIRECTIONS);
const bytes = field.toBinary();     // portable, versioned

One state, several programs — navigation, reachability and influence run over the same packed cells with no conversion between them.

What the measurements established:

| Property | Result | |---|---| | Pathfinding correctness | Identical optimum and explored set to a conventional implicit A* | | Links as geometry | A placement turns most of a graph's link weight into pure adjacency, needing no storage at all | | Error localisation | Two checks per unit cube name the corrupted cell exactly, at every tiling size | | Repair | Single-fault repair restores the original value; multi-fault syndromes are refused, never guessed — 0 wrong writes in 240,000 trials | | Code capacity | A cube whose links carry 2-bit labels holds exactly 2.000 bits per step; capacity and error detection trade on a measured curve |

Honest limit, measured and recorded: against a minimal conventional representation the packed field is competitive, not smaller — the win is that one state serves several programs and repairs itself locally, reading nine neighbouring cells rather than the whole structure. See docs/spatial-field-api.md and docs/ddse-experiment-007.md.

Research

This started as an experiment in spatial encoding and became a memory. The docs/ directory holds the full record — 39 experiments, each with its protocol, its limits and its result, including the null ones:

  • How relevance is learnedlsm-experiment-003.md009
  • Where learning meets geometrylsm-experiment-010.md013
  • The memory tuning itselflsm-experiment-014.md016
  • Real-data retrieval and scaling limitslsm-experiment-017.md, 018, 020, 021
  • The packed spatial layerddse-experiment-002.md022: routes over one buffer, the minimal weighted cube, four programs on one state, implicit pathfinding against A*, bucket search, wavefront and out-of-core shadow fields, the cube as an edge-labelled code, and localisation and repair from tiled geometry

Reproduce any of them:

npm test
npm run experiment:lsm:008     # transfer through shared structure
npm run experiment:lsm:014     # the memory picking its own operating point
npm run experiment:lsm:018     # the dose scan on a real repository
npm run experiment:lsm:020     # frozen project-graph retrieval benchmark
npm run experiment:lsm:021     # warm recall and returned-context scaling
npm run experiment:ddse:005    # packed A* against a conventional implicit A*
npm run experiment:ddse:020    # integer bucket A* and fair baseline ladder
npm run experiment:ddse:021    # lattice paths against a wavefront solver
npm run experiment:ddse:022    # resident block shadow and block-lazy search
npm run experiment:ddse:010    # localising a corrupted cell from shared vertices
npm run experiment:ddse:011    # repair, and what happens when two cells break

Status

Public 0.4.x MVP beta. The library, universal agent CLI, isolated project memory, and action journal are ready for dogfood evaluation; the internals are still moving. Node.js 20 or newer. Run npm view livmem version for the current published build.

License

Apache-2.0.