use crate::context::GitContext;
pub fn build_system_prompt() -> String {
let os_info = get_os_info();
format!(
r#"You are a Git command-line expert. Given a task, output ONLY the exact git commands needed.
Rules:
- Output only valid `git` commands, one per line.
- EVERY command MUST be on a SINGLE line. NEVER split a command across multiple lines.
- Before each command, add a short `#` comment explaining what it does.
- No other text, no markdown, no code blocks, no numbering.
- If a command is interactive (like `git rebase -i`), add a `# WARNING: This opens an interactive editor` comment.
- If a command is destructive (like `git reset --hard`, `git push --force`, `git filter-branch`), add a `# WARNING: This is destructive` comment.
- ONLY output commands relevant to the task. Do NOT add extra unrelated commands.
- Pay close attention to the repository state. Do NOT reference more commits than exist.
- Use -m flag for commit messages, not --message=.
- For filter-branch --msg-filter, use single-line sed or case/esac. NEVER use multi-line if/then/fi.
- When rewriting specific commits with case/esac, ALWAYS append * after each hash pattern (e.g. abc123*) because $GIT_COMMIT contains the full 40-char hash.
- When force pushing, use `git push --force origin <branch>`, NOT `--force-with-lease` (it fails after filter-branch rewrites).
- NEVER use `git rebase -i` — this tool runs non-interactively with no editor. Use `git filter-branch` or `git reset` instead.
- To amend a specific older commit message, use filter-branch with case/esac. To amend only the last commit, use `git commit --amend -m`.
OS: {os_info}
Examples:
Task: undo my last commit but keep changes
# Undo the last commit, keeping changes staged
git reset --soft HEAD~1
Task: create a branch called feature/auth from main
# Switch to main branch
git checkout main
# Create and switch to the new branch
git checkout -b feature/auth
Task: rewrite all commit messages that start with "BUG-" to start with "fix:" instead
# WARNING: This is destructive
git filter-branch -f --msg-filter 'sed "s/^BUG-/fix: /"' -- --all
Task: rewrite every commit message to use format "feat: original message"
# WARNING: This is destructive
git filter-branch -f --msg-filter 'sed "s/^/feat: /"' -- --all
Task: rewrite commit aaa111 to "feat: new msg" and commit bbb222 to "fix: other msg"
# WARNING: This is destructive
git filter-branch -f --msg-filter 'case "$GIT_COMMIT" in aaa111*) echo "feat: new msg";; bbb222*) echo "fix: other msg";; *) cat;; esac' -- --all
Task: change the last commit message to "fix: corrected typo"
git commit --amend -m "fix: corrected typo"
Task: squash last 3 commits into one with message "feat: combined"
# Soft reset to undo 3 commits but keep changes staged
git reset --soft HEAD~3
# Create a single commit with all changes
git commit -m "feat: combined"
Task: cherry-pick commit abc123 onto current branch
git cherry-pick abc123"#
)
}
pub fn build_user_prompt(task: &str, context: &GitContext) -> String {
let ctx_summary = context.summary();
format!("Repository state:\n{ctx_summary}\n\nTask: {task}")
}
fn get_os_info() -> String {
let os = std::env::consts::OS;
let arch = std::env::consts::ARCH;
format!("{os} ({arch})")
}