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

@better-compact/core

v0.4.0

Published

Platform-neutral staged context-pruning ladder over a canonical message IR

Readme

@better-compact/core

Shared context-pruning engine for Better Compact adapters.

Install

npm install @better-compact/core

The OpenCode, OMP, pi, and Claude Code packages bundle or consume this engine through their platform adapters.

Public API

Everything is exported from src/index.ts.

| Module | Main exports | | ---------------------------------- | --------------------------------------------------------------------------------- | | ir.ts | Turn, Item, Codec, CodecOps, Conventions | | ladder.ts | buildPlan, transformTurns, replayPlanSnapshot, LadderSpec | | engine.ts | createEngine, preparePlan, ProcessResult | | stages.ts | pruning stages and Stage | | plan.ts | BoundaryContextPlan, PlanSnapshot, toPlanSnapshot | | ports.ts | EnginePorts, TranscriptStore, PlanStore, Summarizer, Logger | | summarize.ts | createSummaryScheduler | | profiles.ts | presets and config types | | identity.ts | stable keys and range hashes |

Adapter setup

An adapter supplies:

  1. a native message codec;
  2. platform conventions for tools, skills, todos, and notes;
  3. an ordered stage array;
  4. stores for plans and transcripts;
  5. a logger;
  6. a summarizer transport when side-model summaries are enabled.
import { createEngine } from "@better-compact/core"

const engine = createEngine(spec, ports)
const result = await engine.process({
    sessionKey,
    turns,
    contextLimit,
    providerReportedTokens,
})

result.outcome is one of:

  • unchanged: no active plan and no pruning needed;
  • replayed: a valid stored plan was applied;
  • planned: a new plan was built and stored.

Attachment offloading

Set spec.attachments to an AttachmentPolicy to enable the first stage, before tool stubbing. The policy keeps storage and provider pricing in the host:

  • list(item) identifies images and files, including those nested inside tool results.
  • estimateTokens(attachment, item) returns the active provider/model's media cost. Unknown cost returns undefined.
  • store(attachment, item, location) saves the payload and returns a reopenable path or URL. It can be asynchronous.
  • replace(item, attachment, text) replaces the payload with text, preserving unrelated content and the item's key.

The payload stays in the native item handle; core does not copy it into metadata or choose a storage directory. Return a link only after the file is durable and the agent can reopen it. Core passes empty replacement text and emits the link separately, so later summaries cannot truncate the recovery path. Use a stable attachment ID within each item, and change policy.key when the model or retention policy changes.

The stage keeps the protected recent turns and the last two images. keepRecentImages changes that count. Existing compaction archives stay intact. Unpriced attachments, failed writes, and replacements that save no tokens stay unchanged. User prose stays unchanged; an eligible older attachment becomes a stub such as [image/png 1280x800 → /workspace/media/image.png]. Provider estimates replace the codec's generic media estimate for trigger checks and plan accounting. The host should use the provider's image sizing rules, not the base64 string's length.

engine.process() awaits storage automatically. A host that builds forced plans directly must use await preparePlan(turns, inputs, spec, logger). buildPlan() remains synchronous and performs no storage writes; its attachmentJobs describe unresolved work. Persist plans with toPlanSnapshot(). Replay uses saved links without storing the payload again. Changing the policy key invalidates replay so the new provider's costs are applied.

Summary bypass

Pass bypassSummaries: true to skip assistant-message collapse, preview truncation, and prefix summaries. This also refuses cached summary plans. summariesAllowed: false only disables model calls and is a different option. For live settings, engine.process() accepts a reader: bypassSummaries: () => settings.bypassSummaries. The engine rechecks it after asynchronous work before applying a summary.

Automatic passes need no handoff. The host's own compaction threshold measures the pruned request, so native compaction runs exactly when pruning alone cannot keep context below it. For an explicit compaction, plan.needsNativeCompaction is true when pruning leaves context above the target; the host can then run its own compactor. Core does not invoke a provider or duplicate a host's method order. The pi, OMP, and OpenCode settings default bypassSummaries to true; library callers choose the option explicitly.

Development

pnpm --filter @better-compact/core typecheck
pnpm --filter @better-compact/core test
pnpm --filter @better-compact/core build

Architecture

The IR is a view over native messages. Each unchanged item keeps an opaque handle to its original payload. Synthetic pruning output has no native handle.

Native[]
   │ encode
   ▼
Turn[] and Item[]
   │ plan and transform
   ▼
Turn[] and Item[]
   │ decode
   ▼
Native[]

Tool calls and results become one item. Pruning that item removes both native records.

The engine compares estimated usage with the configured trigger. Provider-reported usage can supply a higher floor. A fresh plan selects a raw tail, applies stages in order, writes a transcript, stores a snapshot, and returns transformed turns.

Stored plans contain the boundary, range hash, applied stages, summaries, and transcript path. Replay validates the old prefix before applying the plan. Regrowth can reuse the prior plan as a monotonic floor, so removed content is not restored by a later pass.

The default adapters use this stage order:

  1. skill pruning where supported;
  2. superseded reads;
  3. stale failed-tool inputs;
  4. old tools;
  5. reasoning;
  6. remaining tools;
  7. assistant-run summaries;
  8. rolling prefix summary when required.

The summary scheduler deduplicates jobs, limits concurrency, validates the summary schema, and stops repeated failures for a cooling period. The adapter supplies the model call.

License

AGPL-3.0-or-later