Skip to content

feat(cli): -f/--file prompt-file support (llama.cpp-compatible)#233

Merged
pekkah merged 2 commits into
masterfrom
feat/cli-prompt-file
Jun 13, 2026
Merged

feat(cli): -f/--file prompt-file support (llama.cpp-compatible)#233
pekkah merged 2 commits into
masterfrom
feat/cli-prompt-file

Conversation

@pekkah

@pekkah pekkah commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

Adds -f/--file <path> to the run CLI (llama.cpp's arg name) to read the prompt from a file. Resolved once at the top of Execute into settings.Prompt, so every downstream prompt path (single-turn, chat, format/template) works unchanged. Overrides -p when both are given; reads the file as-is (no trailing-newline stripping); a missing file errors loudly (exit 1).

Motivation

A prompt longer than the OS command-line length limit (~32K chars on Windows) can't be passed via -p — it fails with "The filename or extension is too long." This surfaced while profiling long-context decode (#213): a ~16K-token prompt couldn't be fed via -p.

Verified (CLI)

  • short file → prefilled (30 tok);
  • ~16K-token file → prefilled 10460 tok, no arg-length error;
  • missing file → Prompt file not found: … (exit 1).

Build clean under TreatWarningsAsErrors + AOT. ~15 lines; self-contained.

🤖 Generated with Claude Code

Read the prompt from a file via -f/--file (llama.cpp's arg name), resolved once at the
top of Execute into settings.Prompt so all downstream prompt paths work unchanged.
Overrides -p when both are given; reads the file as-is (no trailing-newline stripping).
A missing file errors loudly (exit 1) instead of running with an empty prompt.

Motivation: prompts longer than the OS command-line length limit (~32K chars on Windows)
can't be passed via -p — a long-context prompt blew the limit during #213 profiling.
Verified: short file (30 tok), ~16K-token file (10460 tok prefilled, no "filename too long"),
and missing-file clean error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new -f|--file option to load prompts from a file, overriding the -p|--prompt option. The review feedback highlights two main issues: potential markup parsing errors in Spectre.Console when rendering the file path, and unhandled I/O exceptions when reading the file. It is recommended to escape the file path and wrap the file read operation in a try-catch block to ensure graceful error handling.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +197 to +205
if (settings.PromptFile is { Length: > 0 } promptFile)
{
if (!File.Exists(promptFile))
{
AnsiConsole.MarkupLine($"[red]Prompt file not found:[/] {promptFile}");
return 1;
}
settings.Prompt = File.ReadAllText(promptFile);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There are two issues in this block:

  1. Spectre.Console Markup Parsing Error: If promptFile contains square brackets (e.g., [path]), AnsiConsole.MarkupLine will attempt to parse it as markup, leading to incorrect rendering or exceptions. Use Markup.Escape(promptFile) to prevent this.
  2. Unhandled I/O Exceptions: File.ReadAllText can throw exceptions (e.g., UnauthorizedAccessException, IOException) if the file is locked or permissions are insufficient. Wrapping it in a try-catch block ensures the CLI exits gracefully with a clean error message instead of crashing with a stack trace.
        if (settings.PromptFile is { Length: > 0 } promptFile)
        {
            if (!File.Exists(promptFile))
            {
                AnsiConsole.MarkupLine($"[red]Prompt file not found:[/] {Markup.Escape(promptFile)}");
                return 1;
            }
            try
            {
                settings.Prompt = File.ReadAllText(promptFile);
            }
            catch (Exception ex)
            {
                AnsiConsole.MarkupLine($"[red]Error reading prompt file:[/] {Markup.Escape(ex.Message)}");
                return 1;
            }
        }

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: Markup.Escape on both the not-found and read-error messages, and File.ReadAllText is wrapped in try/catch (IOException/UnauthorizedAccessException/SecurityException/NotSupportedException) → clean message + exit 1. Verified a bracketed missing path renders correctly.

… (gemini)

gemini MEDIUM: (1) AnsiConsole.MarkupLine would choke on a path containing Spectre
markup chars ([ ]) — Markup.Escape the path in the not-found message and the read-error
message. (2) File.ReadAllText I/O failures (locked/permissions/bad path) were unhandled
(stack trace) — wrap in try/catch over IOException/UnauthorizedAccessException/SecurityException/
NotSupportedException, fail loud with a clean message + exit 1. Verified a bracketed missing
path now renders correctly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pekkah pekkah merged commit f2dffee into master Jun 13, 2026
1 check passed
@pekkah pekkah deleted the feat/cli-prompt-file branch June 13, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant