UNPKG

jay-code

Version:

Streamlined AI CLI orchestration engine with mathematical rigor and enterprise-grade reliability

571 lines (511 loc) 21.3 kB
/** * Shell completion generator for Jay-Code CLI */ import chalk from 'chalk'; import { promises as fs } from 'node:fs'; export class CompletionGenerator { private commands = [ 'start', 'agent', 'task', 'memory', 'config', 'status', 'monitor', 'session', 'workflow', 'repl', 'version', 'completion', ]; private subcommands = { agent: ['spawn', 'list', 'terminate', 'info'], task: ['create', 'list', 'status', 'cancel', 'workflow'], memory: ['query', 'export', 'import', 'stats', 'cleanup'], config: ['show', 'get', 'set', 'init', 'validate'], session: ['list', 'save', 'restore', 'delete', 'export', 'import', 'info', 'clean'], workflow: ['run', 'validate', 'list', 'status', 'stop', 'template'], }; async generate(shell: string, install: boolean = false): Promise<void> { const detectedShell = shell === 'detect' ? await this.detectShell() : shell; switch (detectedShell) { case 'bash': await this.generateBashCompletion(install); break; case 'zsh': await this.generateZshCompletion(install); break; case 'fish': await this.generateFishCompletion(install); break; default: console.error(chalk.red(`Unsupported shell: ${detectedShell}`)); console.log(chalk.gray('Supported shells: bash, zsh, fish')); break; } } private async detectShell(): Promise<string> { const shell = process.env['SHELL'] || ''; if (shell.includes('bash')) return 'bash'; if (shell.includes('zsh')) return 'zsh'; if (shell.includes('fish')) return 'fish'; console.log(chalk.yellow('Could not detect shell, defaulting to bash')); return 'bash'; } private async generateBashCompletion(install: boolean): Promise<void> { const script = this.getBashCompletionScript(); if (install) { await this.installBashCompletion(script); } else { console.log(script); } } private async generateZshCompletion(install: boolean): Promise<void> { const script = this.getZshCompletionScript(); if (install) { await this.installZshCompletion(script); } else { console.log(script); } } private async generateFishCompletion(install: boolean): Promise<void> { const script = this.getFishCompletionScript(); if (install) { await this.installFishCompletion(script); } else { console.log(script); } } private getBashCompletionScript(): string { return `# Jay-Code bash completion _claude_flow_completion() { local cur prev words cword _init_completion || return case \${words[1]} in agent) case \${words[2]} in spawn) COMPREPLY=($(compgen -W "coordinator researcher implementer analyst custom" -- "$cur")) return ;; terminate|info) # In production, this would complete with actual agent IDs COMPREPLY=($(compgen -W "agent-001 agent-002 agent-003" -- "$cur")) return ;; *) COMPREPLY=($(compgen -W "${this.subcommands.agent.join(' ')}" -- "$cur")) return ;; esac ;; task) case \${words[2]} in create) if [[ \${#words[@]} -eq 4 ]]; then COMPREPLY=($(compgen -W "research implementation analysis coordination" -- "$cur")) fi return ;; status|cancel) # In production, this would complete with actual task IDs COMPREPLY=($(compgen -W "task-001 task-002 task-003" -- "$cur")) return ;; workflow) COMPREPLY=($(compgen -f -X '!*.@(json|yaml|yml)' -- "$cur")) return ;; *) COMPREPLY=($(compgen -W "${this.subcommands.task.join(' ')}" -- "$cur")) return ;; esac ;; memory) COMPREPLY=($(compgen -W "${this.subcommands.memory.join(' ')}" -- "$cur")) return ;; config) COMPREPLY=($(compgen -W "${this.subcommands.config.join(' ')}" -- "$cur")) return ;; session) case \${words[2]} in restore|delete|info|export) # In production, this would complete with actual session IDs COMPREPLY=($(compgen -W "session-001 session-002 session-003" -- "$cur")) return ;; import) COMPREPLY=($(compgen -f -X '!*.@(json|yaml|yml)' -- "$cur")) return ;; *) COMPREPLY=($(compgen -W "${this.subcommands.session.join(' ')}" -- "$cur")) return ;; esac ;; workflow) case \${words[2]} in run|validate) COMPREPLY=($(compgen -f -X '!*.@(json|yaml|yml)' -- "$cur")) return ;; template) COMPREPLY=($(compgen -W "research implementation coordination" -- "$cur")) return ;; status|stop) # In production, this would complete with actual workflow IDs COMPREPLY=($(compgen -W "workflow-001 workflow-002 workflow-003" -- "$cur")) return ;; *) COMPREPLY=($(compgen -W "${this.subcommands.workflow.join(' ')}" -- "$cur")) return ;; esac ;; completion) COMPREPLY=($(compgen -W "bash zsh fish" -- "$cur")) return ;; *) COMPREPLY=($(compgen -W "${this.commands.join(' ')}" -- "$cur")) return ;; esac } complete -F _claude_flow_completion jay-code`; } private getZshCompletionScript(): string { return `#compdef jay-code # Jay-Code zsh completion _claude_flow() { local context state state_descr line typeset -A opt_args _arguments -C \\ '(-h --help)'{-h,--help}'[Show help information]' \\ '(-v --verbose)'{-v,--verbose}'[Enable verbose logging]' \\ '(-q --quiet)'{-q,--quiet}'[Suppress non-essential output]' \\ '(-c --config)'{-c,--config}'[Path to configuration file]:config file:_files -g "*.json"' \\ '--log-level[Set log level]:level:(debug info warn error)' \\ '--no-color[Disable colored output]' \\ '--json[Output in JSON format]' \\ '--profile[Use named configuration profile]:profile:' \\ '1: :_claude_flow_commands' \\ '*::arg:->args' case $state in args) case $words[1] in agent) _claude_flow_agent ;; task) _claude_flow_task ;; memory) _claude_flow_memory ;; config) _claude_flow_config ;; session) _claude_flow_session ;; workflow) _claude_flow_workflow ;; completion) _arguments \\ '--install[Install completion script automatically]' \\ '1: :(bash zsh fish)' ;; esac ;; esac } _claude_flow_commands() { local commands commands=( 'start:Start the Jay-Code orchestration system' 'agent:Manage Jay-Code agents' 'task:Manage tasks' 'memory:Manage agent memory' 'config:Manage Jay-Code configuration' 'status:Show Jay-Code system status' 'monitor:Start live monitoring dashboard' 'session:Manage Jay-Code sessions' 'workflow:Execute and manage workflows' 'repl:Start interactive REPL mode' 'version:Show detailed version information' 'completion:Generate shell completion scripts' ) _describe 'commands' commands } _claude_flow_agent() { case $words[2] in spawn) _arguments \\ '(-n --name)'{-n,--name}'[Agent name]:name:' \\ '(-p --priority)'{-p,--priority}'[Agent priority]:priority:' \\ '(-m --max-tasks)'{-m,--max-tasks}'[Maximum concurrent tasks]:max:' \\ '--system-prompt[Custom system prompt]:prompt:' \\ '1: :(coordinator researcher implementer analyst custom)' ;; terminate|info) _arguments '1: :_claude_flow_agents' ;; *) _arguments '1: :(${this.subcommands.agent.join(' ')})' ;; esac } _claude_flow_task() { case $words[2] in create) _arguments \\ '(-p --priority)'{-p,--priority}'[Task priority]:priority:' \\ '(-d --dependencies)'{-d,--dependencies}'[Comma-separated dependency task IDs]:deps:' \\ '(-i --input)'{-i,--input}'[Task input as JSON]:input:' \\ '(-a --assign)'{-a,--assign}'[Assign to specific agent]:agent:_claude_flow_agents' \\ '1: :(research implementation analysis coordination)' \\ '2: :_message_or_description' ;; workflow) _arguments '1: :_files -g "*.json *.yaml *.yml"' ;; status|cancel) _arguments '1: :_claude_flow_tasks' ;; *) _arguments '1: :(${this.subcommands.task.join(' ')})' ;; esac } _claude_flow_memory() { _arguments '1: :(${this.subcommands.memory.join(' ')})' } _claude_flow_config() { _arguments '1: :(${this.subcommands.config.join(' ')})' } _claude_flow_session() { case $words[2] in restore|delete|info|export) _arguments '1: :_claude_flow_sessions' ;; import) _arguments '1: :_files -g "*.json *.yaml *.yml"' ;; *) _arguments '1: :(${this.subcommands.session.join(' ')})' ;; esac } _claude_flow_workflow() { case $words[2] in run|validate) _arguments '1: :_files -g "*.json *.yaml *.yml"' ;; template) _arguments '1: :(research implementation coordination)' ;; status|stop) _arguments '1: :_claude_flow_workflows' ;; *) _arguments '1: :(${this.subcommands.workflow.join(' ')})' ;; esac } # Helper functions for completion _claude_flow_agents() { # In production, this would query the running orchestrator local agents agents=('agent-001:Coordinator Agent' 'agent-002:Research Agent' 'agent-003:Implementation Agent') _describe 'agents' agents } _claude_flow_tasks() { # In production, this would query the running orchestrator local tasks tasks=('task-001:Research Task' 'task-002:Analysis Task' 'task-003:Implementation Task') _describe 'tasks' tasks } _claude_flow_sessions() { # In production, this would query saved sessions local sessions sessions=('session-001:Research Session' 'session-002:Development Session' 'session-003:Analysis Session') _describe 'sessions' sessions } _claude_flow_workflows() { # In production, this would query running workflows local workflows workflows=('workflow-001:Research Workflow' 'workflow-002:Implementation Workflow') _describe 'workflows' workflows } _message_or_description() { _message 'task description' } _claude_flow "$@"`; } private getFishCompletionScript(): string { return `# Jay-Code fish completion function __fish_claude_flow_needs_command set cmd (commandline -opc) if [ (count $cmd) -eq 1 ] return 0 end return 1 end function __fish_claude_flow_using_command set cmd (commandline -opc) if [ (count $cmd) -gt 1 ] if [ $argv[1] = $cmd[2] ] return 0 end end return 1 end # Main commands complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'start' -d 'Start the Jay-Code orchestration system' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'agent' -d 'Manage Jay-Code agents' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'task' -d 'Manage tasks' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'memory' -d 'Manage agent memory' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'config' -d 'Manage Jay-Code configuration' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'status' -d 'Show Jay-Code system status' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'monitor' -d 'Start live monitoring dashboard' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'session' -d 'Manage Jay-Code sessions' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'workflow' -d 'Execute and manage workflows' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'repl' -d 'Start interactive REPL mode' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'version' -d 'Show detailed version information' complete -f -c jay-code -n '__fish_claude_flow_needs_command' -a 'completion' -d 'Generate shell completion scripts' # Global options complete -c jay-code -s h -l help -d 'Show help information' complete -c jay-code -s v -l verbose -d 'Enable verbose logging' complete -c jay-code -s q -l quiet -d 'Suppress non-essential output' complete -c jay-code -s c -l config -r -d 'Path to configuration file' complete -c jay-code -l log-level -r -a 'debug info warn error' -d 'Set log level' complete -c jay-code -l no-color -d 'Disable colored output' complete -c jay-code -l json -d 'Output in JSON format' complete -c jay-code -l profile -r -d 'Use named configuration profile' # Agent subcommands complete -f -c jay-code -n '__fish_claude_flow_using_command agent' -a 'spawn' -d 'Spawn a new agent' complete -f -c jay-code -n '__fish_claude_flow_using_command agent' -a 'list' -d 'List all agents' complete -f -c jay-code -n '__fish_claude_flow_using_command agent' -a 'terminate' -d 'Terminate an agent' complete -f -c jay-code -n '__fish_claude_flow_using_command agent' -a 'info' -d 'Get agent information' # Task subcommands complete -f -c jay-code -n '__fish_claude_flow_using_command task' -a 'create' -d 'Create a new task' complete -f -c jay-code -n '__fish_claude_flow_using_command task' -a 'list' -d 'List all tasks' complete -f -c jay-code -n '__fish_claude_flow_using_command task' -a 'status' -d 'Get task status' complete -f -c jay-code -n '__fish_claude_flow_using_command task' -a 'cancel' -d 'Cancel a task' complete -f -c jay-code -n '__fish_claude_flow_using_command task' -a 'workflow' -d 'Execute workflow from file' # Memory subcommands complete -f -c jay-code -n '__fish_claude_flow_using_command memory' -a 'query' -d 'Query memory entries' complete -f -c jay-code -n '__fish_claude_flow_using_command memory' -a 'export' -d 'Export memory to file' complete -f -c jay-code -n '__fish_claude_flow_using_command memory' -a 'import' -d 'Import memory from file' complete -f -c jay-code -n '__fish_claude_flow_using_command memory' -a 'stats' -d 'Show memory statistics' complete -f -c jay-code -n '__fish_claude_flow_using_command memory' -a 'cleanup' -d 'Clean up old entries' # Config subcommands complete -f -c jay-code -n '__fish_claude_flow_using_command config' -a 'show' -d 'Show current configuration' complete -f -c jay-code -n '__fish_claude_flow_using_command config' -a 'get' -d 'Get specific config value' complete -f -c jay-code -n '__fish_claude_flow_using_command config' -a 'set' -d 'Set config value' complete -f -c jay-code -n '__fish_claude_flow_using_command config' -a 'init' -d 'Initialize config file' complete -f -c jay-code -n '__fish_claude_flow_using_command config' -a 'validate' -d 'Validate config file' # Session subcommands complete -f -c jay-code -n '__fish_claude_flow_using_command session' -a 'list' -d 'List all saved sessions' complete -f -c jay-code -n '__fish_claude_flow_using_command session' -a 'save' -d 'Save current session state' complete -f -c jay-code -n '__fish_claude_flow_using_command session' -a 'restore' -d 'Restore a saved session' complete -f -c jay-code -n '__fish_claude_flow_using_command session' -a 'delete' -d 'Delete a saved session' complete -f -c jay-code -n '__fish_claude_flow_using_command session' -a 'export' -d 'Export session to file' complete -f -c jay-code -n '__fish_claude_flow_using_command session' -a 'import' -d 'Import session from file' complete -f -c jay-code -n '__fish_claude_flow_using_command session' -a 'info' -d 'Show detailed session information' complete -f -c jay-code -n '__fish_claude_flow_using_command session' -a 'clean' -d 'Clean up old sessions' # Workflow subcommands complete -f -c jay-code -n '__fish_claude_flow_using_command workflow' -a 'run' -d 'Execute a workflow from file' complete -f -c jay-code -n '__fish_claude_flow_using_command workflow' -a 'validate' -d 'Validate a workflow file' complete -f -c jay-code -n '__fish_claude_flow_using_command workflow' -a 'list' -d 'List running workflows' complete -f -c jay-code -n '__fish_claude_flow_using_command workflow' -a 'status' -d 'Show workflow execution status' complete -f -c jay-code -n '__fish_claude_flow_using_command workflow' -a 'stop' -d 'Stop a running workflow' complete -f -c jay-code -n '__fish_claude_flow_using_command workflow' -a 'template' -d 'Generate workflow templates' # Completion subcommands complete -f -c jay-code -n '__fish_claude_flow_using_command completion' -a 'bash zsh fish'`; } private async installBashCompletion(script: string): Promise<void> { const possiblePaths = [ '/etc/bash_completion.d/jay-code', '/usr/local/etc/bash_completion.d/jay-code', `${process.env['HOME']}/.local/share/bash-completion/completions/jay-code`, `${process.env['HOME']}/.bash_completion.d/jay-code`, ]; for (const path of possiblePaths) { try { const dir = path.substring(0, path.lastIndexOf('/')); await Deno.mkdir(dir, { recursive: true }); await fs.writeFile(path, script); console.log(chalk.green('✓ Bash completion installed')); console.log(`${chalk.white('Location:')} ${path}`); console.log(chalk.gray('Restart your shell or run: source ~/.bashrc')); return; } catch (error) { // Try next path continue; } } console.error(chalk.red('Failed to install bash completion')); console.log( chalk.gray('You can manually save the completion script to a bash completion directory'), ); } private async installZshCompletion(script: string): Promise<void> { const possiblePaths = [ `${process.env['HOME']}/.zsh/completions/_jay-code`, '/usr/local/share/zsh/site-functions/_jay-code', '/usr/share/zsh/site-functions/_jay-code', ]; for (const path of possiblePaths) { try { const dir = path.substring(0, path.lastIndexOf('/')); await Deno.mkdir(dir, { recursive: true }); await fs.writeFile(path, script); console.log(chalk.green('✓ Zsh completion installed')); console.log(`${chalk.white('Location:')} ${path}`); console.log(chalk.gray('Restart your shell or run: autoload -U compinit && compinit')); return; } catch (error) { // Try next path continue; } } console.error(chalk.red('Failed to install zsh completion')); console.log( chalk.gray('You can manually save the completion script to your zsh completion directory'), ); } private async installFishCompletion(script: string): Promise<void> { const possiblePaths = [ `${process.env['HOME']}/.config/fish/completions/jay-code.fish`, '/usr/local/share/fish/completions/jay-code.fish', '/usr/share/fish/completions/jay-code.fish', ]; for (const path of possiblePaths) { try { const dir = path.substring(0, path.lastIndexOf('/')); await Deno.mkdir(dir, { recursive: true }); await fs.writeFile(path, script); console.log(chalk.green('✓ Fish completion installed')); console.log(`${chalk.white('Location:')} ${path}`); console.log(chalk.gray('Completions will be available in new fish sessions')); return; } catch (error) { // Try next path continue; } } console.error(chalk.red('Failed to install fish completion')); console.log( chalk.gray('You can manually save the completion script to your fish completion directory'), ); } }