Skip to content

Commit 8082bb3

Browse files
author
jzhu
committed
feat: Normalize header when syncing prompt to different app
When syncing a prompt to a different app than its original, the first line header (e.g., '# Gemini Code Assistant Instructions') is now automatically updated to match the target app (e.g., '# Claude Code Assistant Instructions'). This ensures the synced file content is consistent with its target app.
1 parent 4910f9b commit 8082bb3

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

code_assistant_manager/cli/prompts_commands.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
PROMPT_FILE_PATHS,
2121
Prompt,
2222
PromptManager,
23+
get_handler,
2324
get_prompt_file_path,
2425
)
2526

@@ -330,8 +331,9 @@ def sync_prompts(
330331
)
331332
else:
332333
# Just sync the file without changing enabled state
333-
file_path.parent.mkdir(parents=True, exist_ok=True)
334-
file_path.write_text(prompt.content, encoding="utf-8")
334+
# Use the handler's sync_prompt method to ensure proper normalization
335+
handler = get_handler(target_app)
336+
handler.sync_prompt(prompt.content, level, level_project_dir)
335337
typer.echo(
336338
f"{Colors.GREEN}✓ Synced '{prompt_id}' to {target_app} ({level}){Colors.RESET}"
337339
)

code_assistant_manager/prompts/base.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,45 @@ def get_prompt_file_path(
8989
return project_dir / filename
9090
return None
9191

92+
def _normalize_header(self, content: str) -> str:
93+
"""
94+
Normalize the first line header to match this tool's name.
95+
96+
If the content starts with a markdown header like '# Gemini Code Assistant',
97+
it will be updated to match this tool (e.g., '# Claude Code Assistant').
98+
99+
Args:
100+
content: The prompt content
101+
102+
Returns:
103+
Content with normalized header
104+
"""
105+
import re
106+
107+
lines = content.split("\n", 1)
108+
if not lines:
109+
return content
110+
111+
first_line = lines[0]
112+
# Match markdown headers like "# Gemini Code Assistant Instructions"
113+
# or "# Claude Code Assistant" etc.
114+
header_pattern = r"^#\s+(Claude|Codex|Gemini|Copilot|GitHub Copilot)(\s+.*)?"
115+
match = re.match(header_pattern, first_line, re.IGNORECASE)
116+
117+
if match:
118+
# Get the tool name with proper capitalization
119+
tool_display_name = self.tool_name.capitalize()
120+
if self.tool_name == "copilot":
121+
tool_display_name = "GitHub Copilot"
122+
123+
suffix = match.group(2) or ""
124+
new_header = f"# {tool_display_name}{suffix}"
125+
if len(lines) > 1:
126+
return new_header + "\n" + lines[1]
127+
return new_header
128+
129+
return content
130+
92131
def sync_prompt(
93132
self,
94133
content: str,
@@ -115,6 +154,9 @@ def sync_prompt(
115154
f"Tool '{self.tool_name}' does not support level '{level}'"
116155
)
117156

157+
# Normalize header to match this tool's name
158+
content = self._normalize_header(content)
159+
118160
# Ensure parent directory exists
119161
file_path.parent.mkdir(parents=True, exist_ok=True)
120162

0 commit comments

Comments
 (0)