22import sys
33from pathlib import Path
44from typing import Optional
5+ import random
56
67import typer
78
@@ -29,6 +30,38 @@ def _find_prompt_by_name(manager: PromptManager, name: str) -> Optional[Prompt]:
2930 return None
3031
3132
33+ def _generate_fancy_name () -> str :
34+ """Generate a fancy, creative name for a prompt."""
35+ adjectives = [
36+ "Cosmic" , "Digital" , "Quantum" , "Cyber" , "Neural" , "Pixel" , "Binary" ,
37+ "Virtual" , "Synthetic" , "Logic" , "Code" , "Syntax" , "Algorithm" , "Byte" ,
38+ "Data" , "Matrix" , "Circuit" , "Pulse" , "Wave" , "Stream" , "Flux" , "Nexus" ,
39+ "Aether" , "Zenith" , "Prism" , "Echo" , "Nova" , "Aura" , "Spark" , "Bloom" ,
40+ "Whisper" , "Dream" , "Vision" , "Harmony" , "Pulse" , "Radiant" , "Ethereal" ,
41+ "Luminous" , "Mystic" , "Phantom" , "Sapphire" , "Crimson" , "Amber" , "Azure"
42+ ]
43+
44+ nouns = [
45+ "Coder" , "Assistant" , "Wizard" , "Sage" , "Oracle" , "Companion" , "Guide" ,
46+ "Mentor" , "Architect" , "Scribe" , "Alchemist" , "Artisan" , "Craftsman" ,
47+ "Navigator" , "Explorer" , "Pioneer" , "Trailblazer" , "Pathfinder" , "Seeker" ,
48+ "Dreamer" , "Visionary" , "Innovator" , "Creator" , "Builder" , "Weaver" ,
49+ "Sorcerer" , "Enchanter" , "Luminary" , "Beacon" , "Guardian" , "Sentinel" ,
50+ "Whisperer" , "Harmonizer" , "Illuminator" , "Transformer" , "Catalyst"
51+ ]
52+
53+ # Generate 2-3 word combinations
54+ name_parts = []
55+ name_parts .append (random .choice (adjectives ))
56+ name_parts .append (random .choice (nouns ))
57+
58+ # Sometimes add a second adjective for variety
59+ if random .random () < 0.3 :
60+ name_parts .insert (0 , random .choice (adjectives ))
61+
62+ return " " .join (name_parts )
63+
64+
3265@prompt_app .command ("list" )
3366def list_prompts ():
3467 """List all configured prompts."""
@@ -79,26 +112,21 @@ def show_prompt(
79112
80113@prompt_app .command ("add" )
81114def add_prompt (
82- name : str = typer .Argument (... , help = "Name for the prompt" ),
115+ name : Optional [ str ] = typer .Argument (None , help = "Name for the prompt (auto-generated if not provided) " ),
83116 description : Optional [str ] = typer .Option (None , "--description" , "-d" , help = "Description of the prompt" ),
84117 file : Optional [Path ] = typer .Option (None , "--file" , "-f" , help = "Read content from file" ),
85118 default : bool = typer .Option (False , "--default" , help = "Set as default prompt" ),
86119):
87120 """Add a new prompt from file, stdin, or interactive input.
88121
89122 Examples:
90- cam prompt add my-prompt -f prompt.md
91- cat prompt.md | cam prompt add my-prompt
92- cam prompt add my-prompt # Interactive mode
123+ cam prompt add "My Custom Prompt" -f prompt.md
124+ cam prompt add -f prompt.md # Auto-generates a fancy name
125+ cat prompt.md | cam prompt add
126+ cam prompt add # Interactive mode with fancy name
93127 """
94128 manager = _get_manager ()
95129
96- # Check if prompt with same name already exists
97- for p in manager .get_all ().values ():
98- if p .name == name :
99- typer .echo (f"Error: Prompt with name '{ name } ' already exists. Use a different name or remove it first." )
100- raise typer .Exit (1 )
101-
102130 # Read content from file, stdin, or interactive input
103131 if file :
104132 if not file .exists ():
@@ -125,6 +153,21 @@ def add_prompt(
125153 typer .echo ("Error: Content cannot be empty" )
126154 raise typer .Exit (1 )
127155
156+ # Generate or validate name
157+ if not name :
158+ # Generate a fancy name and ensure it's unique
159+ while True :
160+ name = _generate_fancy_name ()
161+ if not _find_prompt_by_name (manager , name ):
162+ break
163+ typer .echo (f"✨ Generated fancy name: { Colors .CYAN } { name } { Colors .RESET } " )
164+ else :
165+ # Check if prompt with same name already exists
166+ existing_prompt = _find_prompt_by_name (manager , name )
167+ if existing_prompt :
168+ typer .echo (f"Error: Prompt with name '{ name } ' already exists. Use a different name or remove it first." )
169+ raise typer .Exit (1 )
170+
128171 # Create the prompt (ID is auto-generated)
129172 prompt = Prompt (
130173 name = name ,
@@ -242,16 +285,17 @@ def remove_prompt(
242285
243286@prompt_app .command ("import" )
244287def import_prompt (
245- name : str = typer .Argument (... , help = "Name for the imported prompt" ),
288+ name : Optional [ str ] = typer .Argument (None , help = "Name for the imported prompt (auto-generated if not provided) " ),
246289 app : str = typer .Option (..., "--app" , "-a" , help = f"App to import from ({ ', ' .join (VALID_APP_TYPES )} )" ),
247290 level : str = typer .Option ("user" , "--level" , "-l" , help = "Level: user or project" ),
248291 project_dir : Optional [Path ] = typer .Option (None , "--project-dir" , "-d" , help = "Project directory (for project level)" ),
249292 description : Optional [str ] = typer .Option (None , "--description" , help = "Description of the prompt" ),
250293):
251294 """Import a prompt from an app's live prompt file.
252-
295+
253296 Examples:
254- cam prompt import my-claude --app claude
297+ cam prompt import "My Claude Prompt" --app claude
298+ cam prompt import --app claude # Auto-generates a fancy name
255299 cam prompt import project-prompt --app claude --level project -d .
256300 """
257301 if app not in VALID_APP_TYPES :
@@ -267,11 +311,6 @@ def import_prompt(
267311
268312 manager = _get_manager ()
269313
270- # Check if prompt with same name already exists
271- if _find_prompt_by_name (manager , name ):
272- typer .echo (f"Error: Prompt '{ name } ' already exists. Use a different name." )
273- raise typer .Exit (1 )
274-
275314 # Get the live content
276315 handler = manager .get_handler (app )
277316 file_path = handler .get_prompt_file_path (level , project_dir )
@@ -293,6 +332,30 @@ def import_prompt(
293332 from code_assistant_manager .prompts .base import PROMPT_ID_PATTERN
294333 content = PROMPT_ID_PATTERN .sub ("" , content ).strip ()
295334
335+ # Generate or validate name
336+ if not name :
337+ # Generate a fancy name with app context and ensure it's unique
338+ while True :
339+ base_name = _generate_fancy_name ()
340+ # Add app context to make it more specific
341+ app_prefixes = {
342+ "claude" : "Claude" ,
343+ "codex" : "Codex" ,
344+ "gemini" : "Gemini" ,
345+ "copilot" : "Copilot" ,
346+ "codebuddy" : "CodeBuddy"
347+ }
348+ prefix = app_prefixes .get (app , app .capitalize ())
349+ name = f"{ prefix } { base_name } "
350+ if not _find_prompt_by_name (manager , name ):
351+ break
352+ typer .echo (f"✨ Generated fancy name: { Colors .CYAN } { name } { Colors .RESET } " )
353+ else :
354+ # Check if prompt with same name already exists
355+ if _find_prompt_by_name (manager , name ):
356+ typer .echo (f"Error: Prompt '{ name } ' already exists. Use a different name." )
357+ raise typer .Exit (1 )
358+
296359 # Create the prompt (ID is auto-generated)
297360 prompt = Prompt (
298361 name = name ,
0 commit comments