parseCliArgs function

CliArgsResult parseCliArgs(
  1. List<String> args
)

Parses the fah argument list.

Throws CliArgsException on unknown flags, missing flag values, an unknown provider, --system-prompt combined with --system-prompt-file, or -p/--prompt combined with positional arguments.

Implementation

CliArgsResult parseCliArgs(List<String> args) {
  String? model;
  var provider = 'openai-completions';
  String? baseUrl;
  String? systemPrompt;
  String? systemPromptFile;
  String? visionModel;
  String? visionBaseUrl;
  String? transcribeModel;
  String? transcribeBaseUrl;
  final plugins = <String>[];
  final promptTemplateDirs = <String>[];
  String? mode;
  String? cwd;
  String? sessionRoot;
  String? session;
  String? prompt;
  final positionals = <String>[];

  String valueFor(int index, String flag) {
    if (index + 1 >= args.length) {
      throw CliArgsException('$flag requires a value');
    }
    return args[index + 1];
  }

  for (var i = 0; i < args.length; i++) {
    switch (args[i]) {
      case '--help' || '-h':
        return const CliArgsHelp();
      case '--version':
        return const CliArgsVersion();
      case '--model':
        model = valueFor(i, '--model');
        i++;
      case '--provider':
        provider = valueFor(i, '--provider');
        i++;
      case '--base-url':
        baseUrl = valueFor(i, '--base-url');
        i++;
      case '--system-prompt':
        systemPrompt = valueFor(i, '--system-prompt');
        i++;
      case '--system-prompt-file':
        systemPromptFile = valueFor(i, '--system-prompt-file');
        i++;
      case '--vision-model':
        visionModel = valueFor(i, '--vision-model');
        i++;
      case '--vision-base-url':
        visionBaseUrl = valueFor(i, '--vision-base-url');
        i++;
      case '--transcribe-model':
        transcribeModel = valueFor(i, '--transcribe-model');
        i++;
      case '--transcribe-base-url':
        transcribeBaseUrl = valueFor(i, '--transcribe-base-url');
        i++;
      case '--plugin':
        plugins.add(valueFor(i, '--plugin'));
        i++;
      case '--prompt-template-dir':
        promptTemplateDirs.add(valueFor(i, '--prompt-template-dir'));
        i++;
      case '--mode':
        mode = valueFor(i, '--mode');
        i++;
      case '--cwd':
        cwd = valueFor(i, '--cwd');
        i++;
      case '--session-root':
        sessionRoot = valueFor(i, '--session-root');
        i++;
      case '--session':
        session = valueFor(i, '--session');
        i++;
      case '-p' || '--prompt':
        prompt = valueFor(i, '--prompt');
        i++;
      default:
        // Anything not flag-like is a positional prompt fragment; unknown
        // `-...` arguments stay an error.
        if (args[i].startsWith('-')) {
          throw CliArgsException('unknown argument: ${args[i]}');
        }
        positionals.add(args[i]);
    }
  }
  if (!cliProviderKinds.contains(provider)) {
    throw CliArgsException('unknown provider: $provider');
  }
  if (systemPrompt != null && systemPromptFile != null) {
    throw CliArgsException(
      'cannot combine --system-prompt and --system-prompt-file',
    );
  }
  if (prompt != null && positionals.isNotEmpty) {
    throw CliArgsException(
      'cannot combine -p/--prompt with positional prompt arguments',
    );
  }
  return CliArgs(
    model: model,
    provider: provider,
    baseUrl: baseUrl,
    systemPrompt: systemPrompt,
    systemPromptFile: systemPromptFile,
    visionModel: visionModel,
    visionBaseUrl: visionBaseUrl,
    transcribeModel: transcribeModel,
    transcribeBaseUrl: transcribeBaseUrl,
    plugins: plugins,
    promptTemplateDirs: promptTemplateDirs,
    mode: mode,
    cwd: cwd,
    sessionRoot: sessionRoot,
    session: session,
    prompt: prompt,
    positionals: positionals,
  );
}