@affectively/slash-commands 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,390 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Slash Command Types
5
+ *
6
+ * Shared type definitions for slash commands across CLI, web, and chat interfaces.
7
+ * These types enable auto-generation of commands from Zod schemas.
8
+ */
9
+
10
+ /**
11
+ * Subscription tier (can be extended by consumers)
12
+ */
13
+ type SubscriptionTier = 'free' | 'premium' | 'ultra-premium' | 'enterprise' | string;
14
+ /**
15
+ * Parameter definition extracted from Zod schema
16
+ */
17
+ interface SlashCommandParameter {
18
+ /** Parameter name */
19
+ name: string;
20
+ /** Parameter type (string, number, boolean, enum, array, object) */
21
+ type: 'string' | 'number' | 'boolean' | 'enum' | 'array' | 'object';
22
+ /** Human-readable description from Zod .describe() */
23
+ description: string;
24
+ /** Whether this parameter is required */
25
+ required: boolean;
26
+ /** Default value if any */
27
+ defaultValue?: unknown;
28
+ /** Enum values if type is 'enum' */
29
+ enumValues?: string[];
30
+ /** CLI flag aliases (e.g., ['-c', '--category']) */
31
+ aliases?: string[];
32
+ }
33
+ /**
34
+ * Slash command definition generated from tool definition
35
+ */
36
+ interface SlashCommandDefinition {
37
+ /** Command name without slash (e.g., 'behaviors_list') */
38
+ name: string;
39
+ /** Human-readable description */
40
+ description: string;
41
+ /** Zod schema for input validation */
42
+ schema: z.ZodType;
43
+ /** Category for grouping (extracted from name prefix, e.g., 'behaviors') */
44
+ category: string;
45
+ /** Subscription tier required */
46
+ requiredTier: SubscriptionTier;
47
+ /** Parsed parameters from schema */
48
+ parameters: SlashCommandParameter[];
49
+ /** Optional command aliases (e.g., ['bl', 'list-behaviors']) */
50
+ aliases?: string[];
51
+ /** Generated help text from schema and description */
52
+ helpText: string;
53
+ /** Example usage strings */
54
+ examples: string[];
55
+ /** Whether this command is hidden from help/autocomplete */
56
+ hidden?: boolean;
57
+ }
58
+ /**
59
+ * Parsed slash command from user input
60
+ */
61
+ interface SlashCommandParsed {
62
+ /** Resolved command name */
63
+ command: string;
64
+ /** Parsed and validated arguments */
65
+ args: Record<string, unknown>;
66
+ /** Original raw input string */
67
+ raw: string;
68
+ /** Whether the command was found in registry */
69
+ found: boolean;
70
+ /** Validation errors if any */
71
+ errors?: string[];
72
+ /** Matched command definition (if found) */
73
+ definition?: SlashCommandDefinition;
74
+ }
75
+ /**
76
+ * Result from executing a slash command
77
+ */
78
+ interface SlashCommandResult {
79
+ /** Whether execution succeeded */
80
+ success: boolean;
81
+ /** Result data (JSON-serializable) */
82
+ data?: unknown;
83
+ /** Error message if failed */
84
+ error?: string;
85
+ /** Execution time in milliseconds */
86
+ executionTimeMs: number;
87
+ /** Command that was executed */
88
+ command: string;
89
+ /** Arguments that were used */
90
+ args: Record<string, unknown>;
91
+ }
92
+ /**
93
+ * Autocomplete suggestion for slash commands
94
+ */
95
+ interface SlashCommandSuggestion {
96
+ /** Full command name */
97
+ command: string;
98
+ /** Display text for UI (may include formatting) */
99
+ displayText: string;
100
+ /** Short description */
101
+ description: string;
102
+ /** Match score (0-100, higher is better match) */
103
+ matchScore?: number;
104
+ /** Category for grouping in UI */
105
+ category: string;
106
+ /** Whether user has access based on subscription */
107
+ hasAccess: boolean;
108
+ /** Required subscription tier for this command */
109
+ requiredTier?: SubscriptionTier;
110
+ }
111
+ /**
112
+ * Tool definition (input to generator)
113
+ */
114
+ interface ToolDefinition {
115
+ /** Tool name (snake_case) */
116
+ name: string;
117
+ /** Tool description */
118
+ description: string;
119
+ /** Zod schema or JSON schema for input */
120
+ inputSchema: z.ZodType | Record<string, unknown>;
121
+ /** Required subscription tier */
122
+ requiredTier?: SubscriptionTier;
123
+ }
124
+ /**
125
+ * Options for the slash command parser
126
+ */
127
+ interface SlashCommandParserOptions {
128
+ /** Whether to allow unknown arguments (default: false) */
129
+ allowUnknownArgs?: boolean;
130
+ /** Whether to coerce types (default: true) */
131
+ coerceTypes?: boolean;
132
+ /** Custom argument separator (default: ' ') */
133
+ argSeparator?: string;
134
+ }
135
+ /**
136
+ * Options for autocomplete
137
+ */
138
+ interface SlashCommandAutocompleteOptions {
139
+ /** Maximum suggestions to return (default: 10) */
140
+ maxSuggestions?: number;
141
+ /** User's subscription tier for filtering */
142
+ userTier?: SubscriptionTier;
143
+ /** Include hidden commands */
144
+ includeHidden?: boolean;
145
+ /** Minimum match score threshold (0-100, default: 0) */
146
+ minScore?: number;
147
+ }
148
+ /**
149
+ * Execution context for slash commands
150
+ */
151
+ interface SlashCommandContext {
152
+ /** User ID (for auth/tracking) */
153
+ userId?: string;
154
+ /** User's subscription tier */
155
+ userTier: SubscriptionTier;
156
+ /** API base URL for remote execution */
157
+ apiBaseUrl: string;
158
+ /** Auth token for API calls */
159
+ authToken?: string;
160
+ /** Conversation ID (for chat context) */
161
+ conversationId?: string;
162
+ /** Whether running in CLI mode */
163
+ isCLI?: boolean;
164
+ }
165
+
166
+ /**
167
+ * Slash Command Generator
168
+ *
169
+ * Converts tool definitions with Zod schemas into SlashCommandDefinitions.
170
+ * This enables auto-generation of CLI commands and web slash commands from
171
+ * a single source of truth (tool definitions).
172
+ */
173
+
174
+ /**
175
+ * Extract category from tool name (prefix before first underscore)
176
+ */
177
+ declare function extractCategory(toolName: string): string;
178
+ /**
179
+ * Extract parameters from a Zod schema
180
+ */
181
+ declare function extractParametersFromZod(schema: z.ZodType): SlashCommandParameter[];
182
+ /**
183
+ * Generate help text from command definition
184
+ */
185
+ declare function generateHelpText(name: string, description: string, parameters: SlashCommandParameter[]): string;
186
+ /**
187
+ * Generate example usage strings
188
+ */
189
+ declare function generateExamples(name: string, parameters: SlashCommandParameter[]): string[];
190
+ /**
191
+ * Generate a SlashCommandDefinition from a tool definition
192
+ */
193
+ declare function generateSlashCommand(tool: ToolDefinition, tierOverride?: SubscriptionTier): SlashCommandDefinition;
194
+ /**
195
+ * Extract parameters from JSON Schema (for tools using inline schema instead of Zod)
196
+ */
197
+ declare function extractParametersFromJsonSchema(jsonSchema: Record<string, unknown>): SlashCommandParameter[];
198
+ /**
199
+ * Generate multiple SlashCommandDefinitions from an array of tools
200
+ */
201
+ declare function generateSlashCommands(tools: ToolDefinition[]): SlashCommandDefinition[];
202
+ /**
203
+ * Generate command aliases (shorter versions of command names)
204
+ */
205
+ declare function generateAliases(name: string): string[];
206
+
207
+ /**
208
+ * Slash Command Parser
209
+ *
210
+ * Parses user input in the form `/command arg1=value1 arg2=value2`
211
+ * Supports both snake_case commands and hierarchical syntax (e.g., `/behaviors list`)
212
+ */
213
+
214
+ /**
215
+ * Check if input starts with a slash command
216
+ */
217
+ declare function isSlashCommand(input: string): boolean;
218
+ /**
219
+ * Extract the command name from input (before arguments)
220
+ */
221
+ declare function extractCommandName(input: string): string;
222
+ /**
223
+ * Parse slash command input into structured form
224
+ *
225
+ * Supports:
226
+ * - `/command` - command with no args
227
+ * - `/command arg1=value1` - command with named args
228
+ * - `/command arg1="value with spaces"` - quoted values
229
+ * - `/command arg1='value with spaces'` - single-quoted values
230
+ * - `/command --arg1=value1` - CLI-style flags
231
+ * - `/command -a value1` - Short flags with space
232
+ * - `/domain subcommand` - Hierarchical commands (converted to domain_subcommand)
233
+ */
234
+ declare function parseSlashCommand(input: string, registry?: Map<string, SlashCommandDefinition>, options?: SlashCommandParserOptions): SlashCommandParsed;
235
+ /**
236
+ * Format a command invocation for display
237
+ */
238
+ declare function formatCommand(command: string, args: Record<string, unknown>): string;
239
+ /**
240
+ * Get partial command info for autocomplete (before user finishes typing)
241
+ */
242
+ declare function getPartialCommand(input: string): {
243
+ command: string;
244
+ isComplete: boolean;
245
+ partialArg?: string;
246
+ };
247
+
248
+ /**
249
+ * Slash Command Registry
250
+ *
251
+ * Central registry for all slash commands. Commands are generated from tool
252
+ * definitions and can be registered either statically or dynamically.
253
+ *
254
+ * Usage:
255
+ * - CLI: Import and use the singleton registry
256
+ * - Web: Build registry from fetched tool definitions
257
+ */
258
+
259
+ /**
260
+ * Slash Command Registry
261
+ *
262
+ * Stores and manages all registered slash commands with support for:
263
+ * - Command lookup by name or alias
264
+ * - Category-based filtering
265
+ * - Subscription tier filtering
266
+ * - Alias resolution
267
+ */
268
+ declare class SlashCommandRegistry {
269
+ private commands;
270
+ private aliases;
271
+ private categories;
272
+ /**
273
+ * Register a single slash command
274
+ */
275
+ register(command: SlashCommandDefinition): void;
276
+ /**
277
+ * Register multiple commands at once
278
+ */
279
+ registerAll(commands: SlashCommandDefinition[]): void;
280
+ /**
281
+ * Register commands from tool definitions
282
+ */
283
+ registerFromTools(tools: ToolDefinition[]): void;
284
+ /**
285
+ * Get a command by name or alias
286
+ */
287
+ get(nameOrAlias: string): SlashCommandDefinition | undefined;
288
+ /**
289
+ * Check if a command exists
290
+ */
291
+ has(nameOrAlias: string): boolean;
292
+ /**
293
+ * Get all registered commands
294
+ */
295
+ getAll(): SlashCommandDefinition[];
296
+ /**
297
+ * Get commands filtered by category
298
+ */
299
+ getByCategory(category: string): SlashCommandDefinition[];
300
+ /**
301
+ * Get commands available for a subscription tier
302
+ */
303
+ getForTier(tier: SubscriptionTier): SlashCommandDefinition[];
304
+ /**
305
+ * Get all categories
306
+ */
307
+ getCategories(): string[];
308
+ /**
309
+ * Get command count by category
310
+ */
311
+ getCountByCategory(): Record<string, number>;
312
+ /**
313
+ * Resolve an alias to the canonical command name
314
+ */
315
+ resolveAlias(alias: string): string | undefined;
316
+ /**
317
+ * Get the underlying Map for direct access
318
+ */
319
+ getMap(): Map<string, SlashCommandDefinition>;
320
+ /**
321
+ * Clear all registered commands
322
+ */
323
+ clear(): void;
324
+ /**
325
+ * Get total command count
326
+ */
327
+ get size(): number;
328
+ }
329
+ /**
330
+ * Global singleton registry instance
331
+ */
332
+ declare const slashCommandRegistry: SlashCommandRegistry;
333
+ /**
334
+ * Execute a slash command
335
+ *
336
+ * @param input - Raw input string (e.g., "/behaviors_list limit=10")
337
+ * @param context - Execution context with auth and API info
338
+ * @param executor - Function to execute the command (API call, local handler, etc.)
339
+ */
340
+ declare function executeSlashCommand(input: string, context: SlashCommandContext, executor: (command: string, args: Record<string, unknown>, context: SlashCommandContext) => Promise<unknown>): Promise<SlashCommandResult>;
341
+ /**
342
+ * Create an API-based command executor
343
+ */
344
+ declare function createAPIExecutor(apiBaseUrl: string, authToken?: string): (command: string, args: Record<string, unknown>, context: SlashCommandContext) => Promise<unknown>;
345
+ /**
346
+ * Export helper to get all commands as an array (useful for CLI help)
347
+ */
348
+ declare function getAllSlashCommands(): SlashCommandDefinition[];
349
+ /**
350
+ * Export helper to get a specific command
351
+ */
352
+ declare function getSlashCommand(name: string): SlashCommandDefinition | undefined;
353
+ /**
354
+ * Export helper to check if a command exists
355
+ */
356
+ declare function hasSlashCommand(name: string): boolean;
357
+
358
+ /**
359
+ * Slash Command Autocomplete
360
+ *
361
+ * Provides fuzzy matching and suggestion generation for slash commands.
362
+ * Used by both CLI tab-completion and web chat autocomplete UI.
363
+ */
364
+
365
+ /**
366
+ * Calculate fuzzy match score between query and target
367
+ * Returns 0-100, higher is better match
368
+ */
369
+ declare function fuzzyMatch(query: string, target: string): number;
370
+ /**
371
+ * Get autocomplete suggestions for a partial input
372
+ */
373
+ declare function getAutocompleteSuggestions(input: string, options?: SlashCommandAutocompleteOptions, registry?: SlashCommandRegistry): SlashCommandSuggestion[];
374
+ /**
375
+ * Get suggestions grouped by category
376
+ */
377
+ declare function getSuggestionsGroupedByCategory(input: string, options?: SlashCommandAutocompleteOptions, registry?: SlashCommandRegistry): Record<string, SlashCommandSuggestion[]>;
378
+ /**
379
+ * Check if input should trigger autocomplete
380
+ */
381
+ declare function shouldShowAutocomplete(input: string): boolean;
382
+ /**
383
+ * Get the text to replace when selecting a suggestion
384
+ */
385
+ declare function getReplacementRange(input: string): {
386
+ start: number;
387
+ end: number;
388
+ };
389
+
390
+ export { type SlashCommandAutocompleteOptions, type SlashCommandContext, type SlashCommandDefinition, type SlashCommandParameter, type SlashCommandParsed, type SlashCommandParserOptions, SlashCommandRegistry, type SlashCommandResult, type SlashCommandSuggestion, type SubscriptionTier, type ToolDefinition, createAPIExecutor, executeSlashCommand, extractCategory, extractCommandName, extractParametersFromJsonSchema, extractParametersFromZod, formatCommand, fuzzyMatch, generateAliases, generateExamples, generateHelpText, generateSlashCommand, generateSlashCommands, getAllSlashCommands, getAutocompleteSuggestions, getPartialCommand, getReplacementRange, getSlashCommand, getSuggestionsGroupedByCategory, hasSlashCommand, isSlashCommand, parseSlashCommand, shouldShowAutocomplete, slashCommandRegistry };