@@ -15,6 +15,7 @@ import { useLoginStore } from '../state/login-store'
1515import { capturePendingAttachments } from '../utils/pending-attachments'
1616import { AGENT_MODES } from '../utils/constants'
1717import { getSystemMessage , getUserMessage } from '../utils/message-history'
18+ import { getSkillByName } from '../utils/skill-registry'
1819
1920import type { MultilineInputHandle } from '../components/multiline-input'
2021import type { InputValue , PendingAttachment } from '../state/chat-store'
@@ -490,7 +491,77 @@ export const COMMAND_REGISTRY: CommandDefinition[] = [
490491
491492export function findCommand ( cmd : string ) : CommandDefinition | undefined {
492493 const lowerCmd = cmd . toLowerCase ( )
493- return COMMAND_REGISTRY . find (
494+
495+ // First check the static command registry
496+ const staticCommand = COMMAND_REGISTRY . find (
494497 ( def ) => def . name === lowerCmd || def . aliases . includes ( lowerCmd ) ,
495498 )
499+ if ( staticCommand ) {
500+ return staticCommand
501+ }
502+
503+ // Check if this is a skill command
504+ const skill = getSkillByName ( lowerCmd )
505+ if ( skill ) {
506+ return createSkillCommand ( skill . name )
507+ }
508+
509+ return undefined
510+ }
511+
512+ /**
513+ * Creates a dynamic command definition for a skill.
514+ * When invoked, the skill's content is sent to the agent.
515+ */
516+ function createSkillCommand ( skillName : string ) : CommandDefinition {
517+ return defineCommandWithArgs ( {
518+ name : skillName ,
519+ handler : ( params , args ) => {
520+ const skill = getSkillByName ( skillName )
521+ if ( ! skill ) {
522+ params . setMessages ( ( prev ) => [
523+ ...prev ,
524+ getUserMessage ( params . inputValue . trim ( ) ) ,
525+ getSystemMessage ( `Skill not found: ${ skillName } ` ) ,
526+ ] )
527+ params . saveToHistory ( params . inputValue . trim ( ) )
528+ params . setInputValue ( { text : '' , cursorPosition : 0 , lastEditDueToNav : false } )
529+ return
530+ }
531+
532+ const trimmed = params . inputValue . trim ( )
533+ params . saveToHistory ( trimmed )
534+ params . setInputValue ( { text : '' , cursorPosition : 0 , lastEditDueToNav : false } )
535+
536+ // Build the message content with skill context and optional user args
537+ const skillContext = `<skill name="${ skill . name } ">
538+ ${ skill . content }
539+ </skill>`
540+
541+ const userPrompt = args . trim ( )
542+ ? `${ skillContext } \n\nUser request: ${ args . trim ( ) } `
543+ : `${ skillContext } \n\nPlease use this skill to help me.`
544+
545+ // Check streaming/queue state
546+ if (
547+ params . isStreaming ||
548+ params . streamMessageIdRef . current ||
549+ params . isChainInProgressRef . current
550+ ) {
551+ const pendingAttachments = capturePendingAttachments ( )
552+ params . addToQueue ( userPrompt , pendingAttachments )
553+ params . setInputFocused ( true )
554+ params . inputRef . current ?. focus ( )
555+ return
556+ }
557+
558+ params . sendMessage ( {
559+ content : userPrompt ,
560+ agentMode : params . agentMode ,
561+ } )
562+ setTimeout ( ( ) => {
563+ params . scrollToLatest ( )
564+ } , 0 )
565+ } ,
566+ } )
496567}
0 commit comments