Prompt Snapshot banner
swarmclawai swarmclawai

Prompt Snapshot

Development community

Description

Vitest-for-prompts. File-based prompt eval runner with snapshots and assertions — no SaaS, no dashboard, CI-native. Built for agents.

Installation

This entry records only its repository, not the path inside it, so there is no exact command to give. Open the source below and copy the folder into ~/.claude/skills/, or the file into ~/.claude/agents/.

README

prompt-snapshot

Vitest-for-prompts. A file-based prompt eval runner with snapshots and assertions. No dashboard, no SaaS, no sign-up — just `.prompt.ts` files in your repo and a CLI that runs them in CI.

[![npm version](https://img.shields.io/npm/v/@swarmclawai/prompt-snapshot.svg)](https://www.npmjs.com/package/@swarmclawai/prompt-snapshot) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE) [![CI](https://github.com/swarmclawai/prompt-snapshot/actions/workflows/ci.yml/badge.svg)](https://github.com/swarmclawai/prompt-snapshot/actions/workflows/ci.yml)

Why this exists

If you ship any LLM feature, you should be testing your prompts the way you test your code — in CI, on every change. The existing options (Langfuse, DeepEval, Phoenix, Promptfoo) are heavy observability platforms shaped for enterprise teams: SDK init, hosted dashboards, sign-ups, YAML configs, whole new abstractions to learn.

A solo dev or small team wants this instead:

  • Colocated .prompt.ts files next to the code that uses the prompt.
  • A TypeScript-native API with types, autocomplete, and Zod schemas.
  • Snapshot testing — run a prompt, capture the output, fail the build if it drifts.
  • Deterministic assertions (contains, matchesSchema, …) for the parts that matter.
  • One CLI, JSON output, stable exit codes — CI-friendly on day one.

That's what `prompt-snapshot` is.

30-second demo

Create `summarizer.prompt.ts`:

import { defineSuite, contains, shorterThan } from "@swarmclawai/prompt-snapshot";

export default defineSuite({
  name: "summarizer",
  model: { provider: "anthropic", model: "claude-haiku-4-5", temperature: 0 },
  prompt: ({ doc }: { doc: string }) =>
    `Summarize the following in one sentence.\n\n${doc}`,
  cases: [
    {
      name: "short-doc",
      input: { doc: "The cat sat on the mat. The dog watched from across the room." },
      assertions: [contains("cat", { caseInsensitive: true }), shorterThan(300)],
      snapshot: