@affectively/slash-commands
v1.0.0
Published
Slash command parser with Zod schema integration. Auto-generates commands from Zod schemas with autocomplete, validation, and type coercion for CLI and chat interfaces.
Maintainers
Readme
@affectively/slash-commands
Slash command parser with Zod schema integration. Auto-generates commands from Zod schemas with autocomplete, validation, and type coercion for CLI and chat interfaces.
Features
- Zod Integration - Generate commands directly from Zod schemas
- Type Coercion - Automatically convert strings to numbers, booleans, arrays
- Autocomplete - Fuzzy matching suggestions for commands and arguments
- Validation - Validate arguments against schema with detailed errors
- Subscription Tiers - Built-in support for tiered command access
- Aliases - Auto-generated aliases (kebab-case, acronyms)
- Flexible Syntax - Supports
key=value,--key=value,--key value,-k
Installation
npm install @affectively/slash-commands zod
# or
bun add @affectively/slash-commands zod
# or
yarn add @affectively/slash-commands zodQuick Start
import {
slashCommandRegistry,
parseSlashCommand,
getAutocompleteSuggestions,
} from '@affectively/slash-commands';
import { z } from 'zod';
// Register commands from tool definitions
slashCommandRegistry.registerFromTools([
{
name: 'users_list',
description: 'List users with optional filtering',
inputSchema: z.object({
role: z.enum(['admin', 'user', 'guest']).optional().describe('Filter by role'),
limit: z.number().default(10).describe('Maximum results'),
active: z.boolean().optional().describe('Only active users'),
}),
requiredTier: 'free',
},
{
name: 'users_create',
description: 'Create a new user',
inputSchema: z.object({
email: z.string().describe('User email address'),
name: z.string().describe('Display name'),
role: z.enum(['admin', 'user', 'guest']).default('user'),
}),
requiredTier: 'premium',
},
]);
// Parse user input
const parsed = parseSlashCommand('/users_list limit=20 role=admin');
console.log(parsed);
// {
// command: 'users_list',
// args: { limit: 20, role: 'admin' },
// found: true,
// errors: undefined
// }
// Get autocomplete suggestions
const suggestions = getAutocompleteSuggestions('/us', { userTier: 'premium' });
console.log(suggestions);
// [
// { command: 'users_list', displayText: '/users_list', ... },
// { command: 'users_create', displayText: '/users_create', ... }
// ]Supported Syntax
# Basic command
/command
# Named arguments
/command arg1=value1 arg2=value2
# Quoted values (for spaces)
/command name="John Doe"
# CLI-style flags
/command --limit=10 --active
# Short flags
/command -l 10 -a
# Boolean flags
/command --active
# Hierarchical commands (auto-converted)
/users list → users_listType Coercion
Arguments are automatically coerced to appropriate types:
parseSlashCommand('/cmd num=42'); // { num: 42 } (number)
parseSlashCommand('/cmd flag=true'); // { flag: true } (boolean)
parseSlashCommand('/cmd arr=[1,2,3]'); // { arr: [1,2,3] } (array)
parseSlashCommand('/cmd obj={"a":1}'); // { obj: { a: 1 } } (object)Registry API
import { slashCommandRegistry } from '@affectively/slash-commands';
// Register a single command
slashCommandRegistry.register(commandDefinition);
// Register multiple commands
slashCommandRegistry.registerAll([cmd1, cmd2]);
// Register from tool definitions (with Zod schemas)
slashCommandRegistry.registerFromTools(tools);
// Get command by name or alias
const cmd = slashCommandRegistry.get('users_list');
const cmd = slashCommandRegistry.get('ul'); // Auto-generated alias
// Filter by category
const userCommands = slashCommandRegistry.getByCategory('users');
// Filter by subscription tier
const freeCommands = slashCommandRegistry.getForTier('free');
// Get all categories
const categories = slashCommandRegistry.getCategories();Autocomplete
import {
getAutocompleteSuggestions,
getSuggestionsGroupedByCategory,
shouldShowAutocomplete,
fuzzyMatch,
} from '@affectively/slash-commands';
// Get suggestions for partial input
const suggestions = getAutocompleteSuggestions('/us', {
userTier: 'premium',
maxSuggestions: 10,
includeHidden: false,
minScore: 30,
});
// Group by category for UI
const grouped = getSuggestionsGroupedByCategory('/us', { userTier: 'premium' });
// { users: [...], utilities: [...] }
// Check if autocomplete should show
if (shouldShowAutocomplete(input)) {
// Show autocomplete UI
}
// Test fuzzy match score
const score = fuzzyMatch('ul', 'users_list'); // 80+ (initials match)Command Execution
import { executeSlashCommand, createAPIExecutor } from '@affectively/slash-commands';
// Execute with custom executor
const result = await executeSlashCommand(
'/users_list limit=10',
{
userTier: 'premium',
apiBaseUrl: 'https://api.example.com',
authToken: 'bearer-token',
},
async (command, args, context) => {
// Your execution logic here
return await fetch(`/api/${command}`, {
method: 'POST',
body: JSON.stringify(args),
});
}
);
// Or use the built-in API executor
const apiExecutor = createAPIExecutor('https://api.example.com', 'auth-token');
const result = await executeSlashCommand('/users_list', context, apiExecutor);Generating Commands
import { generateSlashCommand, generateSlashCommands } from '@affectively/slash-commands';
import { z } from 'zod';
const command = generateSlashCommand({
name: 'search',
description: 'Search for items',
inputSchema: z.object({
query: z.string().describe('Search query'),
page: z.number().default(1),
}),
});
console.log(command.helpText);
// /search
//
// Search for items
//
// Parameters:
// query <string> (required)
// Search query
// page <number> (optional) (default: 1)
console.log(command.examples);
// ['/search', '/search query="example"']Subscription Tiers
// Commands can require specific subscription tiers
const command = generateSlashCommand({
name: 'premium_feature',
description: 'A premium feature',
inputSchema: z.object({}),
requiredTier: 'premium',
});
// Filter available commands by tier
const available = slashCommandRegistry.getForTier('free');
// Autocomplete respects tiers (shows but marks inaccessible)
const suggestions = getAutocompleteSuggestions('/pre', { userTier: 'free' });
// Returns suggestion with hasAccess: falseAPI Reference
Parser
parseSlashCommand(input, registry?, options?)- Parse input into command and argsisSlashCommand(input)- Check if input starts with /extractCommandName(input)- Get command name from inputformatCommand(command, args)- Format command for displaygetPartialCommand(input)- Get partial command info for autocomplete
Registry
SlashCommandRegistry- Main registry classslashCommandRegistry- Global singleton instanceexecuteSlashCommand(input, context, executor)- Execute a commandcreateAPIExecutor(baseUrl, token?)- Create API-based executor
Generator
generateSlashCommand(tool)- Generate command from tool definitiongenerateSlashCommands(tools)- Generate multiple commandsextractParametersFromZod(schema)- Extract params from Zod schemaextractParametersFromJsonSchema(schema)- Extract params from JSON schema
Autocomplete
getAutocompleteSuggestions(input, options?, registry?)- Get suggestionsgetSuggestionsGroupedByCategory(input, options?, registry?)- Grouped suggestionsshouldShowAutocomplete(input)- Check if autocomplete should showfuzzyMatch(query, target)- Calculate match score (0-100)
License
MIT © AFFECTIVELY
