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

@obelum/translator-claude

v0.3.0

Published

Applies what changed in one language of a document to another, driven by Claude. A translator for Obelum-tracked documents.

Readme

@obelum/translator-claude

Part of Obelum; the repository README lists the packages and the roadmap.

Brings one language of a document up to date with the others, driven by Claude.

npm install @obelum/translator-claude @obelum/core

Given a document in several languages, each keeping a copy of what it last saw of the others (see @obelum/core), a run shows Claude what changed in every language since the target last synced and asks it to apply the equivalent changes. A language the target has never seen is shown in full instead.

Edits arrive as exact string replacements the way a code agent makes them, and a run whose edits did not all land is never saved.

Use

import { obelum } from '@obelum/core';
import { claude } from '@obelum/translator-claude';

const session = obelum({
  langs: ['en', 'sv', 'no'],
  file:   lang   => file(`pages/${lang}/pricing.mdx`),
  synced: viewer => ({ file: lang => file(`.obelum/${viewer}/pages/${lang}/pricing.mdx`) }),
  commit: (verb, lang) => git.commit(`${verb} ${lang}`),
});

// Optional: a glossary and rules about which parts of the format are code,
// and someone to ask when the documents cannot settle what to write.
const translator = claude({ apiKey, instructions: glossary, ask: q => promptUser(q) });

const content = await translator.run(await session.brief('sv'), {
  onEvent: event => console.log(event),   // thinking, reasoning, edit, question, error, done
  isCancelled: () => false,
});
if (content) await session.sync('sv', content);

run returns the finished translation, or null when the run did not complete: cancelled, stopped early, or an edit failed and was never put right. Null is never saved; a partial translation stamped as synced would hide the loss forever. translate(brief) is the same run as a stream of events, for a host that wants to render them itself.

What changed comes from @obelum/core's brief and saving the result is the host's sync. This package only turns the brief into two prompts and three tools (edit_file for targeted changes, write_file for a new or rewritten document, ask for a question), applies the edits as they arrive, and decides whether the result is complete. It never reads a file or walks a git log.

The prompt describes the job, not a procedure: understand each change and why it was made, then make the edits its author would have made in the target. One change may need several edits or none, and the target keeps what it does its own way. With a single-source brief (brief.source), it says the target was translated from the source and corrected and localized by hand. The model's plan and summary are in English.

When the documents cannot settle what to write (two languages give the same fee different amounts, say), the model asks instead of guessing. With ask, the host puts the question to a person and the answer goes back to the model; without it, the question is a question event for the host to log, and the content it is about is left as it was.

Options: model defaults to claude-sonnet-5-5 (in ClaudeAgentOptions, through drive). approach: plan (the default) writes out each change and every place it concerns before editing, and checks each edit against the lines around it; check skips the plan; batch is one shot. diffStyle: hunks (the default) shows each sibling as the target last saw it plus a diff; inline and diff are for comparison; none gives no diff and no earlier version, only the current page of each language in the brief, as a baseline for what the diff is worth. The evals/ folder of the repository measures all of them.

For evaluations, claude({ apiKey, drive }) replaces what talks to the model with a recorded transcript or a probe; everything else runs for real.

The API key

The key is passed per run and used directly, including from a browser. This translator is meant to run where the documents are edited, which may be a static site with no server behind it; the key is the editor's own. In Node the same code path applies.

License

MIT.