Skip to content

Commit 9e31a7d

Browse files
Kasper Jungeclaude
authored andcommitted
refactor: extract _resolve_prompt_source to untangle prompt resolution logic
The run() command had 8 nested conditionals spread across 35 lines to resolve the prompt file path from 5 possible sources. Extracting this into a pure function with keyword-only args and early returns makes the priority chain (inline text > name > file > toml) immediately obvious and easier to test independently. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8433836 commit 9e31a7d

1 file changed

Lines changed: 47 additions & 32 deletions

File tree

src/ralphify/cli.py

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,42 @@ def _on_run_stopped(self, d: dict) -> None:
370370
}
371371

372372

373+
def _resolve_prompt_source(
374+
*,
375+
prompt_text: str | None,
376+
prompt_name: str | None,
377+
prompt_file: str | None,
378+
toml_prompt: str,
379+
) -> tuple[str, str | None]:
380+
"""Resolve which prompt file to use, returning ``(file_path, prompt_name)``.
381+
382+
Priority chain: inline text > positional name > --prompt-file > ralph.toml.
383+
The ``toml_prompt`` value from ``ralph.toml`` may be either a file path or
384+
a named prompt — names are tried first, falling back to a literal path.
385+
386+
Raises ``ValueError`` if a named prompt lookup fails.
387+
"""
388+
if prompt_text:
389+
return toml_prompt, None
390+
391+
if prompt_name:
392+
found = resolve_prompt_name(prompt_name)
393+
return str(found.path / PROMPT_MARKER), found.name
394+
395+
if prompt_file:
396+
return prompt_file, None
397+
398+
# Fall back to ralph.toml agent.prompt — could be a name or a path
399+
if is_prompt_name(toml_prompt):
400+
try:
401+
found = resolve_prompt_name(toml_prompt)
402+
return str(found.path / PROMPT_MARKER), found.name
403+
except ValueError:
404+
return toml_prompt, None
405+
406+
return toml_prompt, None
407+
408+
373409
@app.command()
374410
def run(
375411
prompt_name: str | None = typer.Argument(None, help="Name of a prompt in .ralph/prompts/."),
@@ -399,39 +435,18 @@ def run(
399435
rprint("[red]Cannot use both a prompt name and --prompt-file.[/red]")
400436
raise typer.Exit(1)
401437

402-
# Resolve prompt file path using priority chain:
403-
# --prompt (inline text) > positional name > --prompt-file > ralph.toml > root PROMPT.md
404-
resolved_prompt_name: str | None = None
405-
if prompt_text:
406-
# Inline text — no file needed
407-
prompt_file_path = agent.get("prompt", "PROMPT.md")
408-
elif prompt_name:
409-
# Positional arg — look up in .ralph/prompts/
410-
try:
411-
found = resolve_prompt_name(prompt_name)
412-
except ValueError as e:
413-
rprint(f"[red]{e}[/red]")
414-
raise typer.Exit(1)
415-
prompt_file_path = str(found.path / PROMPT_MARKER)
416-
resolved_prompt_name = found.name
417-
elif prompt_file:
418-
prompt_file_path = prompt_file
419-
else:
420-
# Fall back to ralph.toml agent.prompt — could be a name or a path
421-
toml_prompt = agent.get("prompt", "PROMPT.md")
422-
if is_prompt_name(toml_prompt):
423-
# Try as a prompt name first, fall back to file path
424-
try:
425-
found = resolve_prompt_name(toml_prompt)
426-
prompt_file_path = str(found.path / PROMPT_MARKER)
427-
resolved_prompt_name = found.name
428-
except ValueError:
429-
prompt_file_path = toml_prompt
430-
else:
431-
prompt_file_path = toml_prompt
438+
try:
439+
prompt_file_path, resolved_prompt_name = _resolve_prompt_source(
440+
prompt_text=prompt_text,
441+
prompt_name=prompt_name,
442+
prompt_file=prompt_file,
443+
toml_prompt=agent.get("prompt", "PROMPT.md"),
444+
)
445+
except ValueError as e:
446+
rprint(f"[red]{e}[/red]")
447+
raise typer.Exit(1)
432448

433-
prompt_path = Path(prompt_file_path)
434-
if not prompt_text and not prompt_path.exists():
449+
if not prompt_text and not Path(prompt_file_path).exists():
435450
rprint(f"[red]Prompt file '{prompt_file_path}' not found.[/red]")
436451
raise typer.Exit(1)
437452

0 commit comments

Comments
 (0)