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

@fanalis/narrative

v0.1.0

Published

Local LLM narrative orchestrator. Auto-detects Ollama, falls back to transformers.js (Qwen ONNX) if installed.

Readme

@fanalis/narrative

local LLM narrative orchestrator. v1: ollama only. no cloud fallback.

what it does

  1. detectLLM() — probes OLLAMA_HOST (default http://127.0.0.1:11434) within 600 ms. if alive, returns the highest-priority installed model from a preference list (qwen2.5:1.5b → 3b → 7b → llama3-instruct → mistral-instruct → phi).
  2. createLLMRunner({backend, model})LLMRunner — currently only the ollama branch is wired. transformers-js detection succeeds at detectLLM level but the runner factory returns null (post-v1).
  3. narrateJson<T>(llm, systemHint, userPrompt, schemaDescription, opts) — JSON-only prompt with code-fence stripping; parses + returns typed T or null on parse failure (callers fall back to deterministic output).
  4. narrateText(llm, systemHint, userPrompt, opts) — plain-narrative prompt.

how it's used

the CLI's audit command calls prepareLLM(flags, tier) at T≥3 and threads the resulting LLMRunner into the orchestrator via runAudit({llm}). pillars that want LLM input read opts.llm in their runAtTier body.

current LLM users:

  • @fanalis/pillar-aiseo — calls narrateJson<GapVerdict> for the summarization-gap check (asks the model "what would a user expect to learn here vs what's actually answered?").
  • @fanalis/pillar-conversion — calls narrateText for the per-route conversion narrative (FCRS stage commentary).
  • @fanalis/cli — calls summarizeAudit(llm, {target, composite, top}) at the end of an audit for a 1-paragraph diagnosis.

prompt discipline

narrateJson's system hint always tells the model: "Output JSON only, conforming to this shape: ... Do not include code fences, prose, or explanation." cleaning step strips ``````json fences anyway because models still sometimes wrap.

narrateText keeps the system hint terse and uses maxTokens: 320, temperature: 0.4 by default. callers override per use.

what we removed

  • gemini backend (v0 had @google/genai). v1 ships zero paid-api deps; if GEMINI_API_KEY is set, narrative just doesn't fire.
  • the "transformers-js fallback" hand-wave. detect still surfaces transformers-js as available if @huggingface/transformers is installed, but createLLMRunner returns null for that backend until a real runner ships post-v1.

not in scope

  • vision LLM (LLaVA-Critic etc) — registered as post-v1 in @fanalis/models/registry.ts.
  • streaming completions — llm.complete() is request/response.
  • multi-turn conversation — every call is fresh, stateless.