centaurus-cli 3.1.2 → 3.1.4
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.
- package/dist/cli-adapter.js +689 -155
- package/dist/cli-adapter.js.map +1 -1
- package/dist/config/defaultConfig.js +1 -4
- package/dist/config/defaultConfig.js.map +1 -1
- package/dist/config/models.js +6 -0
- package/dist/config/models.js.map +1 -1
- package/dist/config/slash-commands.js +66 -2
- package/dist/config/slash-commands.js.map +1 -1
- package/dist/config/types.js +4 -4
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -1
- package/dist/services/ai-context-injector.js +109 -0
- package/dist/services/ai-context-injector.js.map +1 -1
- package/dist/services/ai-service-client.js +3 -2
- package/dist/services/ai-service-client.js.map +1 -1
- package/dist/services/api-client.js.map +1 -1
- package/dist/services/background-task-manager.js +59 -0
- package/dist/services/background-task-manager.js.map +1 -1
- package/dist/services/local-chat-storage.js +2 -0
- package/dist/services/local-chat-storage.js.map +1 -1
- package/dist/services/skill-storage.js +141 -0
- package/dist/services/skill-storage.js.map +1 -0
- package/dist/services/sub-agent-manager.js +49 -8
- package/dist/services/sub-agent-manager.js.map +1 -1
- package/dist/services/warpify-detector.js +17 -5
- package/dist/services/warpify-detector.js.map +1 -1
- package/dist/tools/background-command.js +5 -2
- package/dist/tools/background-command.js.map +1 -1
- package/dist/tools/command.js +367 -109
- package/dist/tools/command.js.map +1 -1
- package/dist/tools/file-ops.js +23 -6
- package/dist/tools/file-ops.js.map +1 -1
- package/dist/tools/plan-mode.js +184 -336
- package/dist/tools/plan-mode.js.map +1 -1
- package/dist/tools/sub-agent.js +24 -5
- package/dist/tools/sub-agent.js.map +1 -1
- package/dist/tools/todo-list.js +157 -0
- package/dist/tools/todo-list.js.map +1 -0
- package/dist/types/skill.js +30 -0
- package/dist/types/skill.js.map +1 -0
- package/dist/ui/components/App.js +956 -162
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/AuthScreen.js +3 -1
- package/dist/ui/components/AuthScreen.js.map +1 -1
- package/dist/ui/components/AuthWelcomeScreen.js +3 -1
- package/dist/ui/components/AuthWelcomeScreen.js.map +1 -1
- package/dist/ui/components/CodeBlock.js +3 -1
- package/dist/ui/components/CodeBlock.js.map +1 -1
- package/dist/ui/components/CompactShellPreview.js +44 -0
- package/dist/ui/components/CompactShellPreview.js.map +1 -0
- package/dist/ui/components/ConfigViewer.js +3 -1
- package/dist/ui/components/ConfigViewer.js.map +1 -1
- package/dist/ui/components/ConfirmPrompt.js +3 -1
- package/dist/ui/components/ConfirmPrompt.js.map +1 -1
- package/dist/ui/components/ConnectionStatusMessage.js +3 -1
- package/dist/ui/components/ConnectionStatusMessage.js.map +1 -1
- package/dist/ui/components/DetailedPlanReviewScreen.js +84 -74
- package/dist/ui/components/DetailedPlanReviewScreen.js.map +1 -1
- package/dist/ui/components/DiffViewer.js +6 -3
- package/dist/ui/components/DiffViewer.js.map +1 -1
- package/dist/ui/components/FileCreationPreview.js.map +1 -1
- package/dist/ui/components/FileTagAutocomplete.js +4 -2
- package/dist/ui/components/FileTagAutocomplete.js.map +1 -1
- package/dist/ui/components/InputBox.js +243 -40
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/InteractiveShell.js +5 -3
- package/dist/ui/components/InteractiveShell.js.map +1 -1
- package/dist/ui/components/KeyboardHelp.js +4 -1
- package/dist/ui/components/KeyboardHelp.js.map +1 -1
- package/dist/ui/components/LoadingIndicator.js +3 -1
- package/dist/ui/components/LoadingIndicator.js.map +1 -1
- package/dist/ui/components/MCPAddScreen.js +63 -13
- package/dist/ui/components/MCPAddScreen.js.map +1 -1
- package/dist/ui/components/MarkdownRenderer.js +3 -1
- package/dist/ui/components/MarkdownRenderer.js.map +1 -1
- package/dist/ui/components/MessageDisplay.js +9 -7
- package/dist/ui/components/MessageDisplay.js.map +1 -1
- package/dist/ui/components/ModelPicker.js +170 -0
- package/dist/ui/components/ModelPicker.js.map +1 -0
- package/dist/ui/components/MonitorModeAIPanel.js +3 -1
- package/dist/ui/components/MonitorModeAIPanel.js.map +1 -1
- package/dist/ui/components/PlanAcceptedMessage.js +12 -6
- package/dist/ui/components/PlanAcceptedMessage.js.map +1 -1
- package/dist/ui/components/PlanQuestionMessage.js +37 -0
- package/dist/ui/components/PlanQuestionMessage.js.map +1 -0
- package/dist/ui/components/PlanQuestionScreen.js +138 -0
- package/dist/ui/components/PlanQuestionScreen.js.map +1 -0
- package/dist/ui/components/PlanReviewScreen.js +7 -9
- package/dist/ui/components/PlanReviewScreen.js.map +1 -1
- package/dist/ui/components/RulesEditorScreen.js +65 -28
- package/dist/ui/components/RulesEditorScreen.js.map +1 -1
- package/dist/ui/components/SelectPrompt.js +3 -1
- package/dist/ui/components/SelectPrompt.js.map +1 -1
- package/dist/ui/components/SkillCreatorScreen.js +217 -0
- package/dist/ui/components/SkillCreatorScreen.js.map +1 -0
- package/dist/ui/components/SlashCommandAutocomplete.js +4 -2
- package/dist/ui/components/SlashCommandAutocomplete.js.map +1 -1
- package/dist/ui/components/StatusBar.js +4 -2
- package/dist/ui/components/StatusBar.js.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.js +5 -3
- package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
- package/dist/ui/components/SubAgentListScreen.js +65 -0
- package/dist/ui/components/SubAgentListScreen.js.map +1 -0
- package/dist/ui/components/SubAgentViewScreen.js +123 -0
- package/dist/ui/components/SubAgentViewScreen.js.map +1 -0
- package/dist/ui/components/TaskCompletedMessage.js +40 -8
- package/dist/ui/components/TaskCompletedMessage.js.map +1 -1
- package/dist/ui/components/TaskProgressIndicator.js +6 -4
- package/dist/ui/components/TaskProgressIndicator.js.map +1 -1
- package/dist/ui/components/TextEditor.js +297 -0
- package/dist/ui/components/TextEditor.js.map +1 -0
- package/dist/ui/components/TodoListMessage.js +59 -0
- package/dist/ui/components/TodoListMessage.js.map +1 -0
- package/dist/ui/components/ToolExecutionMessage.js +134 -84
- package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
- package/dist/ui/components/ToolExecutionStatus.js +3 -1
- package/dist/ui/components/ToolExecutionStatus.js.map +1 -1
- package/dist/ui/components/WelcomeBanner.js +33 -33
- package/dist/ui/components/WelcomeBanner.js.map +1 -1
- package/dist/ui/components/WorkflowCreatorScreen.js +5 -3
- package/dist/ui/components/WorkflowCreatorScreen.js.map +1 -1
- package/dist/ui/theme.js +97 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/ui/utils/chat-history-limit.js +247 -0
- package/dist/ui/utils/chat-history-limit.js.map +1 -0
- package/dist/utils/chat-formatter.js +22 -9
- package/dist/utils/chat-formatter.js.map +1 -1
- package/dist/utils/git-stats.js +7 -5
- package/dist/utils/git-stats.js.map +1 -1
- package/dist/utils/input-classifier.js +11 -1
- package/dist/utils/input-classifier.js.map +1 -1
- package/dist/utils/output-truncation.js +175 -0
- package/dist/utils/output-truncation.js.map +1 -0
- package/dist/utils/rule-reference-resolver.js +3 -3
- package/dist/utils/rule-reference-resolver.js.map +1 -1
- package/dist/utils/tunnel-commands-manager.js +134 -0
- package/dist/utils/tunnel-commands-manager.js.map +1 -0
- package/package.json +91 -90
- package/postinstall.js +4 -11
- package/dist/ui/components/MultiLineInput.js +0 -255
- package/dist/ui/components/MultiLineInput.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/input-classifier.ts"],"sourcesContent":["/**\r\n * Input Classification Utilities\r\n * \r\n * Provides intelligent heuristic-based detection of user intent (Terminal Command vs AI Message).\r\n * Uses sentence structure analysis, command syntax detection, and context-aware disambiguation.\r\n */\r\n\r\nimport { CustomCommandsManager } from './custom-commands-manager.js';\r\n\r\nexport type InputIntent = 'command' | 'ai';\r\n\r\n// Valid slash commands that should be handled by the Agent/CLI logic\r\nconst SLASH_COMMANDS = new Set([\r\n 'help', 'h', '?',\r\n 'model', 'm', 'models',\r\n 'config', 'c', 'settings',\r\n 'clear', 'cls', 'reset',\r\n 'sync',\r\n 'clean-ui', 'refresh-ui', 'redraw',\r\n 'exit', 'quit', 'q',\r\n 'session', 's',\r\n 'session-limits',\r\n 'tools', 't',\r\n 'plan',\r\n 'init', 'i',\r\n 'mcp',\r\n 'chat',\r\n 'docs',\r\n 'sign-in',\r\n 'logout',\r\n 'quality',\r\n 'autonomous',\r\n 'add-command', 'add-command-auto-detect',\r\n 'background-task', 'bkg', 'bg-task',\r\n 'copy-chat-context',\r\n 'workflow', 'wf',\r\n 'rules',\r\n 'revert'\r\n]);\r\n\r\n// Commands that are definitely terminal commands (not ambiguous with natural language)\r\nconst DEFINITE_COMMANDS = new Set([\r\n // Package Managers\r\n 'npm', 'yarn', 'pnpm', 'bun', 'npx', 'gem', 'pip', 'pip3', 'conda', 'cargo', 'composer', 'mvn', 'gradle',\r\n // Package managers (extended)\r\n 'apt', 'apt-get', 'apt-cache', 'dpkg', 'yum', 'dnf', 'rpm', 'zypper', 'pacman', 'emerge',\r\n 'port', 'brew', 'choco', 'scoop', 'winget', 'snap', 'flatpak', 'nix', 'nix-env', 'apk',\r\n // Version Control\r\n 'git', 'svn', 'hg', 'gh', 'gitk', 'tig',\r\n // File Operations (non-ambiguous)\r\n 'ls', 'cd', 'pwd', 'mkdir', 'rm', 'cp', 'mv', 'cat', 'less', 'more', 'chmod', 'chown', 'chgrp', 'ln',\r\n 'stat', 'file', 'realpath', 'basename', 'dirname', 'readlink', 'dd', 'truncate', 'shred', 'sync',\r\n 'mktemp', 'install', 'xargs', 'tee', 'touch',\r\n // Editors\r\n 'vim', 'nvim', 'vi', 'nano', 'emacs', 'micro', 'helix', 'hx', 'pico', 'joe', 'ne', 'mcedit', 'code',\r\n 'subl', 'atom', 'gedit', 'kate', 'notepad', 'notepad++',\r\n // System / Process\r\n 'ps', 'kill', 'killall', 'htop', 'btop', 'free', 'df', 'du', 'whoami', 'su', 'sudo',\r\n 'nice', 'renice', 'nohup', 'timeout', 'strace', 'ltrace', 'pgrep', 'pkill', 'fuser', 'pstree',\r\n // Network\r\n 'curl', 'wget', 'ssh', 'scp', 'ping', 'telnet', 'nc', 'netstat', 'lsof', 'dig', 'nslookup', 'ip', 'ifconfig', 'traceroute',\r\n 'arp', 'route', 'ss', 'tcpdump', 'nmap', 'iptables', 'ip6tables', 'firewall-cmd', 'ufw',\r\n 'socat', 'rsync', 'ftp', 'sftp', 'sshfs', 'rclone', 'mtr', 'host', 'whois',\r\n // Build / Run (non-ambiguous)\r\n 'cmake', 'docker', 'docker-compose', 'kubectl', 'python', 'python3', 'ruby', 'perl', 'php', 'java', 'gcc', 'g++', 'clang',\r\n 'javac', 'dotnet', 'mono', 'swift', 'swiftc', 'kotlinc', 'scalac', 'elixir', 'mix', 'iex',\r\n // Shell / Subshells\r\n 'echo', 'env', 'cal', 'printenv',\r\n 'wsl', 'bash', 'sh', 'zsh', 'fish', 'powershell', 'pwsh', 'cmd',\r\n 'ksh', 'csh', 'tcsh', 'ash', 'dash',\r\n // Shell built-ins (critical additions)\r\n 'exit', 'logout', 'return', 'break', 'continue',\r\n 'alias', 'unalias', 'builtin', 'command',\r\n 'exec', 'eval', 'declare', 'local', 'readonly',\r\n 'enable', 'disable', 'ulimit', 'umask', 'trap',\r\n 'jobs', 'fg', 'bg', 'disown', 'suspend', 'times',\r\n 'pushd', 'popd', 'dirs', 'cd', 'pwd',\r\n 'fc', 'bind', 'complete', 'compgen', 'compopt', 'shopt',\r\n 'history', 'clear', 'reset', 'tput', 'stty',\r\n // Session/User management\r\n 'login', 'newgrp', 'groups', 'id', 'users', 'finger', 'w', 'who', 'last', 'lastlog',\r\n 'useradd', 'userdel', 'usermod', 'passwd', 'chpasswd',\r\n 'groupadd', 'groupdel', 'groupmod', 'adduser', 'deluser',\r\n // Archives\r\n 'tar', 'zip', 'unzip', 'gzip', 'gunzip', '7z', 'rar', 'bzip2', 'bunzip2', 'xz', 'unxz', 'zstd',\r\n // Search (non-ambiguous)\r\n 'grep', 'egrep', 'fgrep', 'locate', 'sed', 'awk', 'gawk', 'ack', 'ag', 'rg', 'fd', 'fzf',\r\n // Text processing\r\n 'tr', 'wc', 'nl', 'uniq', 'rev', 'tac', 'hexdump', 'xxd', 'od', 'strings',\r\n 'expand', 'unexpand', 'column', 'colrm', 'csplit', 'pr', 'tsort', 'comm',\r\n // Misc\r\n 'jq', 'yq', 'crontab', 'visudo', 'vipw', 'sudoedit', 'at', 'batch',\r\n // Cloud / DevOps\r\n 'aws', 'az', 'gcloud', 'terraform', 'ansible', 'ansible-playbook', 'kubectl', 'helm', 'vagrant',\r\n 'pulumi', 'cdk', 'sam', 'serverless', 'flyctl', 'heroku', 'vercel', 'netlify',\r\n // Database\r\n 'mysql', 'psql', 'mongo', 'mongod', 'mongosh', 'redis-cli', 'sqlite3', 'pg_dump', 'mysqldump',\r\n // Web / Security\r\n 'openssl', 'certbot', 'nginx', 'apache2', 'httpd', 'gpg', 'ssh-keygen', 'ssh-agent', 'ssh-add',\r\n // Language runtimes (non-ambiguous)\r\n 'node', 'deno', 'ts-node', 'tsx', 'esbuild', 'webpack', 'vite', 'rollup', 'parcel',\r\n 'jest', 'vitest', 'mocha', 'pytest', 'phpunit', 'rspec',\r\n // Go\r\n 'go', 'gofmt', 'golint', 'gopls',\r\n // Rust\r\n 'rustc', 'rustup', 'rustfmt', 'clippy',\r\n // System info\r\n 'uname', 'hostname', 'uptime', 'arch', 'nproc', 'lscpu', 'lsblk', 'lsusb', 'lspci',\r\n 'dmidecode', 'dmesg', 'sysctl', 'modprobe', 'lsmod', 'insmod', 'rmmod',\r\n // Services/Daemons\r\n 'systemctl', 'service', 'journalctl', 'loginctl', 'chkconfig', 'update-rc.d', 'launchctl',\r\n // Disk/Storage\r\n 'mount', 'umount', 'fdisk', 'parted', 'mkfs', 'fsck', 'blkid', 'findmnt', 'quota', 'hdparm',\r\n // Windows-specific commands\r\n 'dir', 'copy', 'move', 'del', 'ren', 'rename', 'attrib', 'cls', 'md', 'rd', 'rmdir',\r\n 'xcopy', 'robocopy', 'icacls', 'cacls', 'takeown',\r\n 'tasklist', 'taskkill', 'systeminfo', 'ipconfig', 'netsh', 'pathping',\r\n 'reg', 'regedit', 'schtasks', 'wmic', 'where', 'findstr', 'fc', 'comp',\r\n 'chkdsk', 'sfc', 'dism', 'bcdedit', 'diskpart', 'format', 'label', 'vol',\r\n 'net', 'netstat', 'nbtstat', 'klist', 'gpresult', 'gpupdate', 'shutdown', 'logoff',\r\n // PowerShell aliases that look like commands\r\n 'gci', 'gc', 'sl', 'gi', 'gm', 'gwmi', 'iwr', 'irm',\r\n // Date/Time\r\n 'timedatectl', 'hwclock', 'ntpdate', 'chronyc',\r\n // Containers/Virtualization\r\n 'podman', 'crictl', 'ctr', 'nerdctl', 'lxc', 'lxd', 'virsh', 'vboxmanage', 'multipass', 'lima',\r\n // Kubernetes ecosystem\r\n 'k9s', 'kubectx', 'kubens', 'kustomize', 'skaffold', 'minikube', 'kind', 'k3s', 'k3d',\r\n // Misc utilities\r\n 'xdg-open', 'open', 'wslpath', 'cygpath', 'explorer', 'start',\r\n 'yes', 'seq', 'factor', 'bc', 'dc', 'expr',\r\n 'sleep', 'usleep', 'watch',\r\n // Common CLI tools\r\n 'ffmpeg', 'ffprobe', 'convert', 'identify', 'magick', 'pandoc', 'latex', 'pdflatex', 'bibtex',\r\n 'youtube-dl', 'yt-dlp', 'aria2c', 'axel',\r\n]);\r\n\r\n// Shell built-ins that work standalone or with simple arguments (exit codes, etc.)\r\n// These get special handling for disambiguation\r\nconst SHELL_BUILTINS = new Set([\r\n 'exit', 'logout', 'return', 'break', 'continue',\r\n 'jobs', 'fg', 'bg', 'wait', 'disown', 'suspend',\r\n 'pushd', 'popd', 'dirs',\r\n 'history', 'fc',\r\n 'pwd', 'hash', 'help', 'true', 'false',\r\n 'env', 'printenv', 'export', 'set', 'unset',\r\n 'alias', 'unalias', 'type', 'command', 'builtin',\r\n 'clear', 'reset', 'cls',\r\n]);\r\n\r\n// Commands that can also be natural language words - need disambiguation\r\nconst AMBIGUOUS_COMMANDS = new Set([\r\n 'which', 'make', 'find', 'head', 'tail',\r\n 'test', 'run', 'start', 'stop', 'top', 'man',\r\n 'date', 'time', 'source', 'tree', 'sort',\r\n 'diff', 'patch', 'split', 'join', 'cut', 'paste', 'fold', 'fmt',\r\n 'look', 'spell', 'read', 'print', 'say', 'write',\r\n 'mount', 'watch', 'locate', 'ping', 'host'\r\n]);\r\n\r\n// Natural language keywords that strongly indicate AI intent\r\nconst AI_KEYWORDS = new Set([\r\n // Question words\r\n 'how', 'what', 'why', 'when', 'where', 'who', 'whose', 'whom',\r\n // Action requests\r\n 'write', 'create', 'generate', 'implement', 'scaffold', 'design',\r\n 'explain', 'describe', 'clarify', 'analyze', 'review', 'audit',\r\n 'fix', 'debug', 'solve', 'correct', 'repair',\r\n 'optimize', 'improve', 'refactor', 'format',\r\n 'verify', 'validate',\r\n 'translate', 'convert', 'transform',\r\n 'summarize', 'document', 'comment',\r\n 'add', 'update', 'change', 'modify', 'remove', 'delete',\r\n // Modal verbs indicating requests\r\n 'can', 'could', 'would', 'should', 'shall', 'might', 'must',\r\n // Greetings and polite markers\r\n 'hey', 'hi', 'hello', 'help', 'please', 'thanks', 'thank',\r\n // Contextual\r\n 'show', 'tell', 'give', 'list', 'provide', 'suggest', 'recommend'\r\n]);\r\n\r\n// Words that indicate natural language sentence structure\r\nconst NATURAL_LANGUAGE_MARKERS = new Set([\r\n // Articles\r\n 'a', 'an', 'the',\r\n // Pronouns\r\n 'i', 'me', 'my', 'mine', 'you', 'your', 'yours', 'he', 'she', 'it', 'we', 'they',\r\n 'this', 'that', 'these', 'those',\r\n // Prepositions commonly used in requests\r\n 'for', 'with', 'about', 'from', 'into', 'through', 'during', 'before', 'after',\r\n // Conjunctions\r\n 'and', 'but', 'or', 'so', 'because', 'if', 'then', 'while',\r\n // Common verbs in questions/requests\r\n 'is', 'are', 'was', 'were', 'be', 'been', 'being',\r\n 'do', 'does', 'did', 'doing', 'done',\r\n 'have', 'has', 'had', 'having',\r\n 'get', 'got', 'getting',\r\n // Adverbs\r\n 'here', 'there', 'now', 'just', 'also', 'only', 'even', 'still', 'already'\r\n]);\r\n\r\n// Known command + subcommand patterns (command followed by valid subcommand)\r\nconst COMMAND_SUBCOMMANDS: Map<string, Set<string>> = new Map([\r\n ['git', new Set(['add', 'commit', 'push', 'pull', 'clone', 'checkout', 'branch', 'merge', 'rebase', 'reset', 'stash', 'log', 'diff', 'status', 'init', 'remote', 'fetch', 'tag', 'show', 'rm', 'mv', 'bisect', 'blame', 'cherry-pick', 'revert', 'clean', 'gc', 'reflog', 'worktree', 'submodule', 'config', 'help', 'version'])],\r\n ['npm', new Set(['install', 'i', 'uninstall', 'un', 'update', 'up', 'run', 'start', 'test', 'build', 'init', 'publish', 'pack', 'link', 'unlink', 'ls', 'list', 'outdated', 'audit', 'cache', 'config', 'help', 'version', 'ci', 'exec', 'create', 'set-script', 'pkg', 'dedupe', 'prune', 'shrinkwrap', 'adduser', 'login', 'logout', 'whoami', 'token', 'owner', 'access', 'team', 'deprecate', 'unpublish', 'dist-tag', 'view', 'search', 'doctor', 'explain', 'find-dupes', 'fund', 'hook', 'org', 'ping', 'prefix', 'profile', 'rebuild', 'repo', 'root', 'star', 'stars', 'unstar', 'bugs', 'docs', 'edit', 'explore'])],\r\n ['yarn', new Set(['add', 'remove', 'install', 'run', 'start', 'test', 'build', 'init', 'publish', 'link', 'unlink', 'list', 'outdated', 'audit', 'cache', 'config', 'help', 'version', 'upgrade', 'upgrade-interactive', 'why', 'workspaces', 'set', 'create', 'dlx', 'pack', 'dedupe', 'info'])],\r\n ['pnpm', new Set(['add', 'remove', 'install', 'i', 'run', 'start', 'test', 'build', 'init', 'publish', 'link', 'unlink', 'list', 'ls', 'outdated', 'audit', 'store', 'config', 'help', 'version', 'update', 'up', 'why', 'dlx', 'create', 'exec', 'fetch', 'dedupe', 'patch', 'prune', 'rebuild'])],\r\n ['docker', new Set(['run', 'exec', 'build', 'pull', 'push', 'images', 'ps', 'stop', 'start', 'restart', 'rm', 'rmi', 'logs', 'inspect', 'network', 'volume', 'compose', 'system', 'container', 'image', 'login', 'logout', 'tag', 'save', 'load', 'export', 'import', 'commit', 'cp', 'create', 'diff', 'events', 'history', 'info', 'kill', 'pause', 'unpause', 'port', 'rename', 'stats', 'top', 'update', 'wait', 'attach', 'builder', 'buildx', 'config', 'context', 'manifest', 'plugin', 'search', 'secret', 'service', 'stack', 'swarm', 'trust', 'version'])],\r\n ['kubectl', new Set(['get', 'describe', 'create', 'apply', 'delete', 'edit', 'logs', 'exec', 'port-forward', 'proxy', 'run', 'expose', 'scale', 'rollout', 'set', 'explain', 'cluster-info', 'top', 'cordon', 'uncordon', 'drain', 'taint', 'label', 'annotate', 'config', 'cp', 'attach', 'auth', 'autoscale', 'certificate', 'completion', 'debug', 'diff', 'kustomize', 'patch', 'plugin', 'replace', 'version', 'wait', 'api-resources', 'api-versions'])],\r\n ['go', new Set(['build', 'run', 'test', 'get', 'install', 'mod', 'fmt', 'vet', 'generate', 'clean', 'env', 'version', 'list', 'work', 'doc', 'fix', 'tool', 'bug'])],\r\n ['cargo', new Set(['build', 'run', 'test', 'new', 'init', 'add', 'remove', 'update', 'search', 'publish', 'install', 'uninstall', 'check', 'bench', 'doc', 'clean', 'fetch', 'fix', 'fmt', 'clippy', 'tree', 'vendor', 'verify-project', 'version', 'yank', 'help', 'login', 'logout', 'owner', 'package', 'generate-lockfile', 'locate-project', 'metadata', 'pkgid', 'read-manifest', 'report'])],\r\n ['pip', new Set(['install', 'uninstall', 'download', 'freeze', 'list', 'show', 'search', 'wheel', 'hash', 'check', 'config', 'cache', 'index', 'debug', 'help', 'completion'])],\r\n ['pip3', new Set(['install', 'uninstall', 'download', 'freeze', 'list', 'show', 'search', 'wheel', 'hash', 'check', 'config', 'cache', 'index', 'debug', 'help', 'completion'])],\r\n ['aws', new Set(['s3', 'ec2', 'lambda', 'iam', 'rds', 'dynamodb', 'cloudformation', 'ecs', 'eks', 'sns', 'sqs', 'cloudwatch', 'route53', 'apigateway', 'cognito', 'secretsmanager', 'ssm', 'sts', 'configure', 'help'])],\r\n ['az', new Set(['login', 'logout', 'account', 'group', 'vm', 'storage', 'network', 'webapp', 'functionapp', 'aks', 'acr', 'sql', 'cosmosdb', 'keyvault', 'monitor', 'resource', 'role', 'ad', 'configure', 'help', 'version'])],\r\n ['gcloud', new Set(['auth', 'config', 'compute', 'container', 'functions', 'run', 'app', 'sql', 'storage', 'pubsub', 'iam', 'projects', 'services', 'builds', 'deploy', 'components', 'help', 'version', 'init', 'info'])],\r\n ['terraform', new Set(['init', 'plan', 'apply', 'destroy', 'validate', 'fmt', 'show', 'output', 'refresh', 'import', 'state', 'workspace', 'providers', 'graph', 'taint', 'untaint', 'console', 'force-unlock', 'get', 'login', 'logout', 'version', 'help'])],\r\n ['make', new Set(['all', 'build', 'clean', 'install', 'uninstall', 'test', 'check', 'dist', 'distclean', 'help'])],\r\n ['find', new Set([])], // find uses expressions, not subcommands\r\n ['which', new Set([])], // which doesn't have subcommands\r\n]);\r\n\r\n/**\r\n * Check if the input looks like a natural language sentence\r\n */\r\nfunction looksLikeNaturalLanguage(words: string[]): boolean {\r\n if (words.length < 2) return false;\r\n\r\n const lowerWords = words.map(w => w.toLowerCase());\r\n\r\n // Count natural language markers\r\n let markerCount = 0;\r\n for (const word of lowerWords) {\r\n if (NATURAL_LANGUAGE_MARKERS.has(word)) {\r\n markerCount++;\r\n }\r\n }\r\n\r\n // If more than 30% of words are natural language markers, it's likely natural language\r\n if (markerCount >= Math.ceil(words.length * 0.3)) {\r\n return true;\r\n }\r\n\r\n // Check for common natural language patterns\r\n // Pattern: verb + article (e.g., \"make a\", \"create the\", \"find the\")\r\n if (lowerWords.length >= 2 && ['a', 'an', 'the', 'me', 'my', 'some', 'any'].includes(lowerWords[1])) {\r\n return true;\r\n }\r\n\r\n // Pattern: question word + verb/article (e.g., \"which libraries have\")\r\n if (lowerWords.length >= 3 &&\r\n AMBIGUOUS_COMMANDS.has(lowerWords[0]) &&\r\n NATURAL_LANGUAGE_MARKERS.has(lowerWords[1])) {\r\n return true;\r\n }\r\n\r\n // Pattern: contains \"i\" as a word (pronoun)\r\n if (lowerWords.includes('i') && lowerWords.indexOf('i') > 0) {\r\n return true;\r\n }\r\n\r\n // Pattern: long phrase with multiple natural language markers scattered\r\n if (words.length >= 4 && markerCount >= 2) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if input has strong command syntax indicators\r\n */\r\nfunction hasCommandSyntax(input: string, words: string[]): boolean {\r\n const trimmed = input.trim();\r\n const firstWord = words[0]?.toLowerCase() || '';\r\n\r\n // Flags: -f, --flag (must be preceded by space or at position 2+)\r\n const hasFlags = /\\s-[a-zA-Z]|\\s--[a-zA-Z]/.test(input) ||\r\n (words.length >= 2 && /^-[a-zA-Z]/.test(words[1]));\r\n\r\n // Operators: |, >, >>, <, &&, ||, ;\r\n const hasOperators = /(\\s\\|\\s)|(\\s>\\s)|(\\s>>\\s)|(\\s<\\s)|(\\s&&\\s)|(\\s\\|\\|\\s)|(;)/.test(input);\r\n\r\n // Variable assignment: VAR=val (at start or after space)\r\n const hasVarAssign = /^[a-zA-Z_][a-zA-Z0-9_]*=[^ ]/.test(input) || /\\s[a-zA-Z_][a-zA-Z0-9_]*=[^ ]/.test(input);\r\n\r\n // Quoted arguments that look like command arguments (e.g., -m \"message\")\r\n const hasQuotedWithFlag = /\\s-[a-zA-Z]+\\s+[\"']/.test(input) || /\\s--[a-zA-Z-]+[=\\s]+[\"']/.test(input);\r\n\r\n // Path patterns (absolute paths or ./ or ../)\r\n const hasPathPattern = /^[.~]?\\/|^\\.\\.\\/|\\s[.~]?\\/|\\s\\.\\.\\//.test(input);\r\n\r\n // Windows path patterns (C:\\, D:\\, etc.)\r\n const hasWindowsPath = /^[a-zA-Z]:\\\\|\\\\s[a-zA-Z]:\\\\/.test(input);\r\n\r\n // Redirect to/from file\r\n const hasFileRedirect = /[<>]\\s*[a-zA-Z0-9_./-]+/.test(input);\r\n\r\n // Environment variable usage\r\n const hasEnvVar = /\\$[a-zA-Z_][a-zA-Z0-9_]*|\\$\\{[^}]+\\}|%[a-zA-Z_][a-zA-Z0-9_]*%/.test(input);\r\n\r\n // Shell built-in patterns:\r\n\r\n // Exit/return with numeric code: exit 0, exit 1, return 0, return 1\r\n const hasExitCode = /^(exit|return|break|continue)\\s+\\d+$/.test(trimmed);\r\n\r\n // Background job: command &\r\n const hasBackgroundJob = /\\s*&\\s*$/.test(trimmed);\r\n\r\n // Command chaining: cmd1; cmd2\r\n const hasCommandChain = /;\\s*[a-zA-Z]/.test(input);\r\n\r\n // Command substitution: $(cmd) or `cmd`\r\n const hasCommandSubstitution = /\\$\\([^)]+\\)|`[^`]+`/.test(input);\r\n\r\n // Job control: %1, %2, etc.\r\n const hasJobReference = /^(fg|bg|jobs|kill|disown)\\s+%?\\d+$/.test(trimmed);\r\n\r\n // pushd/popd with path or +N/-N\r\n const hasDirStackOp = /^(pushd|popd)\\s+([+\\-]\\d+|[\\/~.])/.test(trimmed);\r\n\r\n // history with number: history 10, history -c, history -d 5\r\n const hasHistoryOp = /^history\\s+(-[a-z]|\\d+)/.test(trimmed);\r\n\r\n // alias definition: alias name='...' or alias name=\"...\"\r\n const hasAliasDefinition = /^alias\\s+[a-zA-Z_][a-zA-Z0-9_]*=/.test(trimmed);\r\n\r\n // export with assignment: export VAR=value\r\n const hasExportAssign = /^export\\s+[A-Z_][A-Z0-9_]*=/.test(trimmed);\r\n\r\n // cd with path or special: cd -, cd ~, cd ..\r\n const hasCdPath = /^cd\\s+[\\/~.\\-]/.test(trimmed);\r\n\r\n // Check for known command + subcommand pattern\r\n if (words.length >= 2) {\r\n const secondWord = words[1].toLowerCase();\r\n const subcommands = COMMAND_SUBCOMMANDS.get(firstWord);\r\n if (subcommands && subcommands.has(secondWord)) {\r\n return true;\r\n }\r\n }\r\n\r\n // Shell built-in as single word is always a command\r\n if (words.length === 1 && SHELL_BUILTINS.has(firstWord)) {\r\n return true;\r\n }\r\n\r\n return hasFlags || hasOperators || hasVarAssign || hasQuotedWithFlag ||\r\n hasPathPattern || hasWindowsPath || hasFileRedirect || hasEnvVar ||\r\n hasExitCode || hasBackgroundJob || hasCommandChain || hasCommandSubstitution ||\r\n hasJobReference || hasDirStackOp || hasHistoryOp || hasAliasDefinition ||\r\n hasExportAssign || hasCdPath;\r\n}\r\n\r\n/**\r\n * Disambiguate ambiguous commands based on context\r\n */\r\nfunction disambiguateCommand(input: string, words: string[]): InputIntent {\r\n const firstWord = words[0].toLowerCase();\r\n\r\n // If it has command syntax, it's definitely a command\r\n if (hasCommandSyntax(input, words)) {\r\n return 'command';\r\n }\r\n\r\n // If it looks like natural language, it's AI\r\n if (looksLikeNaturalLanguage(words)) {\r\n return 'ai';\r\n }\r\n\r\n // Special case for 'make' - check for Makefile targets vs natural language\r\n if (firstWord === 'make') {\r\n // \"make build\", \"make clean\", \"make all\" - valid Makefile targets\r\n const makeSubcommands = COMMAND_SUBCOMMANDS.get('make');\r\n if (words.length >= 2 && makeSubcommands?.has(words[1].toLowerCase())) {\r\n return 'command';\r\n }\r\n // \"make something\" where something is a single word could be a target\r\n if (words.length === 2 && /^[a-z0-9_-]+$/i.test(words[1])) {\r\n return 'command';\r\n }\r\n // Otherwise, likely natural language (\"make it work\", \"make a file\")\r\n return 'ai';\r\n }\r\n\r\n // Special case for 'which' - almost always a command when alone or with one arg\r\n if (firstWord === 'which') {\r\n // \"which node\" - valid command\r\n if (words.length === 2 && /^[a-z0-9_.-]+$/i.test(words[1])) {\r\n return 'command';\r\n }\r\n // \"which libraries have I used\" - natural language\r\n if (words.length > 2) {\r\n return 'ai';\r\n }\r\n }\r\n\r\n // Special case for 'find' - needs path or expression flags\r\n if (firstWord === 'find') {\r\n // \"find . -name\" or \"find /path\" - command\r\n if (words.length >= 2 && (words[1].startsWith('.') || words[1].startsWith('/') || words[1].startsWith('-'))) {\r\n return 'command';\r\n }\r\n // \"find all bugs\" - natural language\r\n if (words.length > 2) {\r\n return 'ai';\r\n }\r\n }\r\n\r\n // Special case for 'export' - needs assignment\r\n if (firstWord === 'export') {\r\n // \"export VAR=value\" or \"export PATH\" - command\r\n if (words.length >= 2 && /^[A-Z_][A-Z0-9_]*/.test(words[1])) {\r\n return 'command';\r\n }\r\n // \"export the data\" - natural language\r\n return 'ai';\r\n }\r\n\r\n // Special case for 'run', 'start', 'stop', 'test'\r\n if (['run', 'start', 'stop', 'test'].includes(firstWord)) {\r\n // These are more often natural language unless they have specific patterns\r\n // \"run npm install\" - could be shorthand for script runner\r\n // \"run this code\" - natural language\r\n // \"start the server\" - ambiguous but likely natural language\r\n // \"test the api\" - natural language\r\n if (words.length >= 2) {\r\n // If followed by a known command, treat as command\r\n if (DEFINITE_COMMANDS.has(words[1].toLowerCase())) {\r\n return 'command';\r\n }\r\n // If followed by natural language markers, treat as AI\r\n if (NATURAL_LANGUAGE_MARKERS.has(words[1].toLowerCase())) {\r\n return 'ai';\r\n }\r\n }\r\n // Default to AI for these ambiguous words\r\n return 'ai';\r\n }\r\n\r\n // For other ambiguous commands:\r\n // Single word - could be a command, but safer to default to command (can be overridden)\r\n if (words.length === 1) {\r\n return 'command';\r\n }\r\n\r\n // Two words where second is a simple identifier - likely command\r\n if (words.length === 2 && /^[a-z0-9_.-]+$/i.test(words[1]) && !NATURAL_LANGUAGE_MARKERS.has(words[1].toLowerCase())) {\r\n return 'command';\r\n }\r\n\r\n // Default to AI for multi-word ambiguous commands\r\n return 'ai';\r\n}\r\n\r\n/**\r\n * Detects the intent of the user input using intelligent heuristics.\r\n * \r\n * Logic Priority:\r\n * 1. Slash Commands: If starts with '/', check if valid command -> AI\r\n * 2. Prefixes: '?' -> AI, '.', '/', '$', '~' -> Command\r\n * 3. Strong AI Indicators: Question marks, AI keywords\r\n * 4. Strong Command Syntax: Flags, pipes, redirects, quotes, env vars\r\n * 5. Definite Commands: Known command binaries that aren't ambiguous\r\n * 6. Ambiguous Command Disambiguation: Context-aware analysis\r\n * 7. Natural Language Detection: Sentence structure analysis\r\n * 8. Fallback: Multi-word without command syntax -> AI\r\n * \r\n * @param input The user input string\r\n * @returns 'command' | 'ai'\r\n */\r\nexport function detectIntent(input: string): InputIntent {\r\n const trimmed = input.trim();\r\n\r\n if (!trimmed) {\r\n return 'ai'; // Default to AI for empty/whitespace\r\n }\r\n\r\n // Check 0 - Slash Commands (Highest Priority)\r\n if (trimmed.startsWith('/')) {\r\n // Extract command name (remove '/' and take first word)\r\n const commandName = trimmed.slice(1).split(/\\s+/)[0].toLowerCase();\r\n if (SLASH_COMMANDS.has(commandName)) {\r\n return 'ai';\r\n }\r\n // If starts with '/' but not a valid slash command, assume it's a path -> Command\r\n return 'command';\r\n }\r\n\r\n // Check 1 - Explicit Prefixes\r\n if (trimmed.startsWith('?')) return 'ai';\r\n if (trimmed.startsWith('.') || trimmed.startsWith('$') || trimmed.startsWith('~')) return 'command';\r\n\r\n // Parse words for analysis\r\n const words = trimmed.split(/\\s+/);\r\n const firstWord = words[0].toLowerCase();\r\n\r\n // Check 2 - Strong AI Indicators (check BEFORE command matching)\r\n const isQuestion = trimmed.endsWith('?');\r\n const startsWithAIKeyword = AI_KEYWORDS.has(firstWord);\r\n\r\n if (startsWithAIKeyword) {\r\n // If starts with AI keyword, it's almost always AI\r\n // Exception: if it has strong command syntax, it might still be a command\r\n if (!hasCommandSyntax(trimmed, words)) {\r\n return 'ai';\r\n }\r\n }\r\n\r\n if (isQuestion) {\r\n // Questions are almost always AI\r\n // Exception: rare case of command with ? (like \"ls ?*.txt\" - but this is uncommon)\r\n if (!hasCommandSyntax(trimmed, words)) {\r\n return 'ai';\r\n }\r\n }\r\n\r\n // Check 3 - Strong Command Syntax (before command name matching)\r\n if (hasCommandSyntax(trimmed, words)) {\r\n return 'command';\r\n }\r\n\r\n // Check 4 - Definite Commands (non-ambiguous command names)\r\n if (DEFINITE_COMMANDS.has(firstWord)) {\r\n // Special handling for shell built-ins that might be followed by natural language\r\n // e.g., \"exit\" is a command, but \"exit the application\" is AI\r\n if (SHELL_BUILTINS.has(firstWord) && words.length > 1) {\r\n // Check if followed by natural language markers\r\n const secondWord = words[1].toLowerCase();\r\n if (NATURAL_LANGUAGE_MARKERS.has(secondWord)) {\r\n return 'ai';\r\n }\r\n // Check for \"exit/clear/history the ...\" pattern\r\n if (['the', 'this', 'that', 'my', 'your', 'our', 'all'].includes(secondWord)) {\r\n return 'ai';\r\n }\r\n }\r\n return 'command';\r\n }\r\n\r\n // Check 4.5 - Custom Commands (user-defined terminal commands)\r\n // Load custom commands synchronously for fast detection\r\n const customCommandsManager = CustomCommandsManager.getInstance();\r\n customCommandsManager.loadSync();\r\n if (customCommandsManager.hasCommand(firstWord)) {\r\n return 'command';\r\n }\r\n\r\n // Check 5 - Ambiguous Commands (need disambiguation)\r\n if (AMBIGUOUS_COMMANDS.has(firstWord)) {\r\n return disambiguateCommand(trimmed, words);\r\n }\r\n\r\n // Check 6 - Path-like strings\r\n // If it contains slashes and no spaces, it might be a path execution\r\n if ((trimmed.includes('/') || trimmed.includes('\\\\')) && !trimmed.includes(' ')) {\r\n return 'command';\r\n }\r\n\r\n // Check 7 - Natural Language Detection for unknown first words\r\n if (looksLikeNaturalLanguage(words)) {\r\n return 'ai';\r\n }\r\n\r\n // Check 8 - Fallback Heuristics\r\n\r\n // If it's a single word and NOT a known command/keyword:\r\n if (words.length === 1) {\r\n if (trimmed.includes('.')) return 'command'; // script.sh, main.py\r\n // Unknown single word - default to AI (safer for chat)\r\n return 'ai';\r\n }\r\n\r\n // Multiple words, no flags, no operators, no keywords, not natural language pattern\r\n // This is truly ambiguous - default to AI (safer for chat assistant)\r\n return 'ai';\r\n}\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/input-classifier.ts"],"sourcesContent":["/**\r\n * Input Classification Utilities\r\n * \r\n * Provides intelligent heuristic-based detection of user intent (Terminal Command vs AI Message).\r\n * Uses sentence structure analysis, command syntax detection, and context-aware disambiguation.\r\n */\r\n\r\nimport { CustomCommandsManager } from './custom-commands-manager.js';\r\nimport { TunnelCommandsManager } from './tunnel-commands-manager.js';\r\n\r\nexport type InputIntent = 'command' | 'ai';\r\n\r\n// Valid slash commands that should be handled by the Agent/CLI logic\r\nconst SLASH_COMMANDS = new Set([\r\n 'help', 'h', '?',\r\n 'model', 'm', 'models',\r\n 'config', 'c', 'settings',\r\n 'clear', 'cls', 'reset',\r\n 'sync',\r\n 'clean-ui', 'refresh-ui', 'redraw',\r\n 'exit', 'quit', 'q',\r\n 'session', 's',\r\n 'session-limits',\r\n 'tools', 't',\r\n 'plan',\r\n 'init', 'i',\r\n 'mcp',\r\n 'chat',\r\n 'docs',\r\n 'sign-in',\r\n 'logout',\r\n 'quality',\r\n 'autonomous',\r\n 'add-command', 'add-command-auto-detect',\r\n 'background-task', 'bkg', 'bg-task',\r\n 'copy-chat-context',\r\n 'workflow', 'wf',\r\n 'rules',\r\n 'revert',\r\n 'sub-agent', 'subagent',\r\n 'compact',\r\n 'skill'\r\n]);\r\n\r\n// Commands that are definitely terminal commands (not ambiguous with natural language)\r\nconst DEFINITE_COMMANDS = new Set([\r\n // Package Managers\r\n 'npm', 'yarn', 'pnpm', 'bun', 'npx', 'gem', 'pip', 'pip3', 'conda', 'cargo', 'composer', 'mvn', 'gradle',\r\n // Package managers (extended)\r\n 'apt', 'apt-get', 'apt-cache', 'dpkg', 'yum', 'dnf', 'rpm', 'zypper', 'pacman', 'emerge',\r\n 'port', 'brew', 'choco', 'scoop', 'winget', 'snap', 'flatpak', 'nix', 'nix-env', 'apk',\r\n // Version Control\r\n 'git', 'svn', 'hg', 'gh', 'gitk', 'tig',\r\n // File Operations (non-ambiguous)\r\n 'ls', 'cd', 'pwd', 'mkdir', 'rm', 'cp', 'mv', 'cat', 'less', 'more', 'chmod', 'chown', 'chgrp', 'ln',\r\n 'stat', 'file', 'realpath', 'basename', 'dirname', 'readlink', 'dd', 'truncate', 'shred', 'sync',\r\n 'mktemp', 'install', 'xargs', 'tee', 'touch',\r\n // Editors\r\n 'vim', 'nvim', 'vi', 'nano', 'emacs', 'micro', 'helix', 'hx', 'pico', 'joe', 'ne', 'mcedit', 'code',\r\n 'subl', 'atom', 'gedit', 'kate', 'notepad', 'notepad++',\r\n // System / Process\r\n 'ps', 'kill', 'killall', 'htop', 'btop', 'free', 'df', 'du', 'whoami', 'su', 'sudo',\r\n 'nice', 'renice', 'nohup', 'timeout', 'strace', 'ltrace', 'pgrep', 'pkill', 'fuser', 'pstree',\r\n // Network\r\n 'curl', 'wget', 'ssh', 'scp', 'ping', 'telnet', 'nc', 'netstat', 'lsof', 'dig', 'nslookup', 'ip', 'ifconfig', 'traceroute',\r\n 'arp', 'route', 'ss', 'tcpdump', 'nmap', 'iptables', 'ip6tables', 'firewall-cmd', 'ufw',\r\n 'socat', 'rsync', 'ftp', 'sftp', 'sshfs', 'rclone', 'mtr', 'host', 'whois',\r\n // Build / Run (non-ambiguous)\r\n 'cmake', 'docker', 'docker-compose', 'kubectl', 'python', 'python3', 'ruby', 'perl', 'php', 'java', 'gcc', 'g++', 'clang',\r\n 'javac', 'dotnet', 'mono', 'swift', 'swiftc', 'kotlinc', 'scalac', 'elixir', 'mix', 'iex',\r\n // Shell / Subshells\r\n 'echo', 'env', 'cal', 'printenv',\r\n 'wsl', 'bash', 'sh', 'zsh', 'fish', 'powershell', 'pwsh', 'cmd',\r\n 'ksh', 'csh', 'tcsh', 'ash', 'dash',\r\n // Shell built-ins (critical additions)\r\n 'exit', 'logout', 'return', 'break', 'continue',\r\n 'alias', 'unalias', 'builtin', 'command',\r\n 'exec', 'eval', 'declare', 'local', 'readonly',\r\n 'enable', 'disable', 'ulimit', 'umask', 'trap',\r\n 'jobs', 'fg', 'bg', 'disown', 'suspend', 'times',\r\n 'pushd', 'popd', 'dirs', 'cd', 'pwd',\r\n 'fc', 'bind', 'complete', 'compgen', 'compopt', 'shopt',\r\n 'history', 'clear', 'reset', 'tput', 'stty',\r\n // Session/User management\r\n 'login', 'newgrp', 'groups', 'id', 'users', 'finger', 'w', 'who', 'last', 'lastlog',\r\n 'useradd', 'userdel', 'usermod', 'passwd', 'chpasswd',\r\n 'groupadd', 'groupdel', 'groupmod', 'adduser', 'deluser',\r\n // Archives\r\n 'tar', 'zip', 'unzip', 'gzip', 'gunzip', '7z', 'rar', 'bzip2', 'bunzip2', 'xz', 'unxz', 'zstd',\r\n // Search (non-ambiguous)\r\n 'grep', 'egrep', 'fgrep', 'locate', 'sed', 'awk', 'gawk', 'ack', 'ag', 'rg', 'fd', 'fzf',\r\n // Text processing\r\n 'tr', 'wc', 'nl', 'uniq', 'rev', 'tac', 'hexdump', 'xxd', 'od', 'strings',\r\n 'expand', 'unexpand', 'column', 'colrm', 'csplit', 'pr', 'tsort', 'comm',\r\n // Misc\r\n 'jq', 'yq', 'crontab', 'visudo', 'vipw', 'sudoedit', 'at', 'batch',\r\n // Cloud / DevOps\r\n 'aws', 'az', 'gcloud', 'terraform', 'ansible', 'ansible-playbook', 'kubectl', 'helm', 'vagrant',\r\n 'pulumi', 'cdk', 'sam', 'serverless', 'flyctl', 'heroku', 'vercel', 'netlify',\r\n // Database\r\n 'mysql', 'psql', 'mongo', 'mongod', 'mongosh', 'redis-cli', 'sqlite3', 'pg_dump', 'mysqldump',\r\n // Web / Security\r\n 'openssl', 'certbot', 'nginx', 'apache2', 'httpd', 'gpg', 'ssh-keygen', 'ssh-agent', 'ssh-add',\r\n // Language runtimes (non-ambiguous)\r\n 'node', 'deno', 'ts-node', 'tsx', 'esbuild', 'webpack', 'vite', 'rollup', 'parcel',\r\n 'jest', 'vitest', 'mocha', 'pytest', 'phpunit', 'rspec',\r\n // Go\r\n 'go', 'gofmt', 'golint', 'gopls',\r\n // Rust\r\n 'rustc', 'rustup', 'rustfmt', 'clippy',\r\n // System info\r\n 'uname', 'hostname', 'uptime', 'arch', 'nproc', 'lscpu', 'lsblk', 'lsusb', 'lspci',\r\n 'dmidecode', 'dmesg', 'sysctl', 'modprobe', 'lsmod', 'insmod', 'rmmod',\r\n // Services/Daemons\r\n 'systemctl', 'service', 'journalctl', 'loginctl', 'chkconfig', 'update-rc.d', 'launchctl',\r\n // Disk/Storage\r\n 'mount', 'umount', 'fdisk', 'parted', 'mkfs', 'fsck', 'blkid', 'findmnt', 'quota', 'hdparm',\r\n // Windows-specific commands\r\n 'dir', 'copy', 'move', 'del', 'ren', 'rename', 'attrib', 'cls', 'md', 'rd', 'rmdir',\r\n 'xcopy', 'robocopy', 'icacls', 'cacls', 'takeown',\r\n 'tasklist', 'taskkill', 'systeminfo', 'ipconfig', 'netsh', 'pathping',\r\n 'reg', 'regedit', 'schtasks', 'wmic', 'where', 'findstr', 'fc', 'comp',\r\n 'chkdsk', 'sfc', 'dism', 'bcdedit', 'diskpart', 'format', 'label', 'vol',\r\n 'net', 'netstat', 'nbtstat', 'klist', 'gpresult', 'gpupdate', 'shutdown', 'logoff',\r\n // PowerShell aliases that look like commands\r\n 'gci', 'gc', 'sl', 'gi', 'gm', 'gwmi', 'iwr', 'irm',\r\n // Date/Time\r\n 'timedatectl', 'hwclock', 'ntpdate', 'chronyc',\r\n // Containers/Virtualization\r\n 'podman', 'crictl', 'ctr', 'nerdctl', 'lxc', 'lxd', 'virsh', 'vboxmanage', 'multipass', 'lima',\r\n // Kubernetes ecosystem\r\n 'k9s', 'kubectx', 'kubens', 'kustomize', 'skaffold', 'minikube', 'kind', 'k3s', 'k3d',\r\n // Misc utilities\r\n 'xdg-open', 'open', 'wslpath', 'cygpath', 'explorer', 'start',\r\n 'yes', 'seq', 'factor', 'bc', 'dc', 'expr',\r\n 'sleep', 'usleep', 'watch',\r\n // Common CLI tools\r\n 'ffmpeg', 'ffprobe', 'convert', 'identify', 'magick', 'pandoc', 'latex', 'pdflatex', 'bibtex',\r\n 'youtube-dl', 'yt-dlp', 'aria2c', 'axel',\r\n]);\r\n\r\n// Shell built-ins that work standalone or with simple arguments (exit codes, etc.)\r\n// These get special handling for disambiguation\r\nconst SHELL_BUILTINS = new Set([\r\n 'exit', 'logout', 'return', 'break', 'continue',\r\n 'jobs', 'fg', 'bg', 'wait', 'disown', 'suspend',\r\n 'pushd', 'popd', 'dirs',\r\n 'history', 'fc',\r\n 'pwd', 'hash', 'help', 'true', 'false',\r\n 'env', 'printenv', 'export', 'set', 'unset',\r\n 'alias', 'unalias', 'type', 'command', 'builtin',\r\n 'clear', 'reset', 'cls',\r\n]);\r\n\r\n// Commands that can also be natural language words - need disambiguation\r\nconst AMBIGUOUS_COMMANDS = new Set([\r\n 'which', 'make', 'find', 'head', 'tail',\r\n 'test', 'run', 'start', 'stop', 'top', 'man',\r\n 'date', 'time', 'source', 'tree', 'sort',\r\n 'diff', 'patch', 'split', 'join', 'cut', 'paste', 'fold', 'fmt',\r\n 'look', 'spell', 'read', 'print', 'say', 'write',\r\n 'mount', 'watch', 'locate', 'ping', 'host'\r\n]);\r\n\r\n// Natural language keywords that strongly indicate AI intent\r\nconst AI_KEYWORDS = new Set([\r\n // Question words\r\n 'how', 'what', 'why', 'when', 'where', 'who', 'whose', 'whom',\r\n // Action requests\r\n 'write', 'create', 'generate', 'implement', 'scaffold', 'design',\r\n 'explain', 'describe', 'clarify', 'analyze', 'review', 'audit',\r\n 'fix', 'debug', 'solve', 'correct', 'repair',\r\n 'optimize', 'improve', 'refactor', 'format',\r\n 'verify', 'validate',\r\n 'translate', 'convert', 'transform',\r\n 'summarize', 'document', 'comment',\r\n 'add', 'update', 'change', 'modify', 'remove', 'delete',\r\n // Modal verbs indicating requests\r\n 'can', 'could', 'would', 'should', 'shall', 'might', 'must',\r\n // Greetings and polite markers\r\n 'hey', 'hi', 'hello', 'help', 'please', 'thanks', 'thank',\r\n // Contextual\r\n 'show', 'tell', 'give', 'list', 'provide', 'suggest', 'recommend'\r\n]);\r\n\r\n// Words that indicate natural language sentence structure\r\nconst NATURAL_LANGUAGE_MARKERS = new Set([\r\n // Articles\r\n 'a', 'an', 'the',\r\n // Pronouns\r\n 'i', 'me', 'my', 'mine', 'you', 'your', 'yours', 'he', 'she', 'it', 'we', 'they',\r\n 'this', 'that', 'these', 'those',\r\n // Prepositions commonly used in requests\r\n 'for', 'with', 'about', 'from', 'into', 'through', 'during', 'before', 'after',\r\n // Conjunctions\r\n 'and', 'but', 'or', 'so', 'because', 'if', 'then', 'while',\r\n // Common verbs in questions/requests\r\n 'is', 'are', 'was', 'were', 'be', 'been', 'being',\r\n 'do', 'does', 'did', 'doing', 'done',\r\n 'have', 'has', 'had', 'having',\r\n 'get', 'got', 'getting',\r\n // Adverbs\r\n 'here', 'there', 'now', 'just', 'also', 'only', 'even', 'still', 'already'\r\n]);\r\n\r\n// Known command + subcommand patterns (command followed by valid subcommand)\r\nconst COMMAND_SUBCOMMANDS: Map<string, Set<string>> = new Map([\r\n ['git', new Set(['add', 'commit', 'push', 'pull', 'clone', 'checkout', 'branch', 'merge', 'rebase', 'reset', 'stash', 'log', 'diff', 'status', 'init', 'remote', 'fetch', 'tag', 'show', 'rm', 'mv', 'bisect', 'blame', 'cherry-pick', 'revert', 'clean', 'gc', 'reflog', 'worktree', 'submodule', 'config', 'help', 'version'])],\r\n ['npm', new Set(['install', 'i', 'uninstall', 'un', 'update', 'up', 'run', 'start', 'test', 'build', 'init', 'publish', 'pack', 'link', 'unlink', 'ls', 'list', 'outdated', 'audit', 'cache', 'config', 'help', 'version', 'ci', 'exec', 'create', 'set-script', 'pkg', 'dedupe', 'prune', 'shrinkwrap', 'adduser', 'login', 'logout', 'whoami', 'token', 'owner', 'access', 'team', 'deprecate', 'unpublish', 'dist-tag', 'view', 'search', 'doctor', 'explain', 'find-dupes', 'fund', 'hook', 'org', 'ping', 'prefix', 'profile', 'rebuild', 'repo', 'root', 'star', 'stars', 'unstar', 'bugs', 'docs', 'edit', 'explore'])],\r\n ['yarn', new Set(['add', 'remove', 'install', 'run', 'start', 'test', 'build', 'init', 'publish', 'link', 'unlink', 'list', 'outdated', 'audit', 'cache', 'config', 'help', 'version', 'upgrade', 'upgrade-interactive', 'why', 'workspaces', 'set', 'create', 'dlx', 'pack', 'dedupe', 'info'])],\r\n ['pnpm', new Set(['add', 'remove', 'install', 'i', 'run', 'start', 'test', 'build', 'init', 'publish', 'link', 'unlink', 'list', 'ls', 'outdated', 'audit', 'store', 'config', 'help', 'version', 'update', 'up', 'why', 'dlx', 'create', 'exec', 'fetch', 'dedupe', 'patch', 'prune', 'rebuild'])],\r\n ['docker', new Set(['run', 'exec', 'build', 'pull', 'push', 'images', 'ps', 'stop', 'start', 'restart', 'rm', 'rmi', 'logs', 'inspect', 'network', 'volume', 'compose', 'system', 'container', 'image', 'login', 'logout', 'tag', 'save', 'load', 'export', 'import', 'commit', 'cp', 'create', 'diff', 'events', 'history', 'info', 'kill', 'pause', 'unpause', 'port', 'rename', 'stats', 'top', 'update', 'wait', 'attach', 'builder', 'buildx', 'config', 'context', 'manifest', 'plugin', 'search', 'secret', 'service', 'stack', 'swarm', 'trust', 'version'])],\r\n ['kubectl', new Set(['get', 'describe', 'create', 'apply', 'delete', 'edit', 'logs', 'exec', 'port-forward', 'proxy', 'run', 'expose', 'scale', 'rollout', 'set', 'explain', 'cluster-info', 'top', 'cordon', 'uncordon', 'drain', 'taint', 'label', 'annotate', 'config', 'cp', 'attach', 'auth', 'autoscale', 'certificate', 'completion', 'debug', 'diff', 'kustomize', 'patch', 'plugin', 'replace', 'version', 'wait', 'api-resources', 'api-versions'])],\r\n ['go', new Set(['build', 'run', 'test', 'get', 'install', 'mod', 'fmt', 'vet', 'generate', 'clean', 'env', 'version', 'list', 'work', 'doc', 'fix', 'tool', 'bug'])],\r\n ['cargo', new Set(['build', 'run', 'test', 'new', 'init', 'add', 'remove', 'update', 'search', 'publish', 'install', 'uninstall', 'check', 'bench', 'doc', 'clean', 'fetch', 'fix', 'fmt', 'clippy', 'tree', 'vendor', 'verify-project', 'version', 'yank', 'help', 'login', 'logout', 'owner', 'package', 'generate-lockfile', 'locate-project', 'metadata', 'pkgid', 'read-manifest', 'report'])],\r\n ['pip', new Set(['install', 'uninstall', 'download', 'freeze', 'list', 'show', 'search', 'wheel', 'hash', 'check', 'config', 'cache', 'index', 'debug', 'help', 'completion'])],\r\n ['pip3', new Set(['install', 'uninstall', 'download', 'freeze', 'list', 'show', 'search', 'wheel', 'hash', 'check', 'config', 'cache', 'index', 'debug', 'help', 'completion'])],\r\n ['aws', new Set(['s3', 'ec2', 'lambda', 'iam', 'rds', 'dynamodb', 'cloudformation', 'ecs', 'eks', 'sns', 'sqs', 'cloudwatch', 'route53', 'apigateway', 'cognito', 'secretsmanager', 'ssm', 'sts', 'configure', 'help'])],\r\n ['az', new Set(['login', 'logout', 'account', 'group', 'vm', 'storage', 'network', 'webapp', 'functionapp', 'aks', 'acr', 'sql', 'cosmosdb', 'keyvault', 'monitor', 'resource', 'role', 'ad', 'configure', 'help', 'version'])],\r\n ['gcloud', new Set(['auth', 'config', 'compute', 'container', 'functions', 'run', 'app', 'sql', 'storage', 'pubsub', 'iam', 'projects', 'services', 'builds', 'deploy', 'components', 'help', 'version', 'init', 'info'])],\r\n ['terraform', new Set(['init', 'plan', 'apply', 'destroy', 'validate', 'fmt', 'show', 'output', 'refresh', 'import', 'state', 'workspace', 'providers', 'graph', 'taint', 'untaint', 'console', 'force-unlock', 'get', 'login', 'logout', 'version', 'help'])],\r\n ['make', new Set(['all', 'build', 'clean', 'install', 'uninstall', 'test', 'check', 'dist', 'distclean', 'help'])],\r\n ['find', new Set([])], // find uses expressions, not subcommands\r\n ['which', new Set([])], // which doesn't have subcommands\r\n]);\r\n\r\n/**\r\n * Check if the input looks like a natural language sentence\r\n */\r\nfunction looksLikeNaturalLanguage(words: string[]): boolean {\r\n if (words.length < 2) return false;\r\n\r\n const lowerWords = words.map(w => w.toLowerCase());\r\n\r\n // Count natural language markers\r\n let markerCount = 0;\r\n for (const word of lowerWords) {\r\n if (NATURAL_LANGUAGE_MARKERS.has(word)) {\r\n markerCount++;\r\n }\r\n }\r\n\r\n // If more than 30% of words are natural language markers, it's likely natural language\r\n if (markerCount >= Math.ceil(words.length * 0.3)) {\r\n return true;\r\n }\r\n\r\n // Check for common natural language patterns\r\n // Pattern: verb + article (e.g., \"make a\", \"create the\", \"find the\")\r\n if (lowerWords.length >= 2 && ['a', 'an', 'the', 'me', 'my', 'some', 'any'].includes(lowerWords[1])) {\r\n return true;\r\n }\r\n\r\n // Pattern: question word + verb/article (e.g., \"which libraries have\")\r\n if (lowerWords.length >= 3 &&\r\n AMBIGUOUS_COMMANDS.has(lowerWords[0]) &&\r\n NATURAL_LANGUAGE_MARKERS.has(lowerWords[1])) {\r\n return true;\r\n }\r\n\r\n // Pattern: contains \"i\" as a word (pronoun)\r\n if (lowerWords.includes('i') && lowerWords.indexOf('i') > 0) {\r\n return true;\r\n }\r\n\r\n // Pattern: long phrase with multiple natural language markers scattered\r\n if (words.length >= 4 && markerCount >= 2) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if input has strong command syntax indicators\r\n */\r\nfunction hasCommandSyntax(input: string, words: string[]): boolean {\r\n const trimmed = input.trim();\r\n const firstWord = words[0]?.toLowerCase() || '';\r\n\r\n // Flags: -f, --flag (must be preceded by space or at position 2+)\r\n const hasFlags = /\\s-[a-zA-Z]|\\s--[a-zA-Z]/.test(input) ||\r\n (words.length >= 2 && /^-[a-zA-Z]/.test(words[1]));\r\n\r\n // Operators: |, >, >>, <, &&, ||, ;\r\n const hasOperators = /(\\s\\|\\s)|(\\s>\\s)|(\\s>>\\s)|(\\s<\\s)|(\\s&&\\s)|(\\s\\|\\|\\s)|(;)/.test(input);\r\n\r\n // Variable assignment: VAR=val (at start or after space)\r\n const hasVarAssign = /^[a-zA-Z_][a-zA-Z0-9_]*=[^ ]/.test(input) || /\\s[a-zA-Z_][a-zA-Z0-9_]*=[^ ]/.test(input);\r\n\r\n // Quoted arguments that look like command arguments (e.g., -m \"message\")\r\n const hasQuotedWithFlag = /\\s-[a-zA-Z]+\\s+[\"']/.test(input) || /\\s--[a-zA-Z-]+[=\\s]+[\"']/.test(input);\r\n\r\n // Path patterns (absolute paths or ./ or ../)\r\n const hasPathPattern = /^[.~]?\\/|^\\.\\.\\/|\\s[.~]?\\/|\\s\\.\\.\\//.test(input);\r\n\r\n // Windows path patterns (C:\\, D:\\, etc.)\r\n const hasWindowsPath = /^[a-zA-Z]:\\\\|\\\\s[a-zA-Z]:\\\\/.test(input);\r\n\r\n // Redirect to/from file\r\n const hasFileRedirect = /[<>]\\s*[a-zA-Z0-9_./-]+/.test(input);\r\n\r\n // Environment variable usage\r\n const hasEnvVar = /\\$[a-zA-Z_][a-zA-Z0-9_]*|\\$\\{[^}]+\\}|%[a-zA-Z_][a-zA-Z0-9_]*%/.test(input);\r\n\r\n // Shell built-in patterns:\r\n\r\n // Exit/return with numeric code: exit 0, exit 1, return 0, return 1\r\n const hasExitCode = /^(exit|return|break|continue)\\s+\\d+$/.test(trimmed);\r\n\r\n // Background job: command &\r\n const hasBackgroundJob = /\\s*&\\s*$/.test(trimmed);\r\n\r\n // Command chaining: cmd1; cmd2\r\n const hasCommandChain = /;\\s*[a-zA-Z]/.test(input);\r\n\r\n // Command substitution: $(cmd) or `cmd`\r\n const hasCommandSubstitution = /\\$\\([^)]+\\)|`[^`]+`/.test(input);\r\n\r\n // Job control: %1, %2, etc.\r\n const hasJobReference = /^(fg|bg|jobs|kill|disown)\\s+%?\\d+$/.test(trimmed);\r\n\r\n // pushd/popd with path or +N/-N\r\n const hasDirStackOp = /^(pushd|popd)\\s+([+\\-]\\d+|[\\/~.])/.test(trimmed);\r\n\r\n // history with number: history 10, history -c, history -d 5\r\n const hasHistoryOp = /^history\\s+(-[a-z]|\\d+)/.test(trimmed);\r\n\r\n // alias definition: alias name='...' or alias name=\"...\"\r\n const hasAliasDefinition = /^alias\\s+[a-zA-Z_][a-zA-Z0-9_]*=/.test(trimmed);\r\n\r\n // export with assignment: export VAR=value\r\n const hasExportAssign = /^export\\s+[A-Z_][A-Z0-9_]*=/.test(trimmed);\r\n\r\n // cd with path or special: cd -, cd ~, cd ..\r\n const hasCdPath = /^cd\\s+[\\/~.\\-]/.test(trimmed);\r\n\r\n // Check for known command + subcommand pattern\r\n if (words.length >= 2) {\r\n const secondWord = words[1].toLowerCase();\r\n const subcommands = COMMAND_SUBCOMMANDS.get(firstWord);\r\n if (subcommands && subcommands.has(secondWord)) {\r\n return true;\r\n }\r\n }\r\n\r\n // Shell built-in as single word is always a command\r\n if (words.length === 1 && SHELL_BUILTINS.has(firstWord)) {\r\n return true;\r\n }\r\n\r\n return hasFlags || hasOperators || hasVarAssign || hasQuotedWithFlag ||\r\n hasPathPattern || hasWindowsPath || hasFileRedirect || hasEnvVar ||\r\n hasExitCode || hasBackgroundJob || hasCommandChain || hasCommandSubstitution ||\r\n hasJobReference || hasDirStackOp || hasHistoryOp || hasAliasDefinition ||\r\n hasExportAssign || hasCdPath;\r\n}\r\n\r\n/**\r\n * Disambiguate ambiguous commands based on context\r\n */\r\nfunction disambiguateCommand(input: string, words: string[]): InputIntent {\r\n const firstWord = words[0].toLowerCase();\r\n\r\n // If it has command syntax, it's definitely a command\r\n if (hasCommandSyntax(input, words)) {\r\n return 'command';\r\n }\r\n\r\n // If it looks like natural language, it's AI\r\n if (looksLikeNaturalLanguage(words)) {\r\n return 'ai';\r\n }\r\n\r\n // Special case for 'make' - check for Makefile targets vs natural language\r\n if (firstWord === 'make') {\r\n // \"make build\", \"make clean\", \"make all\" - valid Makefile targets\r\n const makeSubcommands = COMMAND_SUBCOMMANDS.get('make');\r\n if (words.length >= 2 && makeSubcommands?.has(words[1].toLowerCase())) {\r\n return 'command';\r\n }\r\n // \"make something\" where something is a single word could be a target\r\n if (words.length === 2 && /^[a-z0-9_-]+$/i.test(words[1])) {\r\n return 'command';\r\n }\r\n // Otherwise, likely natural language (\"make it work\", \"make a file\")\r\n return 'ai';\r\n }\r\n\r\n // Special case for 'which' - almost always a command when alone or with one arg\r\n if (firstWord === 'which') {\r\n // \"which node\" - valid command\r\n if (words.length === 2 && /^[a-z0-9_.-]+$/i.test(words[1])) {\r\n return 'command';\r\n }\r\n // \"which libraries have I used\" - natural language\r\n if (words.length > 2) {\r\n return 'ai';\r\n }\r\n }\r\n\r\n // Special case for 'find' - needs path or expression flags\r\n if (firstWord === 'find') {\r\n // \"find . -name\" or \"find /path\" - command\r\n if (words.length >= 2 && (words[1].startsWith('.') || words[1].startsWith('/') || words[1].startsWith('-'))) {\r\n return 'command';\r\n }\r\n // \"find all bugs\" - natural language\r\n if (words.length > 2) {\r\n return 'ai';\r\n }\r\n }\r\n\r\n // Special case for 'export' - needs assignment\r\n if (firstWord === 'export') {\r\n // \"export VAR=value\" or \"export PATH\" - command\r\n if (words.length >= 2 && /^[A-Z_][A-Z0-9_]*/.test(words[1])) {\r\n return 'command';\r\n }\r\n // \"export the data\" - natural language\r\n return 'ai';\r\n }\r\n\r\n // Special case for 'run', 'start', 'stop', 'test'\r\n if (['run', 'start', 'stop', 'test'].includes(firstWord)) {\r\n // These are more often natural language unless they have specific patterns\r\n // \"run npm install\" - could be shorthand for script runner\r\n // \"run this code\" - natural language\r\n // \"start the server\" - ambiguous but likely natural language\r\n // \"test the api\" - natural language\r\n if (words.length >= 2) {\r\n // If followed by a known command, treat as command\r\n if (DEFINITE_COMMANDS.has(words[1].toLowerCase())) {\r\n return 'command';\r\n }\r\n // If followed by natural language markers, treat as AI\r\n if (NATURAL_LANGUAGE_MARKERS.has(words[1].toLowerCase())) {\r\n return 'ai';\r\n }\r\n }\r\n // Default to AI for these ambiguous words\r\n return 'ai';\r\n }\r\n\r\n // For other ambiguous commands:\r\n // Single word - could be a command, but safer to default to command (can be overridden)\r\n if (words.length === 1) {\r\n return 'command';\r\n }\r\n\r\n // Two words where second is a simple identifier - likely command\r\n if (words.length === 2 && /^[a-z0-9_.-]+$/i.test(words[1]) && !NATURAL_LANGUAGE_MARKERS.has(words[1].toLowerCase())) {\r\n return 'command';\r\n }\r\n\r\n // Default to AI for multi-word ambiguous commands\r\n return 'ai';\r\n}\r\n\r\n/**\r\n * Detects the intent of the user input using intelligent heuristics.\r\n * \r\n * Logic Priority:\r\n * 1. Slash Commands: If starts with '/', check if valid command -> AI\r\n * 2. Prefixes: '?' -> AI, '.', '/', '$', '~' -> Command\r\n * 3. Strong AI Indicators: Question marks, AI keywords\r\n * 4. Strong Command Syntax: Flags, pipes, redirects, quotes, env vars\r\n * 5. Definite Commands: Known command binaries that aren't ambiguous\r\n * 6. Ambiguous Command Disambiguation: Context-aware analysis\r\n * 7. Natural Language Detection: Sentence structure analysis\r\n * 8. Fallback: Multi-word without command syntax -> AI\r\n * \r\n * @param input The user input string\r\n * @returns 'command' | 'ai'\r\n */\r\nexport function detectIntent(input: string): InputIntent {\r\n const trimmed = input.trim();\r\n\r\n if (!trimmed) {\r\n return 'ai'; // Default to AI for empty/whitespace\r\n }\r\n\r\n // Check 0 - Slash Commands (Highest Priority)\r\n if (trimmed.startsWith('/')) {\r\n // Extract command name (remove '/' and take first word)\r\n const commandName = trimmed.slice(1).split(/\\s+/)[0].toLowerCase();\r\n if (SLASH_COMMANDS.has(commandName)) {\r\n return 'ai';\r\n }\r\n // If starts with '/' but not a valid slash command, assume it's a path -> Command\r\n return 'command';\r\n }\r\n\r\n // Check 1 - Explicit Prefixes\r\n if (trimmed.startsWith('?')) return 'ai';\r\n if (trimmed.startsWith('.') || trimmed.startsWith('$') || trimmed.startsWith('~')) return 'command';\r\n\r\n // Parse words for analysis\r\n const words = trimmed.split(/\\s+/);\r\n const firstWord = words[0].toLowerCase();\r\n\r\n // Check 2 - Strong AI Indicators (check BEFORE command matching)\r\n const isQuestion = trimmed.endsWith('?');\r\n const startsWithAIKeyword = AI_KEYWORDS.has(firstWord);\r\n\r\n if (startsWithAIKeyword) {\r\n // If starts with AI keyword, it's almost always AI\r\n // Exception: if it has strong command syntax, it might still be a command\r\n if (!hasCommandSyntax(trimmed, words)) {\r\n return 'ai';\r\n }\r\n }\r\n\r\n if (isQuestion) {\r\n // Questions are almost always AI\r\n // Exception: rare case of command with ? (like \"ls ?*.txt\" - but this is uncommon)\r\n if (!hasCommandSyntax(trimmed, words)) {\r\n return 'ai';\r\n }\r\n }\r\n\r\n // Check 3 - Strong Command Syntax (before command name matching)\r\n if (hasCommandSyntax(trimmed, words)) {\r\n return 'command';\r\n }\r\n\r\n // Check 4 - Definite Commands (non-ambiguous command names)\r\n if (DEFINITE_COMMANDS.has(firstWord)) {\r\n // Special handling for shell built-ins that might be followed by natural language\r\n // e.g., \"exit\" is a command, but \"exit the application\" is AI\r\n if (SHELL_BUILTINS.has(firstWord) && words.length > 1) {\r\n // Check if followed by natural language markers\r\n const secondWord = words[1].toLowerCase();\r\n if (NATURAL_LANGUAGE_MARKERS.has(secondWord)) {\r\n return 'ai';\r\n }\r\n // Check for \"exit/clear/history the ...\" pattern\r\n if (['the', 'this', 'that', 'my', 'your', 'our', 'all'].includes(secondWord)) {\r\n return 'ai';\r\n }\r\n }\r\n return 'command';\r\n }\r\n\r\n // Check 4.5 - Custom Commands (user-defined terminal commands)\r\n // Load custom commands synchronously for fast detection\r\n const customCommandsManager = CustomCommandsManager.getInstance();\r\n customCommandsManager.loadSync();\r\n if (customCommandsManager.hasCommand(firstWord)) {\r\n return 'command';\r\n }\r\n\r\n // Check 4.6 - Registered tunnel commands (supports multi-word prefixes)\r\n const tunnelCommandsManager = TunnelCommandsManager.getInstance();\r\n tunnelCommandsManager.loadSync();\r\n if (tunnelCommandsManager.matchCommand(trimmed)) {\r\n return 'command';\r\n }\r\n\r\n // Check 5 - Ambiguous Commands (need disambiguation)\r\n if (AMBIGUOUS_COMMANDS.has(firstWord)) {\r\n return disambiguateCommand(trimmed, words);\r\n }\r\n\r\n // Check 6 - Path-like strings\r\n // If it contains slashes and no spaces, it might be a path execution\r\n if ((trimmed.includes('/') || trimmed.includes('\\\\')) && !trimmed.includes(' ')) {\r\n return 'command';\r\n }\r\n\r\n // Check 7 - Natural Language Detection for unknown first words\r\n if (looksLikeNaturalLanguage(words)) {\r\n return 'ai';\r\n }\r\n\r\n // Check 8 - Fallback Heuristics\r\n\r\n // If it's a single word and NOT a known command/keyword:\r\n if (words.length === 1) {\r\n if (trimmed.includes('.')) return 'command'; // script.sh, main.py\r\n // Unknown single word - default to AI (safer for chat)\r\n return 'ai';\r\n }\r\n\r\n // Multiple words, no flags, no operators, no keywords, not natural language pattern\r\n // This is truly ambiguous - default to AI (safer for chat assistant)\r\n return 'ai';\r\n}\r\n"],"mappings":"AAOA,SAAS,6BAA6B;AACtC,SAAS,6BAA6B;AAKtC,MAAM,iBAAiB,oBAAI,IAAI;AAAA,EAC3B;AAAA,EAAQ;AAAA,EAAK;AAAA,EACb;AAAA,EAAS;AAAA,EAAK;AAAA,EACd;AAAA,EAAU;AAAA,EAAK;AAAA,EACf;AAAA,EAAS;AAAA,EAAO;AAAA,EAChB;AAAA,EACA;AAAA,EAAY;AAAA,EAAc;AAAA,EAC1B;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAChB;AAAA,EAAW;AAAA,EACX;AAAA,EACA;AAAA,EAAS;AAAA,EACT;AAAA,EACA;AAAA,EAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAAe;AAAA,EACf;AAAA,EAAmB;AAAA,EAAO;AAAA,EAC1B;AAAA,EACA;AAAA,EAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EAAa;AAAA,EACb;AAAA,EACA;AACJ,CAAC;AAGD,MAAM,oBAAoB,oBAAI,IAAI;AAAA;AAAA,EAE9B;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAY;AAAA,EAAO;AAAA;AAAA,EAEhG;AAAA,EAAO;AAAA,EAAW;AAAA,EAAa;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAU;AAAA,EAAU;AAAA,EAChF;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAO;AAAA,EAAW;AAAA;AAAA,EAEjF;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAAQ;AAAA;AAAA,EAElC;AAAA,EAAM;AAAA,EAAM;AAAA,EAAO;AAAA,EAAS;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAChG;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAY;AAAA,EAAW;AAAA,EAAY;AAAA,EAAM;AAAA,EAAY;AAAA,EAAS;AAAA,EAC1F;AAAA,EAAU;AAAA,EAAW;AAAA,EAAS;AAAA,EAAO;AAAA;AAAA,EAErC;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAM;AAAA,EAAU;AAAA,EAC7F;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAW;AAAA;AAAA,EAE5C;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAM;AAAA,EAAU;AAAA,EAAM;AAAA,EAC7E;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAS;AAAA,EAAW;AAAA,EAAU;AAAA,EAAU;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAErF;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAM;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAY;AAAA,EAAM;AAAA,EAAY;AAAA,EAC9G;AAAA,EAAO;AAAA,EAAS;AAAA,EAAM;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAa;AAAA,EAAgB;AAAA,EAClF;AAAA,EAAS;AAAA,EAAS;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAO;AAAA,EAAQ;AAAA;AAAA,EAEnE;AAAA,EAAS;AAAA,EAAU;AAAA,EAAkB;AAAA,EAAW;AAAA,EAAU;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAClH;AAAA,EAAS;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAW;AAAA,EAAU;AAAA,EAAU;AAAA,EAAO;AAAA;AAAA,EAEpF;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EACtB;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAc;AAAA,EAAQ;AAAA,EAC1D;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA;AAAA,EAE7B;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAU;AAAA,EAAS;AAAA,EACrC;AAAA,EAAS;AAAA,EAAW;AAAA,EAAW;AAAA,EAC/B;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAS;AAAA,EACpC;AAAA,EAAU;AAAA,EAAW;AAAA,EAAU;AAAA,EAAS;AAAA,EACxC;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAM;AAAA,EAAU;AAAA,EAAW;AAAA,EACzC;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAM;AAAA,EAC/B;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAW;AAAA,EAAW;AAAA,EAChD;AAAA,EAAW;AAAA,EAAS;AAAA,EAAS;AAAA,EAAQ;AAAA;AAAA,EAErC;AAAA,EAAS;AAAA,EAAU;AAAA,EAAU;AAAA,EAAM;AAAA,EAAS;AAAA,EAAU;AAAA,EAAK;AAAA,EAAO;AAAA,EAAQ;AAAA,EAC1E;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAU;AAAA,EAC3C;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAW;AAAA;AAAA,EAE/C;AAAA,EAAO;AAAA,EAAO;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAM;AAAA,EAAO;AAAA,EAAS;AAAA,EAAW;AAAA,EAAM;AAAA,EAAQ;AAAA;AAAA,EAExF;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA;AAAA,EAEnF;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAW;AAAA,EAAO;AAAA,EAAM;AAAA,EAChE;AAAA,EAAU;AAAA,EAAY;AAAA,EAAU;AAAA,EAAS;AAAA,EAAU;AAAA,EAAM;AAAA,EAAS;AAAA;AAAA,EAElE;AAAA,EAAM;AAAA,EAAM;AAAA,EAAW;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAM;AAAA;AAAA,EAE3D;AAAA,EAAO;AAAA,EAAM;AAAA,EAAU;AAAA,EAAa;AAAA,EAAW;AAAA,EAAoB;AAAA,EAAW;AAAA,EAAQ;AAAA,EACtF;AAAA,EAAU;AAAA,EAAO;AAAA,EAAO;AAAA,EAAc;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA;AAAA,EAEpE;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAW;AAAA,EAAa;AAAA,EAAW;AAAA,EAAW;AAAA;AAAA,EAElF;AAAA,EAAW;AAAA,EAAW;AAAA,EAAS;AAAA,EAAW;AAAA,EAAS;AAAA,EAAO;AAAA,EAAc;AAAA,EAAa;AAAA;AAAA,EAErF;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAO;AAAA,EAAW;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAU;AAAA,EAC1E;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAS;AAAA,EAAU;AAAA,EAAW;AAAA;AAAA,EAEhD;AAAA,EAAM;AAAA,EAAS;AAAA,EAAU;AAAA;AAAA,EAEzB;AAAA,EAAS;AAAA,EAAU;AAAA,EAAW;AAAA;AAAA,EAE9B;AAAA,EAAS;AAAA,EAAY;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC3E;AAAA,EAAa;AAAA,EAAS;AAAA,EAAU;AAAA,EAAY;AAAA,EAAS;AAAA,EAAU;AAAA;AAAA,EAE/D;AAAA,EAAa;AAAA,EAAW;AAAA,EAAc;AAAA,EAAY;AAAA,EAAa;AAAA,EAAe;AAAA;AAAA,EAE9E;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAW;AAAA,EAAS;AAAA;AAAA,EAEnF;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAU;AAAA,EAAU;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAC5E;AAAA,EAAS;AAAA,EAAY;AAAA,EAAU;AAAA,EAAS;AAAA,EACxC;AAAA,EAAY;AAAA,EAAY;AAAA,EAAc;AAAA,EAAY;AAAA,EAAS;AAAA,EAC3D;AAAA,EAAO;AAAA,EAAW;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAW;AAAA,EAAM;AAAA,EAChE;AAAA,EAAU;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAY;AAAA,EAAU;AAAA,EAAS;AAAA,EACnE;AAAA,EAAO;AAAA,EAAW;AAAA,EAAW;AAAA,EAAS;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA;AAAA,EAE1E;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAO;AAAA;AAAA,EAE9C;AAAA,EAAe;AAAA,EAAW;AAAA,EAAW;AAAA;AAAA,EAErC;AAAA,EAAU;AAAA,EAAU;AAAA,EAAO;AAAA,EAAW;AAAA,EAAO;AAAA,EAAO;AAAA,EAAS;AAAA,EAAc;AAAA,EAAa;AAAA;AAAA,EAExF;AAAA,EAAO;AAAA,EAAW;AAAA,EAAU;AAAA,EAAa;AAAA,EAAY;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAO;AAAA;AAAA,EAEhF;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAW;AAAA,EAAY;AAAA,EACtD;AAAA,EAAO;AAAA,EAAO;AAAA,EAAU;AAAA,EAAM;AAAA,EAAM;AAAA,EACpC;AAAA,EAAS;AAAA,EAAU;AAAA;AAAA,EAEnB;AAAA,EAAU;AAAA,EAAW;AAAA,EAAW;AAAA,EAAY;AAAA,EAAU;AAAA,EAAU;AAAA,EAAS;AAAA,EAAY;AAAA,EACrF;AAAA,EAAc;AAAA,EAAU;AAAA,EAAU;AACtC,CAAC;AAID,MAAM,iBAAiB,oBAAI,IAAI;AAAA,EAC3B;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAU;AAAA,EAAS;AAAA,EACrC;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAU;AAAA,EACtC;AAAA,EAAS;AAAA,EAAQ;AAAA,EACjB;AAAA,EAAW;AAAA,EACX;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAC/B;AAAA,EAAO;AAAA,EAAY;AAAA,EAAU;AAAA,EAAO;AAAA,EACpC;AAAA,EAAS;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAW;AAAA,EACvC;AAAA,EAAS;AAAA,EAAS;AACtB,CAAC;AAGD,MAAM,qBAAqB,oBAAI,IAAI;AAAA,EAC/B;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EACjC;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAO;AAAA,EACvC;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAQ;AAAA,EAClC;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAS;AAAA,EAAQ;AAAA,EAC1D;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAO;AAAA,EACzC;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAQ;AACxC,CAAC;AAGD,MAAM,cAAc,oBAAI,IAAI;AAAA;AAAA,EAExB;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAO;AAAA,EAAS;AAAA;AAAA,EAEvD;AAAA,EAAS;AAAA,EAAU;AAAA,EAAY;AAAA,EAAa;AAAA,EAAY;AAAA,EACxD;AAAA,EAAW;AAAA,EAAY;AAAA,EAAW;AAAA,EAAW;AAAA,EAAU;AAAA,EACvD;AAAA,EAAO;AAAA,EAAS;AAAA,EAAS;AAAA,EAAW;AAAA,EACpC;AAAA,EAAY;AAAA,EAAW;AAAA,EAAY;AAAA,EACnC;AAAA,EAAU;AAAA,EACV;AAAA,EAAa;AAAA,EAAW;AAAA,EACxB;AAAA,EAAa;AAAA,EAAY;AAAA,EACzB;AAAA,EAAO;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA;AAAA,EAE/C;AAAA,EAAO;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAErD;AAAA,EAAO;AAAA,EAAM;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAU;AAAA;AAAA,EAElD;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAW;AAC1D,CAAC;AAGD,MAAM,2BAA2B,oBAAI,IAAI;AAAA;AAAA,EAErC;AAAA,EAAK;AAAA,EAAM;AAAA;AAAA,EAEX;AAAA,EAAK;AAAA,EAAM;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAM;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAC1E;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA;AAAA,EAEzB;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAU;AAAA,EAAU;AAAA;AAAA,EAEvE;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAAW;AAAA,EAAM;AAAA,EAAQ;AAAA;AAAA,EAEnD;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAQ;AAAA,EAC1C;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAS;AAAA,EAC9B;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EACtB;AAAA,EAAO;AAAA,EAAO;AAAA;AAAA,EAEd;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AACrE,CAAC;AAGD,MAAM,sBAAgD,oBAAI,IAAI;AAAA,EAC1D,CAAC,OAAO,oBAAI,IAAI,CAAC,OAAO,UAAU,QAAQ,QAAQ,SAAS,YAAY,UAAU,SAAS,UAAU,SAAS,SAAS,OAAO,QAAQ,UAAU,QAAQ,UAAU,SAAS,OAAO,QAAQ,MAAM,MAAM,UAAU,SAAS,eAAe,UAAU,SAAS,MAAM,UAAU,YAAY,aAAa,UAAU,QAAQ,SAAS,CAAC,CAAC;AAAA,EAChU,CAAC,OAAO,oBAAI,IAAI,CAAC,WAAW,KAAK,aAAa,MAAM,UAAU,MAAM,OAAO,SAAS,QAAQ,SAAS,QAAQ,WAAW,QAAQ,QAAQ,UAAU,MAAM,QAAQ,YAAY,SAAS,SAAS,UAAU,QAAQ,WAAW,MAAM,QAAQ,UAAU,cAAc,OAAO,UAAU,SAAS,cAAc,WAAW,SAAS,UAAU,UAAU,SAAS,SAAS,UAAU,QAAQ,aAAa,aAAa,YAAY,QAAQ,UAAU,UAAU,WAAW,cAAc,QAAQ,QAAQ,OAAO,QAAQ,UAAU,WAAW,WAAW,QAAQ,QAAQ,QAAQ,SAAS,UAAU,QAAQ,QAAQ,QAAQ,SAAS,CAAC,CAAC;AAAA,EAC7lB,CAAC,QAAQ,oBAAI,IAAI,CAAC,OAAO,UAAU,WAAW,OAAO,SAAS,QAAQ,SAAS,QAAQ,WAAW,QAAQ,UAAU,QAAQ,YAAY,SAAS,SAAS,UAAU,QAAQ,WAAW,WAAW,uBAAuB,OAAO,cAAc,OAAO,UAAU,OAAO,QAAQ,UAAU,MAAM,CAAC,CAAC;AAAA,EAChS,CAAC,QAAQ,oBAAI,IAAI,CAAC,OAAO,UAAU,WAAW,KAAK,OAAO,SAAS,QAAQ,SAAS,QAAQ,WAAW,QAAQ,UAAU,QAAQ,MAAM,YAAY,SAAS,SAAS,UAAU,QAAQ,WAAW,UAAU,MAAM,OAAO,OAAO,UAAU,QAAQ,SAAS,UAAU,SAAS,SAAS,SAAS,CAAC,CAAC;AAAA,EAClS,CAAC,UAAU,oBAAI,IAAI,CAAC,OAAO,QAAQ,SAAS,QAAQ,QAAQ,UAAU,MAAM,QAAQ,SAAS,WAAW,MAAM,OAAO,QAAQ,WAAW,WAAW,UAAU,WAAW,UAAU,aAAa,SAAS,SAAS,UAAU,OAAO,QAAQ,QAAQ,UAAU,UAAU,UAAU,MAAM,UAAU,QAAQ,UAAU,WAAW,QAAQ,QAAQ,SAAS,WAAW,QAAQ,UAAU,SAAS,OAAO,UAAU,QAAQ,UAAU,WAAW,UAAU,UAAU,WAAW,YAAY,UAAU,UAAU,UAAU,WAAW,SAAS,SAAS,SAAS,SAAS,CAAC,CAAC;AAAA,EACpiB,CAAC,WAAW,oBAAI,IAAI,CAAC,OAAO,YAAY,UAAU,SAAS,UAAU,QAAQ,QAAQ,QAAQ,gBAAgB,SAAS,OAAO,UAAU,SAAS,WAAW,OAAO,WAAW,gBAAgB,OAAO,UAAU,YAAY,SAAS,SAAS,SAAS,YAAY,UAAU,MAAM,UAAU,QAAQ,aAAa,eAAe,cAAc,SAAS,QAAQ,aAAa,SAAS,UAAU,WAAW,WAAW,QAAQ,iBAAiB,cAAc,CAAC,CAAC;AAAA,EAC7b,CAAC,MAAM,oBAAI,IAAI,CAAC,SAAS,OAAO,QAAQ,OAAO,WAAW,OAAO,OAAO,OAAO,YAAY,SAAS,OAAO,WAAW,QAAQ,QAAQ,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC;AAAA,EACnK,CAAC,SAAS,oBAAI,IAAI,CAAC,SAAS,OAAO,QAAQ,OAAO,QAAQ,OAAO,UAAU,UAAU,UAAU,WAAW,WAAW,aAAa,SAAS,SAAS,OAAO,SAAS,SAAS,OAAO,OAAO,UAAU,QAAQ,UAAU,kBAAkB,WAAW,QAAQ,QAAQ,SAAS,UAAU,SAAS,WAAW,qBAAqB,kBAAkB,YAAY,SAAS,iBAAiB,QAAQ,CAAC,CAAC;AAAA,EAClY,CAAC,OAAO,oBAAI,IAAI,CAAC,WAAW,aAAa,YAAY,UAAU,QAAQ,QAAQ,UAAU,SAAS,QAAQ,SAAS,UAAU,SAAS,SAAS,SAAS,QAAQ,YAAY,CAAC,CAAC;AAAA,EAC9K,CAAC,QAAQ,oBAAI,IAAI,CAAC,WAAW,aAAa,YAAY,UAAU,QAAQ,QAAQ,UAAU,SAAS,QAAQ,SAAS,UAAU,SAAS,SAAS,SAAS,QAAQ,YAAY,CAAC,CAAC;AAAA,EAC/K,CAAC,OAAO,oBAAI,IAAI,CAAC,MAAM,OAAO,UAAU,OAAO,OAAO,YAAY,kBAAkB,OAAO,OAAO,OAAO,OAAO,cAAc,WAAW,cAAc,WAAW,kBAAkB,OAAO,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,EACvN,CAAC,MAAM,oBAAI,IAAI,CAAC,SAAS,UAAU,WAAW,SAAS,MAAM,WAAW,WAAW,UAAU,eAAe,OAAO,OAAO,OAAO,YAAY,YAAY,WAAW,YAAY,QAAQ,MAAM,aAAa,QAAQ,SAAS,CAAC,CAAC;AAAA,EAC9N,CAAC,UAAU,oBAAI,IAAI,CAAC,QAAQ,UAAU,WAAW,aAAa,aAAa,OAAO,OAAO,OAAO,WAAW,UAAU,OAAO,YAAY,YAAY,UAAU,UAAU,cAAc,QAAQ,WAAW,QAAQ,MAAM,CAAC,CAAC;AAAA,EACzN,CAAC,aAAa,oBAAI,IAAI,CAAC,QAAQ,QAAQ,SAAS,WAAW,YAAY,OAAO,QAAQ,UAAU,WAAW,UAAU,SAAS,aAAa,aAAa,SAAS,SAAS,WAAW,WAAW,gBAAgB,OAAO,SAAS,UAAU,WAAW,MAAM,CAAC,CAAC;AAAA,EAC7P,CAAC,QAAQ,oBAAI,IAAI,CAAC,OAAO,SAAS,SAAS,WAAW,aAAa,QAAQ,SAAS,QAAQ,aAAa,MAAM,CAAC,CAAC;AAAA,EACjH,CAAC,QAAQ,oBAAI,IAAI,CAAC,CAAC,CAAC;AAAA;AAAA,EACpB,CAAC,SAAS,oBAAI,IAAI,CAAC,CAAC,CAAC;AAAA;AACzB,CAAC;AAKD,SAAS,yBAAyB,OAA0B;AACxD,MAAI,MAAM,SAAS,EAAG,QAAO;AAE7B,QAAM,aAAa,MAAM,IAAI,OAAK,EAAE,YAAY,CAAC;AAGjD,MAAI,cAAc;AAClB,aAAW,QAAQ,YAAY;AAC3B,QAAI,yBAAyB,IAAI,IAAI,GAAG;AACpC;AAAA,IACJ;AAAA,EACJ;AAGA,MAAI,eAAe,KAAK,KAAK,MAAM,SAAS,GAAG,GAAG;AAC9C,WAAO;AAAA,EACX;AAIA,MAAI,WAAW,UAAU,KAAK,CAAC,KAAK,MAAM,OAAO,MAAM,MAAM,QAAQ,KAAK,EAAE,SAAS,WAAW,CAAC,CAAC,GAAG;AACjG,WAAO;AAAA,EACX;AAGA,MAAI,WAAW,UAAU,KACrB,mBAAmB,IAAI,WAAW,CAAC,CAAC,KACpC,yBAAyB,IAAI,WAAW,CAAC,CAAC,GAAG;AAC7C,WAAO;AAAA,EACX;AAGA,MAAI,WAAW,SAAS,GAAG,KAAK,WAAW,QAAQ,GAAG,IAAI,GAAG;AACzD,WAAO;AAAA,EACX;AAGA,MAAI,MAAM,UAAU,KAAK,eAAe,GAAG;AACvC,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAKA,SAAS,iBAAiB,OAAe,OAA0B;AAC/D,QAAM,UAAU,MAAM,KAAK;AAC3B,QAAM,YAAY,MAAM,CAAC,GAAG,YAAY,KAAK;AAG7C,QAAM,WAAW,2BAA2B,KAAK,KAAK,KACjD,MAAM,UAAU,KAAK,aAAa,KAAK,MAAM,CAAC,CAAC;AAGpD,QAAM,eAAe,4DAA4D,KAAK,KAAK;AAG3F,QAAM,eAAe,+BAA+B,KAAK,KAAK,KAAK,gCAAgC,KAAK,KAAK;AAG7G,QAAM,oBAAoB,sBAAsB,KAAK,KAAK,KAAK,2BAA2B,KAAK,KAAK;AAGpG,QAAM,iBAAiB,sCAAsC,KAAK,KAAK;AAGvE,QAAM,iBAAiB,8BAA8B,KAAK,KAAK;AAG/D,QAAM,kBAAkB,0BAA0B,KAAK,KAAK;AAG5D,QAAM,YAAY,gEAAgE,KAAK,KAAK;AAK5F,QAAM,cAAc,uCAAuC,KAAK,OAAO;AAGvE,QAAM,mBAAmB,WAAW,KAAK,OAAO;AAGhD,QAAM,kBAAkB,eAAe,KAAK,KAAK;AAGjD,QAAM,yBAAyB,sBAAsB,KAAK,KAAK;AAG/D,QAAM,kBAAkB,qCAAqC,KAAK,OAAO;AAGzE,QAAM,gBAAgB,oCAAoC,KAAK,OAAO;AAGtE,QAAM,eAAe,0BAA0B,KAAK,OAAO;AAG3D,QAAM,qBAAqB,mCAAmC,KAAK,OAAO;AAG1E,QAAM,kBAAkB,8BAA8B,KAAK,OAAO;AAGlE,QAAM,YAAY,iBAAiB,KAAK,OAAO;AAG/C,MAAI,MAAM,UAAU,GAAG;AACnB,UAAM,aAAa,MAAM,CAAC,EAAE,YAAY;AACxC,UAAM,cAAc,oBAAoB,IAAI,SAAS;AACrD,QAAI,eAAe,YAAY,IAAI,UAAU,GAAG;AAC5C,aAAO;AAAA,IACX;AAAA,EACJ;AAGA,MAAI,MAAM,WAAW,KAAK,eAAe,IAAI,SAAS,GAAG;AACrD,WAAO;AAAA,EACX;AAEA,SAAO,YAAY,gBAAgB,gBAAgB,qBAC/C,kBAAkB,kBAAkB,mBAAmB,aACvD,eAAe,oBAAoB,mBAAmB,0BACtD,mBAAmB,iBAAiB,gBAAgB,sBACpD,mBAAmB;AAC3B;AAKA,SAAS,oBAAoB,OAAe,OAA8B;AACtE,QAAM,YAAY,MAAM,CAAC,EAAE,YAAY;AAGvC,MAAI,iBAAiB,OAAO,KAAK,GAAG;AAChC,WAAO;AAAA,EACX;AAGA,MAAI,yBAAyB,KAAK,GAAG;AACjC,WAAO;AAAA,EACX;AAGA,MAAI,cAAc,QAAQ;AAEtB,UAAM,kBAAkB,oBAAoB,IAAI,MAAM;AACtD,QAAI,MAAM,UAAU,KAAK,iBAAiB,IAAI,MAAM,CAAC,EAAE,YAAY,CAAC,GAAG;AACnE,aAAO;AAAA,IACX;AAEA,QAAI,MAAM,WAAW,KAAK,iBAAiB,KAAK,MAAM,CAAC,CAAC,GAAG;AACvD,aAAO;AAAA,IACX;AAEA,WAAO;AAAA,EACX;AAGA,MAAI,cAAc,SAAS;AAEvB,QAAI,MAAM,WAAW,KAAK,kBAAkB,KAAK,MAAM,CAAC,CAAC,GAAG;AACxD,aAAO;AAAA,IACX;AAEA,QAAI,MAAM,SAAS,GAAG;AAClB,aAAO;AAAA,IACX;AAAA,EACJ;AAGA,MAAI,cAAc,QAAQ;AAEtB,QAAI,MAAM,UAAU,MAAM,MAAM,CAAC,EAAE,WAAW,GAAG,KAAK,MAAM,CAAC,EAAE,WAAW,GAAG,KAAK,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI;AACzG,aAAO;AAAA,IACX;AAEA,QAAI,MAAM,SAAS,GAAG;AAClB,aAAO;AAAA,IACX;AAAA,EACJ;AAGA,MAAI,cAAc,UAAU;AAExB,QAAI,MAAM,UAAU,KAAK,oBAAoB,KAAK,MAAM,CAAC,CAAC,GAAG;AACzD,aAAO;AAAA,IACX;AAEA,WAAO;AAAA,EACX;AAGA,MAAI,CAAC,OAAO,SAAS,QAAQ,MAAM,EAAE,SAAS,SAAS,GAAG;AAMtD,QAAI,MAAM,UAAU,GAAG;AAEnB,UAAI,kBAAkB,IAAI,MAAM,CAAC,EAAE,YAAY,CAAC,GAAG;AAC/C,eAAO;AAAA,MACX;AAEA,UAAI,yBAAyB,IAAI,MAAM,CAAC,EAAE,YAAY,CAAC,GAAG;AACtD,eAAO;AAAA,MACX;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAIA,MAAI,MAAM,WAAW,GAAG;AACpB,WAAO;AAAA,EACX;AAGA,MAAI,MAAM,WAAW,KAAK,kBAAkB,KAAK,MAAM,CAAC,CAAC,KAAK,CAAC,yBAAyB,IAAI,MAAM,CAAC,EAAE,YAAY,CAAC,GAAG;AACjH,WAAO;AAAA,EACX;AAGA,SAAO;AACX;AAkBO,SAAS,aAAa,OAA4B;AACrD,QAAM,UAAU,MAAM,KAAK;AAE3B,MAAI,CAAC,SAAS;AACV,WAAO;AAAA,EACX;AAGA,MAAI,QAAQ,WAAW,GAAG,GAAG;AAEzB,UAAM,cAAc,QAAQ,MAAM,CAAC,EAAE,MAAM,KAAK,EAAE,CAAC,EAAE,YAAY;AACjE,QAAI,eAAe,IAAI,WAAW,GAAG;AACjC,aAAO;AAAA,IACX;AAEA,WAAO;AAAA,EACX;AAGA,MAAI,QAAQ,WAAW,GAAG,EAAG,QAAO;AACpC,MAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,GAAG,EAAG,QAAO;AAG1F,QAAM,QAAQ,QAAQ,MAAM,KAAK;AACjC,QAAM,YAAY,MAAM,CAAC,EAAE,YAAY;AAGvC,QAAM,aAAa,QAAQ,SAAS,GAAG;AACvC,QAAM,sBAAsB,YAAY,IAAI,SAAS;AAErD,MAAI,qBAAqB;AAGrB,QAAI,CAAC,iBAAiB,SAAS,KAAK,GAAG;AACnC,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,MAAI,YAAY;AAGZ,QAAI,CAAC,iBAAiB,SAAS,KAAK,GAAG;AACnC,aAAO;AAAA,IACX;AAAA,EACJ;AAGA,MAAI,iBAAiB,SAAS,KAAK,GAAG;AAClC,WAAO;AAAA,EACX;AAGA,MAAI,kBAAkB,IAAI,SAAS,GAAG;AAGlC,QAAI,eAAe,IAAI,SAAS,KAAK,MAAM,SAAS,GAAG;AAEnD,YAAM,aAAa,MAAM,CAAC,EAAE,YAAY;AACxC,UAAI,yBAAyB,IAAI,UAAU,GAAG;AAC1C,eAAO;AAAA,MACX;AAEA,UAAI,CAAC,OAAO,QAAQ,QAAQ,MAAM,QAAQ,OAAO,KAAK,EAAE,SAAS,UAAU,GAAG;AAC1E,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAIA,QAAM,wBAAwB,sBAAsB,YAAY;AAChE,wBAAsB,SAAS;AAC/B,MAAI,sBAAsB,WAAW,SAAS,GAAG;AAC7C,WAAO;AAAA,EACX;AAGA,QAAM,wBAAwB,sBAAsB,YAAY;AAChE,wBAAsB,SAAS;AAC/B,MAAI,sBAAsB,aAAa,OAAO,GAAG;AAC7C,WAAO;AAAA,EACX;AAGA,MAAI,mBAAmB,IAAI,SAAS,GAAG;AACnC,WAAO,oBAAoB,SAAS,KAAK;AAAA,EAC7C;AAIA,OAAK,QAAQ,SAAS,GAAG,KAAK,QAAQ,SAAS,IAAI,MAAM,CAAC,QAAQ,SAAS,GAAG,GAAG;AAC7E,WAAO;AAAA,EACX;AAGA,MAAI,yBAAyB,KAAK,GAAG;AACjC,WAAO;AAAA,EACX;AAKA,MAAI,MAAM,WAAW,GAAG;AACpB,QAAI,QAAQ,SAAS,GAAG,EAAG,QAAO;AAElC,WAAO;AAAA,EACX;AAIA,SAAO;AACX;","names":[]}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
import { quickLog } from "./conversation-logger.js";
|
|
5
|
+
const DEFAULT_TRUNCATION_THRESHOLD = 3e4;
|
|
6
|
+
const HEAD_FRACTION = 0.2;
|
|
7
|
+
const TAIL_FRACTION = 0.8;
|
|
8
|
+
const TOOL_OUTPUTS_DIR_NAME = "tool-outputs";
|
|
9
|
+
const STALE_SESSION_MAX_AGE_MS = 48 * 60 * 60 * 1e3;
|
|
10
|
+
const TRUNCATION_EXEMPT_TOOLS = /* @__PURE__ */ new Set([
|
|
11
|
+
"write_to_file",
|
|
12
|
+
"edit_file",
|
|
13
|
+
"multi_edit_file",
|
|
14
|
+
"create_plan",
|
|
15
|
+
"mark_task_complete",
|
|
16
|
+
"plan_ask_question",
|
|
17
|
+
"todo_write",
|
|
18
|
+
"task_complete",
|
|
19
|
+
"create_image"
|
|
20
|
+
]);
|
|
21
|
+
function getToolOutputsBaseDir() {
|
|
22
|
+
return path.join(os.homedir(), ".centaurus", TOOL_OUTPUTS_DIR_NAME);
|
|
23
|
+
}
|
|
24
|
+
function getSessionDir(chatId) {
|
|
25
|
+
const baseDir = getToolOutputsBaseDir();
|
|
26
|
+
const sessionDir = path.join(baseDir, chatId || "_no_chat");
|
|
27
|
+
return sessionDir;
|
|
28
|
+
}
|
|
29
|
+
function ensureDir(dirPath) {
|
|
30
|
+
try {
|
|
31
|
+
if (!fs.existsSync(dirPath)) {
|
|
32
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
quickLog(`[OutputTruncation] Failed to create directory ${dirPath}: ${error}
|
|
37
|
+
`);
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function truncateWithHeadTail(content, threshold = DEFAULT_TRUNCATION_THRESHOLD, outputFilePath, isRemoteContext) {
|
|
42
|
+
if (!content || content.length <= threshold) {
|
|
43
|
+
return content;
|
|
44
|
+
}
|
|
45
|
+
const headChars = Math.floor(threshold * HEAD_FRACTION);
|
|
46
|
+
const tailChars = threshold - headChars;
|
|
47
|
+
const head = content.slice(0, headChars);
|
|
48
|
+
const tail = content.slice(-tailChars);
|
|
49
|
+
const omittedChars = content.length - headChars - tailChars;
|
|
50
|
+
let marker;
|
|
51
|
+
if (outputFilePath) {
|
|
52
|
+
if (isRemoteContext) {
|
|
53
|
+
marker = `
|
|
54
|
+
|
|
55
|
+
... [${omittedChars.toLocaleString()} characters omitted \u2014 full output saved to LOCAL machine: ${outputFilePath} \u2014 use view_file with Environment="local" to read it] ...
|
|
56
|
+
|
|
57
|
+
`;
|
|
58
|
+
} else {
|
|
59
|
+
marker = `
|
|
60
|
+
|
|
61
|
+
... [${omittedChars.toLocaleString()} characters omitted \u2014 full output saved to: ${outputFilePath}] ...
|
|
62
|
+
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
marker = `
|
|
67
|
+
|
|
68
|
+
... [${omittedChars.toLocaleString()} characters omitted] ...
|
|
69
|
+
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
return head + marker + tail;
|
|
73
|
+
}
|
|
74
|
+
function saveFullOutput(content, toolName, chatId) {
|
|
75
|
+
try {
|
|
76
|
+
const sessionDir = getSessionDir(chatId);
|
|
77
|
+
if (!ensureDir(sessionDir)) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const safeName = toolName.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase();
|
|
81
|
+
const timestamp = Date.now();
|
|
82
|
+
const shortId = Math.random().toString(36).substring(2, 8);
|
|
83
|
+
const fileName = `${safeName}_${timestamp}_${shortId}.txt`;
|
|
84
|
+
const filePath = path.join(sessionDir, fileName);
|
|
85
|
+
fs.writeFileSync(filePath, content, "utf-8");
|
|
86
|
+
quickLog(`[OutputTruncation] Saved full output (${content.length} chars) to ${filePath}
|
|
87
|
+
`);
|
|
88
|
+
return filePath;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
quickLog(`[OutputTruncation] Failed to save output: ${error}
|
|
91
|
+
`);
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function truncateToolOutput(toolName, result, chatId, threshold = DEFAULT_TRUNCATION_THRESHOLD, isRemoteContext = false) {
|
|
96
|
+
if (typeof result !== "string") {
|
|
97
|
+
try {
|
|
98
|
+
const str = JSON.stringify(result);
|
|
99
|
+
if (str.length <= threshold) return result;
|
|
100
|
+
const savedPath2 = saveFullOutput(str, toolName, chatId);
|
|
101
|
+
return truncateWithHeadTail(str, threshold, savedPath2 ?? void 0, isRemoteContext);
|
|
102
|
+
} catch {
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (TRUNCATION_EXEMPT_TOOLS.has(toolName)) {
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
if (result.length <= threshold) {
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
const savedPath = saveFullOutput(result, toolName, chatId);
|
|
113
|
+
return truncateWithHeadTail(result, threshold, savedPath ?? void 0, isRemoteContext);
|
|
114
|
+
}
|
|
115
|
+
function cleanupToolOutputsForChat(chatId) {
|
|
116
|
+
try {
|
|
117
|
+
const sessionDir = getSessionDir(chatId);
|
|
118
|
+
if (fs.existsSync(sessionDir)) {
|
|
119
|
+
fs.rmSync(sessionDir, { recursive: true, force: true });
|
|
120
|
+
quickLog(`[OutputTruncation] Cleaned up tool outputs for chat ${chatId}
|
|
121
|
+
`);
|
|
122
|
+
}
|
|
123
|
+
} catch (error) {
|
|
124
|
+
quickLog(`[OutputTruncation] Failed to clean up tool outputs for chat ${chatId}: ${error}
|
|
125
|
+
`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function cleanupOrphanedToolOutputs() {
|
|
129
|
+
try {
|
|
130
|
+
const noChatDir = getSessionDir(null);
|
|
131
|
+
if (fs.existsSync(noChatDir)) {
|
|
132
|
+
fs.rmSync(noChatDir, { recursive: true, force: true });
|
|
133
|
+
quickLog(`[OutputTruncation] Cleaned up orphaned (no-chat) tool outputs
|
|
134
|
+
`);
|
|
135
|
+
}
|
|
136
|
+
} catch (error) {
|
|
137
|
+
quickLog(`[OutputTruncation] Failed to clean up orphaned outputs: ${error}
|
|
138
|
+
`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function cleanupStaleToolOutputs() {
|
|
142
|
+
try {
|
|
143
|
+
const baseDir = getToolOutputsBaseDir();
|
|
144
|
+
if (!fs.existsSync(baseDir)) return;
|
|
145
|
+
const now = Date.now();
|
|
146
|
+
const entries = fs.readdirSync(baseDir, { withFileTypes: true });
|
|
147
|
+
for (const entry of entries) {
|
|
148
|
+
if (!entry.isDirectory()) continue;
|
|
149
|
+
const dirPath = path.join(baseDir, entry.name);
|
|
150
|
+
try {
|
|
151
|
+
const stat = fs.statSync(dirPath);
|
|
152
|
+
const age = now - stat.mtimeMs;
|
|
153
|
+
if (age > STALE_SESSION_MAX_AGE_MS) {
|
|
154
|
+
fs.rmSync(dirPath, { recursive: true, force: true });
|
|
155
|
+
quickLog(`[OutputTruncation] Cleaned up stale session dir: ${entry.name} (age: ${Math.round(age / 36e5)}h)
|
|
156
|
+
`);
|
|
157
|
+
}
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} catch (error) {
|
|
162
|
+
quickLog(`[OutputTruncation] Failed to clean up stale outputs: ${error}
|
|
163
|
+
`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
export {
|
|
167
|
+
DEFAULT_TRUNCATION_THRESHOLD,
|
|
168
|
+
cleanupOrphanedToolOutputs,
|
|
169
|
+
cleanupStaleToolOutputs,
|
|
170
|
+
cleanupToolOutputsForChat,
|
|
171
|
+
saveFullOutput,
|
|
172
|
+
truncateToolOutput,
|
|
173
|
+
truncateWithHeadTail
|
|
174
|
+
};
|
|
175
|
+
//# sourceMappingURL=output-truncation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/output-truncation.ts"],"sourcesContent":["/**\r\n * Output Truncation Utility\r\n * \r\n * Handles truncation of large tool outputs to prevent context window bloat.\r\n * Follows the Gemini CLI approach: head+tail truncation with full output\r\n * saved to a retrievable file.\r\n * \r\n * Strategy:\r\n * - Threshold: 30,000 characters (~7,500 tokens) per tool output\r\n * - Split: 20% head / 80% tail (tail usually has errors, results, summaries)\r\n * - Full output saved to ~/.centaurus/tool-outputs/{chatId}/{toolName}_{id}.txt\r\n * - Truncated result includes the file path so AI can read it if needed\r\n * \r\n * Storage:\r\n * - Tool output files live at ~/.centaurus/tool-outputs/{chatId}/\r\n * - Cleaned up when: chat is deleted, new chat started, or stale cleanup on startup\r\n * - Follows same pattern as checkpoints (~/.centaurus/checkpoints/{chatId}/)\r\n */\r\n\r\nimport * as fs from 'fs';\r\nimport * as path from 'path';\r\nimport * as os from 'os';\r\nimport { quickLog } from './conversation-logger.js';\r\n\r\n// ============================================================================\r\n// CONSTANTS\r\n// ============================================================================\r\n\r\n/** Default maximum characters per tool output before truncation kicks in */\r\nexport const DEFAULT_TRUNCATION_THRESHOLD = 30_000;\r\n\r\n/** Fraction of the budget allocated to the head (beginning) of the output */\r\nconst HEAD_FRACTION = 0.2;\r\n\r\n/** Fraction of the budget allocated to the tail (end) of the output */\r\nconst TAIL_FRACTION = 0.8;\r\n\r\n/** Base directory for tool output files */\r\nconst TOOL_OUTPUTS_DIR_NAME = 'tool-outputs';\r\n\r\n/** Max age for orphaned session directories (48 hours) */\r\nconst STALE_SESSION_MAX_AGE_MS = 48 * 60 * 60 * 1000;\r\n\r\n/** Tools that should NEVER be truncated (already handled elsewhere or always small) */\r\nconst TRUNCATION_EXEMPT_TOOLS = new Set([\r\n 'write_to_file',\r\n 'edit_file',\r\n 'multi_edit_file',\r\n 'create_plan',\r\n 'mark_task_complete',\r\n 'plan_ask_question',\r\n 'todo_write',\r\n 'task_complete',\r\n 'create_image',\r\n]);\r\n\r\n// ============================================================================\r\n// DIRECTORY MANAGEMENT\r\n// ============================================================================\r\n\r\n/**\r\n * Get the base directory for all tool output storage.\r\n * ~/.centaurus/tool-outputs/\r\n */\r\nfunction getToolOutputsBaseDir(): string {\r\n return path.join(os.homedir(), '.centaurus', TOOL_OUTPUTS_DIR_NAME);\r\n}\r\n\r\n/**\r\n * Get the directory for a specific chat's tool outputs.\r\n * ~/.centaurus/tool-outputs/{chatId}/\r\n * Falls back to a \"no-chat\" directory for outputs before a chat ID is assigned.\r\n */\r\nfunction getSessionDir(chatId: string | null): string {\r\n const baseDir = getToolOutputsBaseDir();\r\n const sessionDir = path.join(baseDir, chatId || '_no_chat');\r\n return sessionDir;\r\n}\r\n\r\n/**\r\n * Ensure a directory exists, creating it recursively if needed.\r\n * Returns true if successful, false if creation failed.\r\n */\r\nfunction ensureDir(dirPath: string): boolean {\r\n try {\r\n if (!fs.existsSync(dirPath)) {\r\n fs.mkdirSync(dirPath, { recursive: true });\r\n }\r\n return true;\r\n } catch (error) {\r\n quickLog(`[OutputTruncation] Failed to create directory ${dirPath}: ${error}\\n`);\r\n return false;\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// CORE TRUNCATION\r\n// ============================================================================\r\n\r\n/**\r\n * Truncate a tool output string using head+tail strategy.\r\n * \r\n * Keeps the first 20% and last 80% of the allowed characters, with a\r\n * descriptive marker in between. This preserves the beginning of the output\r\n * (command banner, column headers) and the end (final results, errors, summaries).\r\n * \r\n * If a file path is provided, the marker includes it so the AI can read the full output.\r\n * \r\n * @param content - The full output string\r\n * @param threshold - Maximum allowed characters (default: 30,000)\r\n * @param outputFilePath - Optional path where the full output was saved\r\n * @returns The truncated string, or the original if under threshold\r\n */\r\nexport function truncateWithHeadTail(\r\n content: string,\r\n threshold: number = DEFAULT_TRUNCATION_THRESHOLD,\r\n outputFilePath?: string,\r\n isRemoteContext?: boolean,\r\n): string {\r\n if (!content || content.length <= threshold) {\r\n return content;\r\n }\r\n\r\n const headChars = Math.floor(threshold * HEAD_FRACTION);\r\n const tailChars = threshold - headChars;\r\n\r\n const head = content.slice(0, headChars);\r\n const tail = content.slice(-tailChars);\r\n const omittedChars = content.length - headChars - tailChars;\r\n\r\n let marker: string;\r\n if (outputFilePath) {\r\n if (isRemoteContext) {\r\n // When in a remote session (SSH/Docker/WSL), the file is saved on the LOCAL machine.\r\n // Tell the AI to use Environment=\"local\" so view_file reads from the local filesystem.\r\n marker = `\\n\\n... [${omittedChars.toLocaleString()} characters omitted — full output saved to LOCAL machine: ${outputFilePath} — use view_file with Environment=\"local\" to read it] ...\\n\\n`;\r\n } else {\r\n marker = `\\n\\n... [${omittedChars.toLocaleString()} characters omitted — full output saved to: ${outputFilePath}] ...\\n\\n`;\r\n }\r\n } else {\r\n marker = `\\n\\n... [${omittedChars.toLocaleString()} characters omitted] ...\\n\\n`;\r\n }\r\n\r\n return head + marker + tail;\r\n}\r\n\r\n// ============================================================================\r\n// FILE SAVE\r\n// ============================================================================\r\n\r\n/**\r\n * Save the full tool output to a file for later retrieval by the AI.\r\n * \r\n * File naming: {toolName}_{timestamp}_{shortId}.txt\r\n * Location: ~/.centaurus/tool-outputs/{chatId}/\r\n * \r\n * @param content - The full output to save\r\n * @param toolName - Name of the tool that produced the output\r\n * @param chatId - Current chat ID (null if no chat yet)\r\n * @returns The absolute file path, or null if save failed\r\n */\r\nexport function saveFullOutput(\r\n content: string,\r\n toolName: string,\r\n chatId: string | null,\r\n): string | null {\r\n try {\r\n const sessionDir = getSessionDir(chatId);\r\n if (!ensureDir(sessionDir)) {\r\n return null;\r\n }\r\n\r\n // Sanitize tool name for filename\r\n const safeName = toolName.replace(/[^a-zA-Z0-9_-]/g, '_').toLowerCase();\r\n const timestamp = Date.now();\r\n const shortId = Math.random().toString(36).substring(2, 8);\r\n const fileName = `${safeName}_${timestamp}_${shortId}.txt`;\r\n const filePath = path.join(sessionDir, fileName);\r\n\r\n fs.writeFileSync(filePath, content, 'utf-8');\r\n\r\n quickLog(`[OutputTruncation] Saved full output (${content.length} chars) to ${filePath}\\n`);\r\n return filePath;\r\n } catch (error) {\r\n quickLog(`[OutputTruncation] Failed to save output: ${error}\\n`);\r\n return null;\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// MAIN ENTRY POINT\r\n// ============================================================================\r\n\r\n/**\r\n * Truncate a tool result if it exceeds the threshold.\r\n * \r\n * This is the main function to call from the CLI adapter. It:\r\n * 1. Checks if the tool is exempt from truncation\r\n * 2. Checks if the output exceeds the threshold\r\n * 3. Saves the full output to a file\r\n * 4. Returns the head+tail truncated version with a file reference\r\n * \r\n * @param toolName - The name of the tool\r\n * @param result - The raw result (string or any)\r\n * @param chatId - Current chat session ID\r\n * @param threshold - Optional custom threshold (default: 30,000)\r\n * @returns The (possibly truncated) result\r\n */\r\nexport function truncateToolOutput(\r\n toolName: string,\r\n result: any,\r\n chatId: string | null,\r\n threshold: number = DEFAULT_TRUNCATION_THRESHOLD,\r\n isRemoteContext: boolean = false,\r\n): any {\r\n // Only truncate string results\r\n if (typeof result !== 'string') {\r\n // For objects, try to stringify and check size\r\n try {\r\n const str = JSON.stringify(result);\r\n if (str.length <= threshold) return result;\r\n // If the stringified version is too large, truncate the string form\r\n const savedPath = saveFullOutput(str, toolName, chatId);\r\n return truncateWithHeadTail(str, threshold, savedPath ?? undefined, isRemoteContext);\r\n } catch {\r\n return result;\r\n }\r\n }\r\n\r\n // Skip exempt tools\r\n if (TRUNCATION_EXEMPT_TOOLS.has(toolName)) {\r\n return result;\r\n }\r\n\r\n // Check if truncation is needed\r\n if (result.length <= threshold) {\r\n return result;\r\n }\r\n\r\n // Save full output to file\r\n const savedPath = saveFullOutput(result, toolName, chatId);\r\n\r\n // Return truncated version\r\n return truncateWithHeadTail(result, threshold, savedPath ?? undefined, isRemoteContext);\r\n}\r\n\r\n// ============================================================================\r\n// CLEANUP\r\n// ============================================================================\r\n\r\n/**\r\n * Delete all tool output files for a specific chat.\r\n * Called when a chat is deleted.\r\n */\r\nexport function cleanupToolOutputsForChat(chatId: string): void {\r\n try {\r\n const sessionDir = getSessionDir(chatId);\r\n if (fs.existsSync(sessionDir)) {\r\n fs.rmSync(sessionDir, { recursive: true, force: true });\r\n quickLog(`[OutputTruncation] Cleaned up tool outputs for chat ${chatId}\\n`);\r\n }\r\n } catch (error) {\r\n quickLog(`[OutputTruncation] Failed to clean up tool outputs for chat ${chatId}: ${error}\\n`);\r\n }\r\n}\r\n\r\n/**\r\n * Delete the \"no-chat\" session directory.\r\n * Called when a new chat is started (outputs from before chat creation are no longer relevant).\r\n */\r\nexport function cleanupOrphanedToolOutputs(): void {\r\n try {\r\n const noChatDir = getSessionDir(null);\r\n if (fs.existsSync(noChatDir)) {\r\n fs.rmSync(noChatDir, { recursive: true, force: true });\r\n quickLog(`[OutputTruncation] Cleaned up orphaned (no-chat) tool outputs\\n`);\r\n }\r\n } catch (error) {\r\n quickLog(`[OutputTruncation] Failed to clean up orphaned outputs: ${error}\\n`);\r\n }\r\n}\r\n\r\n/**\r\n * Clean up stale tool output directories from old sessions.\r\n * Removes session directories that are older than STALE_SESSION_MAX_AGE_MS.\r\n * Called on startup to prevent unbounded disk growth.\r\n */\r\nexport function cleanupStaleToolOutputs(): void {\r\n try {\r\n const baseDir = getToolOutputsBaseDir();\r\n if (!fs.existsSync(baseDir)) return;\r\n\r\n const now = Date.now();\r\n const entries = fs.readdirSync(baseDir, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n if (!entry.isDirectory()) continue;\r\n\r\n const dirPath = path.join(baseDir, entry.name);\r\n try {\r\n const stat = fs.statSync(dirPath);\r\n const age = now - stat.mtimeMs;\r\n\r\n if (age > STALE_SESSION_MAX_AGE_MS) {\r\n fs.rmSync(dirPath, { recursive: true, force: true });\r\n quickLog(`[OutputTruncation] Cleaned up stale session dir: ${entry.name} (age: ${Math.round(age / 3600000)}h)\\n`);\r\n }\r\n } catch {\r\n // Skip directories we can't stat\r\n }\r\n }\r\n } catch (error) {\r\n quickLog(`[OutputTruncation] Failed to clean up stale outputs: ${error}\\n`);\r\n }\r\n}\r\n"],"mappings":"AAmBA,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,YAAY,QAAQ;AACpB,SAAS,gBAAgB;AAOlB,MAAM,+BAA+B;AAG5C,MAAM,gBAAgB;AAGtB,MAAM,gBAAgB;AAGtB,MAAM,wBAAwB;AAG9B,MAAM,2BAA2B,KAAK,KAAK,KAAK;AAGhD,MAAM,0BAA0B,oBAAI,IAAI;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAUD,SAAS,wBAAgC;AACvC,SAAO,KAAK,KAAK,GAAG,QAAQ,GAAG,cAAc,qBAAqB;AACpE;AAOA,SAAS,cAAc,QAA+B;AACpD,QAAM,UAAU,sBAAsB;AACtC,QAAM,aAAa,KAAK,KAAK,SAAS,UAAU,UAAU;AAC1D,SAAO;AACT;AAMA,SAAS,UAAU,SAA0B;AAC3C,MAAI;AACF,QAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,SAAG,UAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,IAC3C;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,aAAS,iDAAiD,OAAO,KAAK,KAAK;AAAA,CAAI;AAC/E,WAAO;AAAA,EACT;AACF;AAoBO,SAAS,qBACd,SACA,YAAoB,8BACpB,gBACA,iBACQ;AACR,MAAI,CAAC,WAAW,QAAQ,UAAU,WAAW;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,KAAK,MAAM,YAAY,aAAa;AACtD,QAAM,YAAY,YAAY;AAE9B,QAAM,OAAO,QAAQ,MAAM,GAAG,SAAS;AACvC,QAAM,OAAO,QAAQ,MAAM,CAAC,SAAS;AACrC,QAAM,eAAe,QAAQ,SAAS,YAAY;AAElD,MAAI;AACJ,MAAI,gBAAgB;AAClB,QAAI,iBAAiB;AAGnB,eAAS;AAAA;AAAA,OAAY,aAAa,eAAe,CAAC,kEAA6D,cAAc;AAAA;AAAA;AAAA,IAC/H,OAAO;AACL,eAAS;AAAA;AAAA,OAAY,aAAa,eAAe,CAAC,oDAA+C,cAAc;AAAA;AAAA;AAAA,IACjH;AAAA,EACF,OAAO;AACL,aAAS;AAAA;AAAA,OAAY,aAAa,eAAe,CAAC;AAAA;AAAA;AAAA,EACpD;AAEA,SAAO,OAAO,SAAS;AACzB;AAiBO,SAAS,eACd,SACA,UACA,QACe;AACf,MAAI;AACF,UAAM,aAAa,cAAc,MAAM;AACvC,QAAI,CAAC,UAAU,UAAU,GAAG;AAC1B,aAAO;AAAA,IACT;AAGA,UAAM,WAAW,SAAS,QAAQ,mBAAmB,GAAG,EAAE,YAAY;AACtE,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,UAAU,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC;AACzD,UAAM,WAAW,GAAG,QAAQ,IAAI,SAAS,IAAI,OAAO;AACpD,UAAM,WAAW,KAAK,KAAK,YAAY,QAAQ;AAE/C,OAAG,cAAc,UAAU,SAAS,OAAO;AAE3C,aAAS,yCAAyC,QAAQ,MAAM,cAAc,QAAQ;AAAA,CAAI;AAC1F,WAAO;AAAA,EACT,SAAS,OAAO;AACd,aAAS,6CAA6C,KAAK;AAAA,CAAI;AAC/D,WAAO;AAAA,EACT;AACF;AAqBO,SAAS,mBACd,UACA,QACA,QACA,YAAoB,8BACpB,kBAA2B,OACtB;AAEL,MAAI,OAAO,WAAW,UAAU;AAE9B,QAAI;AACF,YAAM,MAAM,KAAK,UAAU,MAAM;AACjC,UAAI,IAAI,UAAU,UAAW,QAAO;AAEpC,YAAMA,aAAY,eAAe,KAAK,UAAU,MAAM;AACtD,aAAO,qBAAqB,KAAK,WAAWA,cAAa,QAAW,eAAe;AAAA,IACrF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MAAI,wBAAwB,IAAI,QAAQ,GAAG;AACzC,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO;AAAA,EACT;AAGA,QAAM,YAAY,eAAe,QAAQ,UAAU,MAAM;AAGzD,SAAO,qBAAqB,QAAQ,WAAW,aAAa,QAAW,eAAe;AACxF;AAUO,SAAS,0BAA0B,QAAsB;AAC9D,MAAI;AACF,UAAM,aAAa,cAAc,MAAM;AACvC,QAAI,GAAG,WAAW,UAAU,GAAG;AAC7B,SAAG,OAAO,YAAY,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACtD,eAAS,uDAAuD,MAAM;AAAA,CAAI;AAAA,IAC5E;AAAA,EACF,SAAS,OAAO;AACd,aAAS,+DAA+D,MAAM,KAAK,KAAK;AAAA,CAAI;AAAA,EAC9F;AACF;AAMO,SAAS,6BAAmC;AACjD,MAAI;AACF,UAAM,YAAY,cAAc,IAAI;AACpC,QAAI,GAAG,WAAW,SAAS,GAAG;AAC5B,SAAG,OAAO,WAAW,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACrD,eAAS;AAAA,CAAiE;AAAA,IAC5E;AAAA,EACF,SAAS,OAAO;AACd,aAAS,2DAA2D,KAAK;AAAA,CAAI;AAAA,EAC/E;AACF;AAOO,SAAS,0BAAgC;AAC9C,MAAI;AACF,UAAM,UAAU,sBAAsB;AACtC,QAAI,CAAC,GAAG,WAAW,OAAO,EAAG;AAE7B,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,UAAU,GAAG,YAAY,SAAS,EAAE,eAAe,KAAK,CAAC;AAE/D,eAAW,SAAS,SAAS;AAC3B,UAAI,CAAC,MAAM,YAAY,EAAG;AAE1B,YAAM,UAAU,KAAK,KAAK,SAAS,MAAM,IAAI;AAC7C,UAAI;AACF,cAAM,OAAO,GAAG,SAAS,OAAO;AAChC,cAAM,MAAM,MAAM,KAAK;AAEvB,YAAI,MAAM,0BAA0B;AAClC,aAAG,OAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACnD,mBAAS,oDAAoD,MAAM,IAAI,UAAU,KAAK,MAAM,MAAM,IAAO,CAAC;AAAA,CAAM;AAAA,QAClH;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,aAAS,wDAAwD,KAAK;AAAA,CAAI;AAAA,EAC5E;AACF;","names":["savedPath"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { rulesStorage } from "../services/rules-storage.js";
|
|
2
|
-
const RULE_REFERENCE_REGEX = /(^|[\s\n])@rules:([a-zA-Z0-9_-]+)/g;
|
|
2
|
+
const RULE_REFERENCE_REGEX = /(^|[\s\n])@rules:(?:"([^"]+)"|([a-zA-Z0-9_-]+))/g;
|
|
3
3
|
function resolveRuleReferences(prompt) {
|
|
4
4
|
const referencedRuleNames = [];
|
|
5
5
|
let match;
|
|
6
6
|
while ((match = RULE_REFERENCE_REGEX.exec(prompt)) !== null) {
|
|
7
|
-
const ruleName = match[2];
|
|
8
|
-
if (!referencedRuleNames.includes(ruleName)) {
|
|
7
|
+
const ruleName = match[2] || match[3];
|
|
8
|
+
if (ruleName && !referencedRuleNames.includes(ruleName)) {
|
|
9
9
|
referencedRuleNames.push(ruleName);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/rule-reference-resolver.ts"],"sourcesContent":["import { rulesStorage } from '../services/rules-storage.js';\r\n\r\nexport interface ResolvedRuleReference {\r\n name: string;\r\n content: string;\r\n}\r\n\r\nexport interface ResolveRuleReferencesResult {\r\n augmentedPrompt: string;\r\n referencedRules: ResolvedRuleReference[];\r\n missingRuleNames: string[];\r\n}\r\n\r\nconst RULE_REFERENCE_REGEX = /(^|[\\s\\n])@rules:([a-zA-Z0-9_-]+)/g;\r\n\r\nexport function resolveRuleReferences(prompt: string): ResolveRuleReferencesResult {\r\n const referencedRuleNames: string[] = [];\r\n let match: RegExpExecArray | null;\r\n\r\n while ((match = RULE_REFERENCE_REGEX.exec(prompt)) !== null) {\r\n const ruleName = match[2]
|
|
1
|
+
{"version":3,"sources":["../../src/utils/rule-reference-resolver.ts"],"sourcesContent":["import { rulesStorage } from '../services/rules-storage.js';\r\n\r\nexport interface ResolvedRuleReference {\r\n name: string;\r\n content: string;\r\n}\r\n\r\nexport interface ResolveRuleReferencesResult {\r\n augmentedPrompt: string;\r\n referencedRules: ResolvedRuleReference[];\r\n missingRuleNames: string[];\r\n}\r\n\r\nconst RULE_REFERENCE_REGEX = /(^|[\\s\\n])@rules:(?:\"([^\"]+)\"|([a-zA-Z0-9_-]+))/g;\r\n\r\nexport function resolveRuleReferences(prompt: string): ResolveRuleReferencesResult {\r\n const referencedRuleNames: string[] = [];\r\n let match: RegExpExecArray | null;\r\n\r\n while ((match = RULE_REFERENCE_REGEX.exec(prompt)) !== null) {\r\n const ruleName = match[2] || match[3]; // quoted or unquoted\r\n if (ruleName && !referencedRuleNames.includes(ruleName)) {\r\n referencedRuleNames.push(ruleName);\r\n }\r\n }\r\n\r\n if (referencedRuleNames.length === 0) {\r\n return {\r\n augmentedPrompt: prompt,\r\n referencedRules: [],\r\n missingRuleNames: []\r\n };\r\n }\r\n\r\n const referencedRules: ResolvedRuleReference[] = [];\r\n const missingRuleNames: string[] = [];\r\n\r\n for (const ruleName of referencedRuleNames) {\r\n const rule = rulesStorage.load(ruleName);\r\n if (!rule) {\r\n missingRuleNames.push(ruleName);\r\n continue;\r\n }\r\n\r\n referencedRules.push({\r\n name: rule.name,\r\n content: rule.content\r\n });\r\n }\r\n\r\n if (referencedRules.length === 0) {\r\n return {\r\n augmentedPrompt: prompt,\r\n referencedRules,\r\n missingRuleNames\r\n };\r\n }\r\n\r\n const injectedRulesBlock = referencedRules\r\n .map(rule => `Rule: ${rule.name}\\n${rule.content}`)\r\n .join('\\n\\n');\r\n\r\n return {\r\n augmentedPrompt: `${prompt}\\n\\nThe following saved rules were referenced in this prompt. Apply them as additional user instructions for this message:\\n\\n${injectedRulesBlock}`,\r\n referencedRules,\r\n missingRuleNames\r\n };\r\n}\r\n"],"mappings":"AAAA,SAAS,oBAAoB;AAa7B,MAAM,uBAAuB;AAEtB,SAAS,sBAAsB,QAA6C;AAC/E,QAAM,sBAAgC,CAAC;AACvC,MAAI;AAEJ,UAAQ,QAAQ,qBAAqB,KAAK,MAAM,OAAO,MAAM;AACzD,UAAM,WAAW,MAAM,CAAC,KAAK,MAAM,CAAC;AACpC,QAAI,YAAY,CAAC,oBAAoB,SAAS,QAAQ,GAAG;AACrD,0BAAoB,KAAK,QAAQ;AAAA,IACrC;AAAA,EACJ;AAEA,MAAI,oBAAoB,WAAW,GAAG;AAClC,WAAO;AAAA,MACH,iBAAiB;AAAA,MACjB,iBAAiB,CAAC;AAAA,MAClB,kBAAkB,CAAC;AAAA,IACvB;AAAA,EACJ;AAEA,QAAM,kBAA2C,CAAC;AAClD,QAAM,mBAA6B,CAAC;AAEpC,aAAW,YAAY,qBAAqB;AACxC,UAAM,OAAO,aAAa,KAAK,QAAQ;AACvC,QAAI,CAAC,MAAM;AACP,uBAAiB,KAAK,QAAQ;AAC9B;AAAA,IACJ;AAEA,oBAAgB,KAAK;AAAA,MACjB,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,IAClB,CAAC;AAAA,EACL;AAEA,MAAI,gBAAgB,WAAW,GAAG;AAC9B,WAAO;AAAA,MACH,iBAAiB;AAAA,MACjB;AAAA,MACA;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,qBAAqB,gBACtB,IAAI,UAAQ,SAAS,KAAK,IAAI;AAAA,EAAK,KAAK,OAAO,EAAE,EACjD,KAAK,MAAM;AAEhB,SAAO;AAAA,IACH,iBAAiB,GAAG,MAAM;AAAA;AAAA;AAAA;AAAA,EAAiI,kBAAkB;AAAA,IAC7K;AAAA,IACA;AAAA,EACJ;AACJ;","names":[]}
|