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

@agentrewind/core

v0.1.4

Published

Dependency-free AgentRewind core runtime for deterministic LLM-agent record, replay, and fork.

Downloads

87

Readme

@agentrewind/core

Dependency-free Node 20 ESM runtime for AgentRewind.

Most users should install the umbrella package, @agentrewind/sdk. Use @agentrewind/core directly when you want the runtime without the CLI package or bundled provider clients.

API Surface

import { AgentRewind } from "@agentrewind/core";

Core exports:

  • AgentRewind.record() for live recording.
  • AgentRewind.recordRun() for the common record-once-and-close flow.
  • AgentRewind.replayRun() for the common load-and-run replay flow.
  • AgentRewind.withProvider() for binding { model, codec, store, tools } once and reusing that setup for record/replay helpers.
  • AgentRewind.replay() for strict, warning, or passthrough replay.
  • AgentRewind.listSessions() and AgentRewind.resolveSessionPath() for finding sessions in a store without manually joining .rewind/<id> paths.
  • AgentRewind.summary() and AgentRewind.listSessionSummaries() for provider, event count, model/tool step, redaction, and token-usage summaries without manually walking events().
  • AgentRewind.timeline() for the same compact rows returned by agentrewind inspect --json.
  • AgentRewind.promptContext() and AgentRewind.promptDiff() for reading or diffing recorded prompts by model-call site or step.
  • AgentRewind.toolCall() for reading recorded tool args, result, error, latency, and provenance by tool name or step.
  • AgentRewind.entropyDraw() for reading recorded ctx.clock(), ctx.random(), ctx.uuid(), or ctx.env() values by source or step.
  • AgentRewind.pack() and AgentRewind.unpack() for programmatic bundle creation/restoration; pack() accepts the same session selectors as replay.
  • assertProviderClient() for failing fast when a codec does not match the SDK client shape.
  • assertProviderCodec() and assertCodecConformance() for failing fast when a custom codec is incomplete or cannot normalize/store/rebuild fixtures.
  • Replay.fork() for replay-prefix/live-tail forking that writes complete child sessions.
  • defineTools() for preserving tool argument/result types in ctx.tools.
  • defineHarness() for preserving harness return types and tool-aware ctx.tools types without manual generic annotations.
  • defineAgent({ tools, harness }) for carrying tool handlers and harnesses together at runtime.
  • Session store helpers for JSONL sessions, blobs, vaults, pack, and unpack.
  • Fingerprinting, redaction, migration, token usage, typed errors, and explainRewindError() for readable drift diagnostics.

The main entrypoint intentionally returns the public Session and Replay interfaces. Internal recorder/replayer classes are kept out of the common API so editor autocomplete shows the methods application engineers are expected to use.

AgentRewind.replay(session) and AgentRewind.replayRun(session, ...) accept a full session path, a session id with { store }, latest with { store }, or a store directory when it contains exactly one session. AgentRewind.replay() can be loaded without a codec when you only need inspection methods such as events(), contextAt(), or diffContext(). Pass { codec } before calling replay.run() or replay.fork(); otherwise AgentRewind throws a ConfigurationError with that fix in the explanation. Recording setup validates the required store, model, and codec fields the same way, which gives JavaScript users actionable setup errors.

Use AgentRewind.summary(session, { store }) when a test or dashboard needs the same high-level facts as agentrewind doctor --json:

const summary = await AgentRewind.summary("latest", { store: ".rewind" });
const summaries = await AgentRewind.listSessionSummaries(".rewind");
const timeline = await AgentRewind.timeline("latest", { store: ".rewind" });
console.log(summary.counts.modelCalls, summary.usage.inputTokens);

Use prompt inspection helpers when you know a stable model-call site:

const messages = await AgentRewind.promptContext("latest", {
  store: ".rewind",
  site: "draft-answer"
});
const diff = await AgentRewind.promptDiff("latest", {
  store: ".rewind",
  fromSite: "draft-answer",
  toSite: "final-answer"
});
const tool = await AgentRewind.toolCall("latest", {
  store: ".rewind",
  name: "lookupCustomer"
});
const entropy = await AgentRewind.entropyDraw("latest", {
  store: ".rewind",
  source: "uuid"
});

Programmatic packing also accepts selectors:

await AgentRewind.pack("latest", "latest-session.rewind", { store: ".rewind" });
await AgentRewind.unpack("latest-session.rewind", "unpacked-session");

Harness Contract

Harness code must route external boundaries through ctx:

import { defineAgent, defineHarness, defineTools } from "@agentrewind/core";

const tools = defineTools({
  lookup: async (args: { id: string }) => ({ id: args.id, plan: "enterprise" as const })
});

const harness = defineHarness(tools, async (ctx) => {
  const id = ctx.uuid();
  const response = await ctx.model.create(request, { site: "decision" });
  const result = await ctx.tools.lookup({ id });
  return { response, result };
});
const agent = defineAgent({ tools, harness });

Use ctx.clock(), ctx.random(), ctx.uuid(), and ctx.env(key) instead of ambient globals when those values affect prompts, tool args, or control flow. Strict replay serves the recorded values instead of reading live environment state.

If the harness calls ctx.tools.someTool() during recording but the session was created without a matching tool handler, AgentRewind throws a ConfigurationError that names the missing tool and lists the configured tools. The usual fix is to use defineAgent({ tools, harness }), or pass the same tools object to defineHarness(tools, harness) and the tools option on AgentRewind.record() or AgentRewind.recordRun().

Tool arguments, tool results, model requests, and normalized model responses must be JSON-compatible. Use toolSerializers for tool values that need runtime types such as Date, Map, classes, or Buffer; keep SDK-specific conversions inside provider codecs.

Error Diagnostics

import { AgentRewind, explainRewindError } from "@agentrewind/core";

try {
  await AgentRewind.replayRun(".rewind/demo", { codec }, harness);
} catch (error) {
  console.error(explainRewindError(error, {
    sessionPath: ".rewind/demo"
  }));
  throw error;
}

The formatter turns structured RewindError.data into expected/actual boundary details, common checks, and useful CLI commands.

Forking

Prefer Replay.fork({ atStep, harness, model }) when you want the fork to run your current agent code. If harness is omitted, fork reuses the last harness passed to Replay.run() when one is available. If a replay is freshly loaded and no harness has been run, fork falls back to a stored-event tail walk: prefix boundary events are persisted into the child as provenance: "recorded", tail model calls go live through the supplied model client, and matching tail tools are recorded into the child as provenance: "recorded".

The resulting child is a normal replayable session. It contains the recorded prefix plus the forked live/stub tail, so a child created from a model step after a tool call can replay with a full matching harness instead of needing a tail-only harness. If the fork changed a prompt or model request, replay the child with the updated harness code that now produces that forked tail request. fork.tokensSpent only counts live tail model calls.

atStep follows the same linearized boundary-event steps returned by events() and printed by the CLI. Splitting inside concurrent work is best-effort because each async lane keeps its own order and the cross-lane split is reconstructed from recorded initiation steps.

Dependencies

@agentrewind/core intentionally has no runtime package dependencies. It uses Node built-ins only.