Skip to content

🐍 TUI for building structured prompts for Claude

Notifications You must be signed in to change notification settings

cut0/pre-claude

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

22 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

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

About

🐍 TUI for building structured prompts for Claude

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •