npm package: @juleswhite/promptable
Description: Tiny framework for building self-documenting, LLM-friendly npm packages
Author: Jules White
Latest version: 1.0.2

# @juleswhite/promptable

> Tiny framework for building self-documenting, LLM-friendly npm packages

[![npm version](https://img.shields.io/npm/v/@juleswhite/promptable.svg)](https://www.npmjs.com/package/@juleswhite/promptable)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## What is a Promptable Package?

A **promptable package** is an npm package designed for seamless interaction with Large Language Models (LLMs). It provides self-documenting CLI commands via `npx` that output structured, context-sized documentation optimized for LLM consumption.

**Key Features:**
- ✅ Self-documenting via `npx` executable
- ✅ Output sized for LLM context windows (≤2000 lines per command)
- ✅ Progressive navigation with next-step suggestions
- ✅ Universal `--llm` flag for LLM discoverability
- ✅ Zero dependencies, ~200 lines of code

## Installation

```bash
npm install @juleswhite/promptable
```

## Quick Start

### 1. Create your CLI executable (`bin/cli.js`):

```javascript
#!/usr/bin/env node

import { createPromptable, printHeader } from '@juleswhite/promptable';

const cli = createPromptable({
  title: 'My Package',
  subtitle: 'A great package',
  docsDir: './docs',
  packageCommand: 'npx my-package'
});

// Add --llm command (required for promptable standard)
cli.addCommand('--llm', (cli) => {
  printHeader(cli.config.title, cli.config.subtitle);
  console.log('Welcome to my package!\n');
  cli.printCommandList();
}, {
  description: 'Getting started (default)',
  aliases: ['--start']
});

// Add help command
cli.addCommand('--help', cli.createHelpCommand(), {
  description: 'Show all commands',
  aliases: ['-h']
});

// Add markdown-based documentation command
cli.addCommand('--guide',
  cli.createMarkdownCommand('GUIDE.md', 'Getting Started'),
  { description: 'Usage guide' }
);

cli.run();
```

### 2. Configure package.json:

```json
{
  "name": "my-package",
  "type": "module",
  "bin": "./bin/cli.js",
  "files": ["bin", "docs"],
  "dependencies": {
    "@juleswhite/promptable": "^1.0.0"
  }
}
```

**Important:** Use the string form `"bin": "./bin/cli.js"` to automatically create a binary matching your package name. This ensures `npx my-package --llm` works correctly.

### 3. Test it:

```bash
chmod +x bin/cli.js
npm link
npx my-package --llm
```

## The `--llm` Standard

**All promptable packages MUST respond to the `--llm` flag:**

```bash
npx your-package --llm
```

This convention allows LLMs to automatically discover and navigate your package's documentation.

## API Reference

### `createPromptable(config)`

Creates a new PromptableCLI instance.

**Config:**
- `title: string` - Main title for headers
- `subtitle: string` - Subtitle for headers
- `docsDir: string` - Path to markdown documentation
- `packageCommand: string` - Base command for navigation (e.g., "npx my-package")

### PromptableCLI Methods

#### `.addCommand(name, handler, options)`

Add a new command to the CLI.

- `name: string` - Command name (e.g., '--colors')
- `handler: Function` - Command handler `(cli) => {}`
- `options.description: string` - Command description
- `options.aliases: string[]` - Array of command aliases

#### `.run(args?)`

Execute the CLI. Defaults to `process.argv.slice(2)`.

#### `.printCommandList()`

Print all available commands with descriptions.

### Helper Functions

#### `printHeader(title, subtitle?)`

Print a colored header with separator lines.

#### `printSection(title, content?)`

Print a section with colored title and separator.

#### `printNextStep(message, command)`

Print a next-step suggestion with highlighted command.

#### `colorize(text, color)`

Colorize text with ANSI codes.

**Available colors:** `cyan`, `blue`, `green`, `yellow`, `magenta`, `red`, `gray`, `bright`, `dim`

#### `readMarkdown(docsDir, filename)`

Read a markdown file from the docs directory.

#### `extractSection(content, sectionTitle)`

Extract a section from markdown content by heading title.

### Command Builder Methods

#### `.createHelpCommand()`

Creates a standard help command that lists all available commands.

#### `.createMarkdownCommand(filename, sectionTitle, nextStep?)`

Creates a command that extracts and displays a markdown section.

**Parameters:**
- `filename: string` - Markdown file name
- `sectionTitle: string` - Section heading to extract
- `nextStep?: { message: string, command: string }` - Next step suggestion

#### `.createFullDocCommand(filename)`

Creates a command that outputs an entire markdown file.

## Complete Example

```javascript
#!/usr/bin/env node

import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import {
  createPromptable,
  printHeader,
  printSection,
  colorize
} from '@juleswhite/promptable';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const docsDir = join(__dirname, '..', 'docs');

const cli = createPromptable({
  title: '🎨 My Design System',
  subtitle: 'Beautiful, accessible components',
  docsDir,
  packageCommand: 'npx my-design-system'
});

// Required: --llm entry point
cli.addCommand('--llm', (cli) => {
  printHeader(cli.config.title, cli.config.subtitle);

  printSection('🚀 Quick Start', `
    ${colorize('1.', 'yellow')} Install: ${colorize('npm install my-design-system', 'bright')}
    ${colorize('2.', 'yellow')} Import: ${colorize('import { Button } from "my-design-system"', 'bright')}
    ${colorize('3.', 'yellow')} Use: ${colorize('<Button>Click me</Button>', 'bright')}
  `);

  cli.printCommandList();
}, {
  description: 'Getting started guide (default)',
  aliases: ['--start', '--get-started']
});

// Help command
cli.addCommand('--help', cli.createHelpCommand(), {
  aliases: ['-h']
});

// Documentation from markdown
cli.addCommand('--colors',
  cli.createMarkdownCommand('GUIDE.md', 'Color System', {
    message: 'Learn about components:',
    command: 'npx my-design-system --components'
  }),
  { description: 'Color palette and usage' }
);

cli.addCommand('--components',
  cli.createMarkdownCommand('GUIDE.md', 'Components'),
  { description: 'Available components' }
);

// Full docs
cli.addCommand('--full',
  cli.createFullDocCommand('GUIDE.md'),
  { description: 'Complete documentation (large)' }
);

cli.run();
```

## Why Promptable Packages?

Traditional documentation has issues for LLM-assisted development:

1. **Too Large** - Full docs exceed LLM context windows
2. **Poor Navigation** - No clear path from A → B → C
3. **Not Queryable** - Can't ask "just show me X"
4. **Static** - Doesn't adapt to user's learning path

Promptable packages solve this by:

1. **Chunking intelligently** - Each command outputs a focused topic
2. **Guiding navigation** - Each output suggests the next logical step
3. **Being queryable** - `npx package --topic` gets exactly what you need
4. **Adapting** - Users choose their own path through the knowledge
5. **Being paste-friendly** - Clean output perfect for LLM prompts

## Learn More

Explore the full specification and examples:

```bash
npx @juleswhite/promptable --llm          # Getting started
npx @juleswhite/promptable --standard     # The --llm flag convention
npx @juleswhite/promptable --patterns     # Integration patterns
npx @juleswhite/promptable --api          # API reference
npx @juleswhite/promptable --example      # Complete example
npx @juleswhite/promptable --full         # Full specification
```

## Real-World Examples

- [@majkapp/plugin-ui](https://www.npmjs.com/package/@majkapp/plugin-ui) - UI component library with aesthetic documentation

## Contributing

Issues and PRs welcome! Please ensure your package follows the promptable package standard.

## License

MIT © Jules White