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

pre-claude

v0.0.2

Published

🐍 TUI for building structured prompts for Claude

Readme

pre-claude

ζ—₯本θͺžη‰ˆ

"pre"-claude is a TUI tool for efficiently creating complex prompts with structured forms for Claude Code.

Define templates in TypeScript config files to share with your team and enable reproducible prompt workflows.

Works seamlessly with your existing Claude Code setup including MCP and Skills.

Concepts

Scenario

Defines a document type (e.g., design doc, meeting notes). Configure prompt templates and output destinations.

Step

Each page of the form wizard. Group related fields together for easier input.

| Scenario Selection | Form Input | Preview | |:---:|:---:|:---:| | select | edit | preview |

Requirements

  • Node.js 18+
  • Claude Code

Installation

npm install pre-claude

Usage

# Try the example
npx pre-claude example
npx pre-claude example --lang ja

# Create a config file
npx pre-claude init

# Run the TUI
npx pre-claude run --config ./pre-claude.config.ts

See examples/ for configuration examples.

Screens

The TUI consists of 3 screens.

Scenario Selection Screen

A 2-pane screen displayed at startup. Select a scenario in the left pane, then choose to create new or edit an existing document in the right pane.

select

| Key | Action | |-----|--------| | ↑↓ / j/k | Navigate items | | β†’ / l / Enter | Select / Move to right pane | | ← / h / Esc | Move to left pane | | q | Quit |

Form Input Screen

A 3-panel layout with step tabs at the top, field list on the left, and editing area on the right.

edit

| Key | Action | |-----|--------| | ←→ / h/l | Navigate steps | | ↑↓ / j/k | Navigate fields | | Enter | Start editing / Confirm | | Esc | Cancel | | n / p | Next / Previous step | | d | Delete repeatable item | | g | Generate preview | | q | Go back |

Preview Screen

AI generates the document and displays the result with streaming.

preview

| Key | Action | |-----|--------| | ↑↓ / j/k | Scroll | | r | Regenerate | | s | Save | | c | Continue in Claude Code | | i | Show formData / aiContext | | Esc / q | Go back |

Press c to continue the conversation in Claude Code, inheriting the current session.

Configuration

Basic Structure

import { defineConfig, defineScenario, type Step } from 'pre-claude';

const steps = [
  {
    slug: 'overview',
    title: 'Overview',
    description: 'Basic project information',
    name: 'overview',
    fields: [
      {
        id: 'title',
        type: 'input',
        label: 'Title',
        description: 'Project name',
        required: true,
      },
    ],
  },
] as const satisfies Step[];

export default defineConfig({
  scenarios: [
    defineScenario({
      id: 'design-doc',
      name: 'Design Document',
      steps,
      prompt: ({ formData, aiContext }) =>
        `Create a design document based on:\n${JSON.stringify({ formData, aiContext }, null, 2)}`,
      outputDir: './docs',
    }),
  ],
});

Scenario

| Property | Type | Required | Description | |----------|------|:--------:|-------------| | id | string | β—‹ | Unique identifier | | name | string | β—‹ | Display name | | steps | Step[] | β—‹ | Form wizard steps | | prompt | (params) => string | β—‹ | Prompt generator function | | outputDir | string | | Output directory | | filename | string \| function | | Filename |

The prompt function receives the following arguments. You can view the actual values by pressing i on the preview screen.

formData

An object containing the values entered in the form.

{
  [stepName: string]: {
    [fieldId: string]: string | boolean | Array<{ [fieldId: string]: string | boolean }>
  }
}

Example:

{
  "overview": {
    "title": "My Project",
    "priority": "high"
  },
  "features": {
    "items": [
      { "name": "Feature 1", "desc": "Description 1" },
      { "name": "Feature 2", "desc": "Description 2" }
    ]
  }
}

aiContext

Metadata such as field labels and descriptions. Helps the AI understand the meaning of each field.

{
  [stepName: string]: {
    _step: { title: string; description: string };
    [fieldId: string]: { label: string; description: string }
  }
}

Example:

{
  "overview": {
    "_step": { "title": "Overview", "description": "Basic project information" },
    "title": { "label": "Title", "description": "Project name" },
    "priority": { "label": "Priority", "description": "Select priority" }
  }
}

Step

| Property | Type | Description | |----------|------|-------------| | slug | string | URL-friendly identifier | | title | string | Title | | description | string | Description | | name | string | Key name in formData | | fields | Field[] | Field array |

Field Types

input

{
  id: 'title',
  type: 'input',
  label: 'Title',
  description: 'Description',
  placeholder: 'Placeholder',
  required: true,
  inputType: 'text', // 'text' | 'date' | 'url'
  suggestions: ['Option 1', 'Option 2'], // Autocomplete
  default: 'Default value',
}

textarea

{
  id: 'description',
  type: 'textarea',
  label: 'Description',
  description: 'Detailed description',
  rows: 5,
}

select

{
  id: 'priority',
  type: 'select',
  label: 'Priority',
  description: 'Select priority',
  options: [
    { value: 'low', label: 'Low' },
    { value: 'medium', label: 'Medium' },
    { value: 'high', label: 'High' },
  ],
  default: 'medium',
}

checkbox

{
  id: 'agree',
  type: 'checkbox',
  label: 'I agree',
  description: 'Agreement to terms',
  required: true,
}

Layouts

repeatable

A repeatable field that can be dynamically added or removed.

{
  type: 'repeatable',
  id: 'features',
  label: 'Features',
  minCount: 1,
  defaultCount: 2,
  field: {
    type: 'group',
    fields: [
      { id: 'name', type: 'input', label: 'Name', description: '' },
      { id: 'desc', type: 'textarea', label: 'Description', description: '', rows: 2 },
    ],
  },
}

formData becomes an array:

{
  features: [
    { name: 'Feature 1', desc: 'Description 1' },
    { name: 'Feature 2', desc: 'Description 2' },
  ]
}

group

Groups multiple fields together. Used within repeatable.

Conditional Display

Use the when property to specify display conditions for fields.

// Simple conditions
{ ..., when: { field: 'priority', is: 'high' } }
{ ..., when: { field: 'priority', is: ['high', 'medium'] } }
{ ..., when: { field: 'priority', isNot: 'low' } }
{ ..., when: { field: 'title', isNotEmpty: true } }
{ ..., when: { field: 'notes', isEmpty: true } }

// AND condition
{
  ...,
  when: {
    and: [
      { field: 'priority', is: 'high' },
      { field: 'type', is: 'feature' }
    ]
  }
}

// OR condition
{
  ...,
  when: {
    or: [
      { field: 'priority', is: 'high' },
      { field: 'type', is: 'urgent' }
    ]
  }
}

// Reference fields from other steps
{ ..., when: { field: 'overview.priority', is: 'high' } }

Type Safety

Using defineScenario with as const satisfies Step[] enables type inference for formData.

const scenario = defineScenario({
  id: 'my-scenario',
  name: 'My Scenario',
  steps,
  prompt: ({ formData }) => {
    // formData.overview?.title is string | undefined
    return `Title: ${formData.overview?.title ?? 'Untitled'}`;
  },
  filename: ({ formData, timestamp }) =>
    `${formData.overview?.title ?? 'untitled'}-${timestamp}.md`,
});

License

MIT