Core foundation for slash command packages - provides interfaces, types, and utilities for building slash commands
npm install @bernierllc/slash-commands-coreCore foundation package for building slash command packages. Provides types, utilities, and base classes following the validator pattern for MECE slash command architecture.
``bash`
npm install @bernierllc/slash-commands-core
- Type Safety - Complete TypeScript definitions for slash commands
- Base Classes - Abstract base class for consistent command packages
- Validation - Built-in argument parsing and validation with Zod
- Multi-platform - Support for in-app, Slack, Discord, Teams platforms
- Rate Limiting - Built-in rate limiting utilities
- Permission System - Role-based command permissions
- NeverHub Integration - Service discovery and event system support
`typescript
import { SlashCommandPackage, SlashCommandSpec, SlashCommandContext, SlashCommandResponse, z } from '@bernierllc/slash-commands-core';
export class MyCommandsPackage extends SlashCommandPackage {
readonly packageName = '@my-org/my-commands';
readonly version = '1.0.0';
readonly description = 'My custom slash commands';
readonly commands: Record
'hello': {
name: 'hello',
description: 'Say hello to someone',
usage: '
examples: ['/hello John', '/hello @user'],
arguments: [{
name: 'name',
description: 'Name to greet',
required: true,
type: 'string',
schema: z.string().min(1).max(50)
}],
requiresAuth: false,
platforms: ['in-app', 'slack', 'discord']
}
};
async initialize(): Promise
// Register command handlers
this.handlers.set('hello', this.handleHello.bind(this));
}
private async handleHello(
context: SlashCommandContext,
args: Record
): Promise
const name = args.name as string;
return {
success: true,
message: Hello, ${name}! 👋,Hello, ${name}! 👋
formatting: {
markdown: ,Hello, ${name}!
plainText: `
}
};
}
}
`typescript
import { NeverHubAdapter } from '@bernierllc/neverhub-adapter';
export class NeverHubCommandPackage extends SlashCommandPackage {
private neverhub?: NeverHubAdapter;
async initialize(): Promise
// Initialize command handlers first
await super.initialize();
// Setup NeverHub integration
if (await NeverHubAdapter.detect()) {
this.neverhub = new NeverHubAdapter();
await this.neverhub.register({
type: 'slash-commands-tasks',
name: this.packageName,
version: this.version,
capabilities: [{
type: 'slash-commands',
name: 'task-management',
commands: Object.keys(this.commands),
version: this.version
}]
});
// Listen for command execution events
await this.neverhub.subscribe('slash-command.execute', async (event) => {
if (this.commands[event.data.command]) {
const response = await this.execute(event.data);
await this.neverhub!.publishEvent({
type: 'slash-command.response',
data: {
commandId: event.data.commandId,
response,
userId: event.data.userId
}
});
}
});
}
}
}
`
typescript
interface SlashCommandContext {
commandId: string; // Unique execution ID
command: string; // Command name (without /)
args: string[]; // Raw arguments
userId: string; // User who executed
platform: string; // Platform (in-app, slack, etc.)
conversationId?: string; // Channel/conversation ID
metadata?: Record; // Platform-specific data
timestamp: Date; // Execution timestamp
}
`$3
`typescript
interface SlashCommandResponse {
success: boolean; // Execution success
message?: string; // User-facing message
data?: any; // Structured response data
error?: string; // Error message if failed
formatting?: { // Platform-specific formatting
markdown?: string;
plainText?: string;
platform?: Record;
};
ephemeral?: boolean; // Private response flag
}
`$3
`typescript
interface SlashCommandSpec {
name: string; // Command name
description: string; // Human-readable description
usage?: string; // Usage syntax
examples?: string[]; // Usage examples
aliases?: string[]; // Alternative names
arguments?: SlashCommandArgument[]; // Expected arguments
requiresAuth?: boolean; // Authentication required
minRole?: string; // Minimum role required
adminOnly?: boolean; // Admin-only command
platforms?: string[]; // Supported platforms
category?: string; // Help category
enabled?: boolean; // Default enabled state
}
`Utilities
$3
`typescript
import { parseCommandString, createCommandContext } from '@bernierllc/slash-commands-core';const { command, args } = parseCommandString('/hello world');
// command: "hello", args: ["world"]
const context = createCommandContext('/hello world', 'user123', 'in-app');
`$3
`typescript
import { createSuccessResponse, createErrorResponse } from '@bernierllc/slash-commands-core';// Success response
const success = createSuccessResponse('Task created successfully', { id: '123' });
// Error response
const error = createErrorResponse('Task not found', true);
`$3
`typescript
import { validateCommandArgs, isValidCommandName, z } from '@bernierllc/slash-commands-core';// Validate command name
const valid = isValidCommandName('my-command'); // true
const invalid = isValidCommandName('My Command'); // false
// Validate arguments with Zod
const schema = z.object({
title: z.string().min(1),
priority: z.enum(['low', 'medium', 'high'])
});
`$3
`typescript
import { CommandRateLimiter } from '@bernierllc/slash-commands-core';const limiter = new CommandRateLimiter(10, 60000); // 10 requests per minute
if (!limiter.isAllowed(userId)) {
const remaining = limiter.getRemainingRequests(userId);
const resetTime = limiter.getTimeUntilReset(userId);
// Handle rate limit exceeded
}
`$3
`typescript
import { formatResponseForPlatform, escapeForPlatform } from '@bernierllc/slash-commands-core';const response = {
success: true,
message: 'Default message',
formatting: {
markdown: 'Bold message',
plainText: 'Bold message'
}
};
const slackFormatted = formatResponseForPlatform(response, 'slack');
const escaped = escapeForPlatform('Special chars', 'discord');
`Architecture Pattern
The slash-commands-core follows the validator pattern used throughout BernierLLC packages:
1. Core Package (
@bernierllc/slash-commands-core) - Provides foundation types and utilities
2. Specific Packages (@bernierllc/slash-commands-tasks, etc.) - Implement specific commands
3. Suite Integration - In-app-chat suite orchestrates command routing via NeverHub$3
- Mutually Exclusive - Each command package handles distinct functionality
- Collectively Exhaustive - All command needs covered by the ecosystem
- Service Discovery - Commands auto-register when packages come online
- Graceful Degradation - Works without optional command packages
Integration with In-App Chat
Commands automatically integrate with
@bernierllc/in-app-chat when both packages are available:1. Command packages register with NeverHub
2. In-app-chat discovers available commands
3. Users can execute commands across platforms (in-app, Slack, Discord, Teams)
4. Responses are formatted appropriately for each platform
Development Workflow
$3
`bash
mkdir my-commands-package
cd my-commands-package
npm init
npm install @bernierllc/slash-commands-core
`$3
Extend SlashCommandPackage and implement your commands following the examples above.$3
`typescript
const package = new MyCommandsPackage();
await package.initialize();const context = createCommandContext('/hello world', 'user123', 'in-app');
const response = await package.execute(context);
``- @bernierllc/in-app-chat - Main chat suite that orchestrates commands
- @bernierllc/neverhub-adapter - Service discovery and events
- @bernierllc/slash-commands-tasks - Example task management commands
Copyright (c) 2025 Bernier LLC. All rights reserved.