Coverage for src / osiris_cli / prompts.py: 0%

75 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-27 17:41 +0200

1import json 

2from pathlib import Path 

3from .config import CONFIG_DIR 

4 

5PROMPTS_FILE = CONFIG_DIR / "prompts.json" 

6 

7DEFAULT_PROMPTS = [ 

8 {"text": "Summarize the purpose of this file", "category": "Analysis"}, 

9 {"text": "Identify potential bugs or security issues", "category": "Code Quality"}, 

10 {"text": "Refactor this code to be more idiomatic", "category": "Refactoring"}, 

11 {"text": "Write unit tests for the selected code", "category": "Testing"}, 

12 {"text": "Explain how this works step-by-step", "category": "Learning"}, 

13] 

14 

15class PromptManager: 

16 def __init__(self): 

17 self.prompts = [] 

18 self.recents = [] 

19 self.load() 

20 

21 def load(self): 

22 if PROMPTS_FILE.exists(): 

23 try: 

24 data = json.loads(PROMPTS_FILE.read_text()) 

25 self.prompts = data.get("saved", DEFAULT_PROMPTS) 

26 self.recents = data.get("recents", []) 

27 except: 

28 self.prompts = DEFAULT_PROMPTS 

29 self.recents = [] 

30 else: 

31 self.prompts = DEFAULT_PROMPTS 

32 self.recents = [] 

33 self.save() 

34 

35 def save(self): 

36 data = { 

37 "saved": self.prompts, 

38 "recents": self.recents 

39 } 

40 PROMPTS_FILE.write_text(json.dumps(data, indent=2)) 

41 

42 def add_custom(self, text: str): 

43 # Dedupe 

44 if any(p["text"] == text for p in self.prompts): 

45 return 

46 self.prompts.append({"text": text, "category": "Custom"}) 

47 self.save() 

48 

49 def add_recent(self, text: str): 

50 # Ignore short/common commands 

51 if len(text) < 5 or text.startswith("/"): 

52 return 

53 

54 # Dedupe 

55 if text in self.recents: 

56 self.recents.remove(text) 

57 

58 self.recents.insert(0, text) 

59 # Keep last 10 

60 self.recents = self.recents[:10] 

61 self.save() 

62 

63 def delete_prompt(self, text: str): 

64 """Deletes a prompt from saved prompts.""" 

65 original_len = len(self.prompts) 

66 self.prompts = [p for p in self.prompts if p["text"] != text] 

67 if len(self.prompts) < original_len: 

68 self.save() 

69 return True 

70 return False 

71 

72 def get_all(self): 

73 """Return list of (label, text) tuples for UI.""" 

74 options = [] 

75 

76 # Recents first (Top 3) 

77 if self.recents: 

78 options.append(("-- Recent --", None)) 

79 for r in self.recents[:3]: 

80 options.append((f"🕒 {r[:40]}...", r)) 

81 

82 # Saved 

83 options.append(("-- Library --", None)) 

84 for p in self.prompts: 

85 icon = "📝" 

86 if p["category"] == "Analysis": icon = "🔍" 

87 elif p["category"] == "Refactoring": icon = "🔧" 

88 elif p["category"] == "Testing": icon = "🧪" 

89 

90 options.append((f"{icon} {p['text']}", p['text'])) 

91 

92 return options 

93 

94 def export_prompts(self, file_path: Path): 

95 """Exports saved prompts to a JSON file.""" 

96 with open(file_path, "w") as f: 

97 json.dump(self.prompts, f, indent=2) 

98 

99 def import_prompts(self, file_path: Path): 

100 """Imports prompts from a JSON file, adding new ones and avoiding duplicates.""" 

101 if not file_path.exists(): 

102 raise FileNotFoundError(f"Prompt file not found: {file_path}") 

103 

104 with open(file_path, "r") as f: 

105 new_prompts = json.load(f) 

106 

107 added_count = 0 

108 for new_p in new_prompts: 

109 if "text" in new_p and not any(p["text"] == new_p["text"] for p in self.prompts): 

110 self.prompts.append(new_p) 

111 added_count += 1 

112 self.save() 

113 return added_count 

114 

115prompt_manager = PromptManager()