()
| 381 | } |
| 382 | |
| 383 | private resolveToolsArg(): string[] | null { |
| 384 | if (typeof this.toolsArg === 'undefined') { |
| 385 | return null; |
| 386 | } |
| 387 | |
| 388 | const raw = this.toolsArg.trim(); |
| 389 | if (raw.length === 0) { |
| 390 | throw new Error( |
| 391 | 'The --tools option requires a value. Use "all", "none", or a comma-separated list of tool IDs.' |
| 392 | ); |
| 393 | } |
| 394 | |
| 395 | const availableTools = getToolsWithSkillsDir(); |
| 396 | const availableSet = new Set(availableTools); |
| 397 | const availableList = ['all', 'none', ...availableTools].join(', '); |
| 398 | |
| 399 | const lowerRaw = raw.toLowerCase(); |
| 400 | if (lowerRaw === 'all') { |
| 401 | return availableTools; |
| 402 | } |
| 403 | |
| 404 | if (lowerRaw === 'none') { |
| 405 | return []; |
| 406 | } |
| 407 | |
| 408 | const tokens = raw |
| 409 | .split(',') |
| 410 | .map((token) => token.trim()) |
| 411 | .filter((token) => token.length > 0); |
| 412 | |
| 413 | if (tokens.length === 0) { |
| 414 | throw new Error( |
| 415 | 'The --tools option requires at least one tool ID when not using "all" or "none".' |
| 416 | ); |
| 417 | } |
| 418 | |
| 419 | const normalizedTokens = tokens.map((token) => token.toLowerCase()); |
| 420 | |
| 421 | if (normalizedTokens.some((token) => token === 'all' || token === 'none')) { |
| 422 | throw new Error('Cannot combine reserved values "all" or "none" with specific tool IDs.'); |
| 423 | } |
| 424 | |
| 425 | const invalidTokens = tokens.filter( |
| 426 | (_token, index) => !availableSet.has(normalizedTokens[index]) |
| 427 | ); |
| 428 | |
| 429 | if (invalidTokens.length > 0) { |
| 430 | throw new Error( |
| 431 | `Invalid tool(s): ${invalidTokens.join(', ')}. Available values: ${availableList}` |
| 432 | ); |
| 433 | } |
| 434 | |
| 435 | // Deduplicate while preserving order |
| 436 | const deduped: string[] = []; |
| 437 | for (const token of normalizedTokens) { |
| 438 | if (!deduped.includes(token)) { |
| 439 | deduped.push(token); |
| 440 | } |
no test coverage detected