| 136 | function isTrivial(signalText: string): boolean { |
| 137 | const t = signalText.trim(); |
| 138 | if (t.split(/\s+/).filter(Boolean).length > 5) return false; // long → real task |
| 139 | if (/[a-z][A-Z]/.test(t)) return false; // camelCase identifier |
| 140 | if (/[/._-][a-zA-Z]{1,6}/.test(t)) return false; // path / .ext / snake_case |
| 141 | const lower = t.toLowerCase(); |
| 142 | const TASK_WORDS = [ |
| 143 | 'fix', 'bug', 'error', 'refactor', 'implement', 'build', 'deploy', 'test', 'debug', |
| 144 | 'create', 'update', 'remove', 'add ', 'edit', 'write', 'change', 'review', 'find', |
| 145 | // Short, ordinary asks that are unmistakably WORK. Without these, "commit and open a PR" |
| 146 | // (5 words, no listed verb) was judged trivial and handed CORE tools only — so the git |
| 147 | // family never reached the model on exactly the turn it was needed. |
| 148 | 'commit', 'push', 'merge', 'rebase', 'pr ', ' pr', 'pull request', 'branch', 'stash', |
| 149 | 'install', 'run ', 'start', 'stop', 'open', 'check', 'look', 'show', 'list', |
| 150 | 'rename', 'move', 'delete', 'clean', 'format', 'lint', 'upgrade', 'bump', |
| 151 | 'کامیت', 'پوش', 'مرج', 'برنچ', 'نصب', 'اجرا', 'باز کن', 'نشان', 'لیست', |
| 152 | 'باگ', 'خطا', 'اصلاح', 'بساز', 'پیدا', 'پیاده', 'اضاف', 'تست', 'دیباگ', 'ریفکتور', |
| 153 | 'درست', 'حذف', 'تغییر', 'بنویس', 'بررسی', 'پیدا کن', 'عوض', |
| 154 | ]; |
| 155 | return !TASK_WORDS.some(w => lower.includes(w)); |
| 156 | } |
| 157 | |
| 158 | export interface RelevanceResult { |
| 159 | selected: Set<string>; |
| 160 | matchedFamilies: number; |
| 161 | includedAll: boolean; |
| 162 | trivial: boolean; |
| 163 | } |
| 164 | |
| 165 | export function selectRelevantToolNames(allNames: string[], signalText: string): RelevanceResult { |