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

@conare/sdk

v1.3.0

Published

Typed, zero-dependency client for the Conare Partner API (per-end-user memory for AI apps).

Readme

@conare/sdk

Typed, zero-dependency TypeScript client for the Conare Partner API: isolated per-end-user memory, versioned source lifecycle, hybrid retrieval, deep recall, and memory-grounded suggestions.

Full reference: docs/openapi.yaml. Caeros handoff: docs/CAEROS_INTEGRATION_PROMPT.md.

Install

bun add @conare/sdk # or: npm i @conare/sdk

It works in Node 18+, Bun, Deno, and Cloudflare Workers through global fetch. Keep the scoped cint_... Integration key in a server-side secret manager.

Start safely

import { Conare, ConareError, hasAnswer } from "@conare/sdk";

const conare = new Conare({
  apiKey: process.env.CONARE_API_KEY!,
  onResponse(meta) {
    metrics.timing("conare.request", meta.durationMs, {
      status: String(meta.status),
      requestId: meta.requestId,
    });
  },
});

// Side-effect-free deploy smoke test: key, namespace config, and backend hop.
await conare.status({ requestId: `deploy-${process.env.RELEASE_ID}` });

const recalled = await conare.recall({
  endUserId: "u_123",
  query: "what matters to this user right now",
});
if (hasAnswer(recalled)) {
  systemPrompt += `\n\nWhat we know about this user:\n${recalled.answer}`;
}

Every request sends one safe X-Request-Id; retries retain it. Every response returns it, and ConareError.requestId exposes it for support correlation.

Write models

Use save for append-only observations whose source has no durable record ID:

await conare.memories.save({
  endUserId: "u_123",
  content: "User prefers smaller islands and wants to avoid crowds.",
  containerTag: "conversation-observation",
});

Use the versioned source lifecycle for database-owned facts. The identity is (endUserId, source, externalId); higher versions correct or delete the same logical record without stale retries resurrecting old state:

await conare.memories.upsertSource({
  endUserId: "u_123",
  source: "caeros-profile",
  externalId: "profile_123",
  version: 7,
  occurredAt: "2026-07-16T10:30:00Z",
  content: "User prefers smaller islands.",
  idempotencyKey: "profile_123:v7",
});

await conare.memories.deleteSource({
  endUserId: "u_123",
  source: "caeros-profile",
  externalId: "profile_123",
  version: 8,
  occurredAt: "2026-07-17T09:00:00Z",
  idempotencyKey: "profile_123:v8",
});

Bootstrap with an outbox

Bulk-mirror database-owned records through memories.lifecycleBatch (at most 100 items and 1 MiB of aggregate content per call). There is no server-side import job: a client-side outbox that re-sends after a crash is the entire resume story — already-applied items replay to the same durable receipt, and superseded versions fail per item with stale_source_version.

const result = await conare.memories.lifecycleBatch({
  endUserId: "u_123",
  items: [{
    source: "caeros-profile",
    externalId: "profile_123",
    version: 7,
    occurredAt: "2026-07-16T10:30:00Z",
    content: "User prefers smaller islands.",
  }],
});

// result.success means only "the batch was processed" — check each item.
for (const [index, item] of result.items.entries()) {
  if (item.success || item.code === "stale_source_version") {
    outbox.markDone(index); // that version (or newer) is durable
  } else {
    outbox.scheduleRetry(index, item.code);
  }
}

Mark an outbox row done on per-item success or per-item stale_source_version (both mean the version is already durable), then send the next batch. Ongoing corrections and deletes use upsertSource / deleteSource with the next version.

API surface

| Client method | Purpose | | --- | --- | | status | Authenticated, side-effect-free deployment readiness | | memories.save, memories.saveBatch | Append-only distilled observations | | memories.search | Fast raw hybrid retrieval without synthesis | | memories.getSource, upsertSource, deleteSource | Durable source-owned lifecycle | | memories.lifecycleBatch | Versioned bulk bootstrap with per-item outcomes | | recall | Citation-grounded personalized answer | | suggestions | Up to five grounded proactive actions | | deleteUser | Complete end-user memory deletion |

Retry and quota behavior

Safe storage, lifecycle, status, and search operations automatically retry network failures, 408, 429, and 5xx responses with bounded exponential backoff. recall and suggestions do not automatically retry because an ambiguous response could repeat paid synthesis; retry those deliberately with the same caller request ID.

try {
  await conare.memories.search({ endUserId, query });
} catch (error) {
  if (error instanceof ConareError) {
    logger.warn("Conare call failed", {
      code: error.code,
      requestId: error.requestId,
      retryAfterSeconds: error.retryAfterSeconds,
    });
    if (error.isUsageExhausted) showBudgetFallback();
    else if (!error.isRateLimited) throw error;
  }
}

recall can also return a typed shallow result on legacy plans; use hasAnswer(response) to distinguish it. Rate state is exposed on both ResponseMeta.rateLimit and ConareError.rateLimit.

Client options

new Conare({
  apiKey: "cint_...",
  baseUrl: "https://api.conare.ai",
  fetch: customFetch,
  timeoutMs: 30_000, // must outlast recall/suggestions synthesis; lower it for storage-only clients
  maxRetries: 2, // fail fast: retries multiply tail latency, and writes are idempotent to retry later
  retryBaseMs: 250, // backoff base; retries wait ~base * 2^attempt (+ jitter)
  maxRetryDelayMs: 60_000, // cap on any single wait, including server-directed Retry-After
  onResponse: (meta) => observe(meta),
});

Each default's full rationale is documented on ConareOptions in src/index.ts.

License

MIT