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

pi-st-ejs

v0.1.0

Published

SillyTavern EJS template engine for pi — ported from ST-Prompt-Template

Readme

pi-st-ejs

SillyTavern EJS template engine for pi. Ported from ST-Prompt-Template — provides the full variable API, worldbook functions, and synchronous EJS template evaluation that SillyTavern worldbooks expect.

Install

npm install pi-st-ejs

Requires Node.js >= 22.19.0.

Quick start

import {
  objectStore, createVariableState, precacheVariables,
  createWorldInfoStore, parseDecorators,
  prepareContext, evalTemplate,
} from "pi-st-ejs";

// 1. Create a variable store backed by your runtime state
const state = objectStore(runtimeState);
const vars = createVariableState(state);
precacheVariables(vars);

// 2. Load worldbook entries from ST JSON
const entries = worldbookEntries.map(e => {
  const [decorators, cleanContent] = parseDecorators(e.content);
  return { ...e, content: cleanContent };
});
const worldInfo = createWorldInfoStore(entries);

// 3. Build the EJS execution context
const ctx = prepareContext(vars, {
  messages: chatHistory,
  worldInfoStore: worldInfo,
  activated: new Set(),
  customVars: {},
  messageText: lastMessage,
  ctxText: fullContext,
  renderFn: (content, extraData) =>
    evalTemplate(content, { ...ctx, ...extraData }),
});

// 4. Render templates (synchronous)
const result = evalTemplate(templateString, ctx);

API

Variable store

| Function | ST equivalent | |----------|---------------| | objectStore(root) | Creates a StateStore from a plain object | | createVariableState(store) | Initializes the variable system | | precacheVariables(vs) | Merges global + initial + local + cache scopes |

Variable API (EJS context)

| Function | Description | |----------|-------------| | getvar(path, opts?) | Read a variable; default scope = cache | | setvar(path, value, opts?) | Write a variable; supports nx (no-overwrite) | | incvar(path, amount?, opts?) | Increment a numeric variable | | decvar(path, amount?, opts?) | Decrement a numeric variable | | delvar(path, opts?) | Delete a variable | | insvar(path, value, position?) | Insert into an array variable | | variables | Accessor for the merged cache tree |

Worldbook API

| Function | Description | |----------|-------------| | getwi(title, data?) | Get entry content by title; data passed as extra EJS context | | activewi(title) | Check if entry is activated | | getEnabledWorldInfoEntries() | List all enabled entries | | parseDecorators(content) | Strip @@preprocessing / @@activate / @@dont_activate decorators | | createWorldInfoStore(entries) | Build a worldbook store from entry array |

Chat API (EJS context)

| Function | Description | |----------|-------------| | getChatMessages() | All messages as string[] | | getChatMessages(n) | Last n messages | | getChatMessages(start, end) | Slice by index (negative = from end) | | getChatMessages(start, end, role) | Slice filtered by role | | getChatMessage(idx) | Single message; negative index from end | | matchChatMessages(pattern, and?) | Regex or substring match |

EJS context extras

| Name | Description | |------|-------------| | _ | Lodash shim: _.get, _.set, _.has, _.merge, _.cloneDeep, _.isArray, _.toArray, _.concat | | define(name, value, merge?) | Define a persistent variable (SharedDefines) | | getAllVariables() | Returns { stat_data: cacheVars } | | getVariables(opts?) | Same as getAllVariables | | findVariables(query) | Returns [] (pi has no per-message variable tracking) | | messageText | Current message text | | ctxText | Full context text |

Template evaluation

| Function | Description | |----------|-------------| | evalTemplate(template, ctx) | Synchronous EJS render | | hasEjsSyntax(text) | Check if string contains EJS tags |

EJS syntax

Standard EJS with ST conventions:

  • <% / <%_ / <%= / <%- — code, trim-start, escaped output, raw output
  • await getwi(...)await is stripped before evaluation (ST convention)
  • print(...) — available as outputFunctionName (not in context to avoid shadowing)

ST decorators

Worldbook entries in ST JSON may have decorators in their content:

| Decorator | Behavior | |-----------|----------| | @@preprocessing | Stripped; EJS runs before keyword matching in ST | | @@activate | Emitted by preprocessing to force-activate entry | | @@dont_activate | Emitted by preprocessing to suppress entry |

parseDecorators(content) returns [decorators, cleanContent].

License

MIT