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

voice-rewriter

v0.1.1

Published

Rewrite social posts and replies in a supplied voice with Gemini, then fail closed on factual or meaning drift.

Readme

voice-rewriter

Rewrite an original social post or a reply in a user-supplied voice with the Gemini API. voice-rewriter fixes the model to gemini-flash-latest, uses HIGH reasoning, checks exact factual anchors locally, and runs a separate semantic audit before it returns text.

The tool does not research facts. Give it source-backed facts, and it will fail closed when its audit detects added, removed, or contradictory claims.

Requirements

  • Node.js 24 or newer.
  • A Gemini API key in GEMINI_API_KEY.

Voice profiles, examples, source text, facts, and context are sent to Gemini. voice-rewriter adds no persistence, logging, or telemetry.

Install

Install the CLI globally:

npm install --global voice-rewriter

Or run it without a permanent install:

npx voice-rewriter --version

For the library API, add it to your project:

npm install voice-rewriter

Quick start

Create a voice profile from real user-written evidence:

Direct and plainspoken. Keep one point per post. Use first person only when the source supports it. Profanity is allowed when natural. No generic hook, fake excitement, or call to action.

Read the key silently, then export it without putting the value in the command or shell history:

read -r -s GEMINI_API_KEY
export GEMINI_API_KEY
printf '\n'

Rewrite an original post:

voice-rewriter \
  --kind post \
  --profile voice.md \
  --facts facts.md \
  --max-chars 280 \
  "The test suite passed, and the release shipped."

Rewrite a reply from stdin with parent context:

printf '%s\n' 'Yes, build 12 fixed the launch crash.' | \
  voice-rewriter \
    --kind reply \
    --profile voice.md \
    --context parent-post.md

Add --example <file> more than once to supply real user-written samples. Add --json to receive the rewrite, audit, fixed model, and reasoning level as one JSON object.

CLI reference

voice-rewriter --kind <post|reply> --profile <file> [options] [--] ["source text"]

If source text is omitted, the CLI reads stdin.

| Option | Purpose | | --- | --- | | --kind <post\|reply> | Content type. Required. | | --profile <file> | Voice rules grounded in user evidence. Required. | | --example <file> | User-written example. Repeatable. | | --facts <file> | Source-backed facts the rewrite may use. | | --context <file> | Parent post or conversation context. | | --max-chars <count> | Maximum output length in user-perceived characters. | | --json | Print the successful result or error as JSON. | | -- | Treat every remaining argument as source text, including option-like text. | | --help | Show command help. | | --version | Show the installed version. |

Exit codes:

| Code | Meaning | | ---: | --- | | 0 | Rewrite and audit passed. | | 1 | Unexpected local failure. | | 2 | Invalid input or missing configuration. | | 3 | Deterministic or semantic fidelity failure. No candidate is printed. | | 4 | Gemini generation or response failure. |

Library API

import { rewriteSocial } from "voice-rewriter";

const result = await rewriteSocial({
  kind: "reply",
  text: "Yes, build 12 fixed it.",
  voiceProfile: "Short, direct, and useful.",
  context: "Did build 12 fix the launch crash?",
  facts: "Build 12 fixed the launch crash.",
  maxCharacters: 120,
});

console.log(result.text);

The library reads GEMINI_API_KEY by default. It also accepts { apiKey, signal } as the second argument for applications that own their credential and cancellation lifecycle.

Integrity model

Every successful request has four gates:

  1. Local input validation and exact-anchor extraction for URLs, mentions, hashtags, and numeric tokens.
  2. A structured rewrite call using gemini-flash-latest and ThinkingLevel.HIGH.
  3. Local response, anchor, and grapheme-limit validation, with at most one bounded rewrite retry.
  4. A separate structured high-reasoning audit for meaning and claim fidelity.

Source content, profiles, examples, facts, and context are serialized as untrusted data. The prompts explicitly reject embedded instructions. Profanity is allowed and is not a reason to sanitize the source voice.

No model-based audit can prove truth. This design catches deterministic drift and asks a second model pass to detect semantic drift, but callers still own the accuracy of supplied facts and the decision to publish. The gemini-flash-latest alias can change behind the same name; the package intentionally follows that alias because it is part of this tool's contract.

Development

npm ci
npm run lint
npm run test:live   # runs only when GEMINI_API_KEY is set
npm pack --dry-run

The architecture decision and full test plan are in ADR-001 and the implementation plan.

Maintainer

voice-rewriter is built and maintained by Victor Solano.

License

MIT. See LICENSE.