Vernon Wee Hong KOH ревизий этого фрагмента 3 weeks ago. К ревизии
1 file changed, 5 insertions
func
| @@ -454,6 +454,11 @@ prompt() { | |||
| 454 | 454 | ||
| 455 | 455 | printf "Enhanced prompt:\n" | |
| 456 | 456 | command cat "$output_file" | |
| 457 | + | if clip < "$output_file"; then | |
| 458 | + | printf '\nEnhanced prompt copied to clipboard.\n' >&2 | |
| 459 | + | else | |
| 460 | + | printf '\nUnable to copy to clipboard; the enhanced prompt is shown above.\n' >&2 | |
| 461 | + | fi | |
| 457 | 462 | rm -f "$output_file" | |
| 458 | 463 | ||
| 459 | 464 | command auggie account status | |
Vernon Wee Hong KOH ревизий этого фрагмента 3 weeks ago. К ревизии
1 file changed, 17 insertions
func
| @@ -398,6 +398,8 @@ prompt() { | |||
| 398 | 398 | local prompt | |
| 399 | 399 | local line | |
| 400 | 400 | local output_file | |
| 401 | + | local input_keymap | |
| 402 | + | local input_status | |
| 401 | 403 | ||
| 402 | 404 | require_cli auggie "Auggie CLI" || return 1 | |
| 403 | 405 | require_cli script "script utility" || return 1 | |
| @@ -406,6 +408,21 @@ prompt() { | |||
| 406 | 408 | prompt="$*" | |
| 407 | 409 | elif [ ! -t 0 ]; then | |
| 408 | 410 | prompt="$(cat)" | |
| 411 | + | elif [ -n "${ZSH_VERSION:-}" ]; then | |
| 412 | + | # Keep all lines in one ZLE buffer so previous lines remain editable. | |
| 413 | + | input_keymap="auggie-prompt-$$-$RANDOM" | |
| 414 | + | bindkey -N "$input_keymap" emacs || return 1 | |
| 415 | + | bindkey -M "$input_keymap" '^J' self-insert | |
| 416 | + | bindkey -M "$input_keymap" '^M' self-insert-unmeta | |
| 417 | + | bindkey -M "$input_keymap" '^[[13;2u' accept-line | |
| 418 | + | bindkey -M "$input_keymap" '^[[27;2;13~' accept-line | |
| 419 | + | bindkey -M "$input_keymap" '^D' accept-line | |
| 420 | + | printf 'Enter your prompt: Enter adds a line; Shift+Enter (configured terminal) or Ctrl+D submits; Ctrl+C cancels.\n' | |
| 421 | + | prompt="" | |
| 422 | + | vared -M "$input_keymap" -p '> ' prompt | |
| 423 | + | input_status=$? | |
| 424 | + | bindkey -D "$input_keymap" | |
| 425 | + | [ "$input_status" -eq 0 ] || return "$input_status" | |
| 409 | 426 | else | |
| 410 | 427 | echo "Reading prompt... Type 'EOF' on a new line and press Enter when finished." | |
| 411 | 428 | prompt="" | |
Vernon Wee Hong KOH ревизий этого фрагмента 3 weeks ago. К ревизии
1 file changed, 47 insertions, 46 deletions
func
| @@ -105,45 +105,41 @@ alias open='open_file' | |||
| 105 | 105 | # Function: clear_history (Supports shell, Claude, Codex, and OpenCode) | |
| 106 | 106 | # ----------------------------------------------------------------------------- | |
| 107 | 107 | clear_history() { | |
| 108 | + | if [ "$#" -gt 1 ]; then | |
| 109 | + | printf "Usage: clear_history [--all | shell | claude | codex | opencode]\n" >&2 | |
| 110 | + | return 2 | |
| 111 | + | fi | |
| 108 | 112 | case "${1:-}" in | |
| 109 | 113 | --all) | |
| 110 | - | clear_history claude | |
| 111 | - | clear_history codex | |
| 112 | - | clear_history opencode | |
| 113 | - | clear_history | |
| 114 | + | local result=0 target | |
| 115 | + | for target in claude codex opencode shell; do | |
| 116 | + | clear_history "$target" || result=1 | |
| 117 | + | done | |
| 114 | 118 | ||
| 115 | 119 | if [ -t 1 ]; then | |
| 116 | 120 | command clear | |
| 117 | 121 | fi | |
| 122 | + | return "$result" | |
| 118 | 123 | ;; | |
| 119 | 124 | ||
| 120 | 125 | claude) | |
| 121 | - | if [ -d "$HOME/.claude/projects" ]; then | |
| 122 | - | # Use 'yes' to skip prompts and -f to ignore non-existent files | |
| 123 | - | yes | rm -rf "$HOME/.claude/projects"/* | |
| 124 | - | echo "Claude project history/cache cleared." | |
| 126 | + | local claude_home="${CLAUDE_CONFIG_DIR:-$HOME/.claude}" | |
| 127 | + | if [ -d "$claude_home/projects" ]; then | |
| 128 | + | command rm -rf -- "$claude_home/projects"/*(DN) || return 1 | |
| 129 | + | fi | |
| 130 | + | if [ -f "$claude_home/history.jsonl" ]; then | |
| 131 | + | : > "$claude_home/history.jsonl" || return 1 | |
| 125 | 132 | fi | |
| 133 | + | echo "Claude project history/cache cleared." | |
| 126 | 134 | ;; | |
| 127 | 135 | ||
| 128 | 136 | codex) | |
| 129 | 137 | local codex_home="${CODEX_HOME:-$HOME/.codex}" | |
| 130 | - | local codex_session_file | |
| 131 | - | local codex_session_id | |
| 132 | - | ||
| 133 | - | mkdir -p "$codex_home" | |
| 134 | - | : > "$codex_home/history.jsonl" | |
| 135 | - | ||
| 136 | - | if command -v codex >/dev/null 2>&1; then | |
| 137 | - | find "$codex_home/sessions" "$codex_home/archived_sessions" -type f -name '*.jsonl' -print 2>/dev/null | while IFS= read -r codex_session_file; do | |
| 138 | - | codex_session_id="$(sed -n 's/.*"session_id":"\([^"]*\)".*/\1/p; q' "$codex_session_file")" | |
| 139 | - | if [ -n "$codex_session_id" ]; then | |
| 140 | - | codex delete --force "$codex_session_id" >/dev/null 2>&1 || true | |
| 141 | - | fi | |
| 142 | - | done | |
| 143 | - | fi | |
| 138 | + | command mkdir -p -- "$codex_home" || return 1 | |
| 139 | + | : > "$codex_home/history.jsonl" || return 1 | |
| 144 | 140 | ||
| 145 | - | rm -rf "$codex_home/sessions" "$codex_home/archived_sessions" "$codex_home/shell_snapshots" | |
| 146 | - | mkdir -p "$codex_home/sessions" "$codex_home/archived_sessions" "$codex_home/shell_snapshots" | |
| 141 | + | command rm -rf -- "$codex_home/sessions" "$codex_home/archived_sessions" "$codex_home/shell_snapshots" || return 1 | |
| 142 | + | command mkdir -p -- "$codex_home/sessions" "$codex_home/archived_sessions" "$codex_home/shell_snapshots" || return 1 | |
| 147 | 143 | ||
| 148 | 144 | echo "Codex history cleared." | |
| 149 | 145 | ;; | |
| @@ -152,29 +148,33 @@ clear_history() { | |||
| 152 | 148 | local opencode_state_home="${XDG_STATE_HOME:-$HOME/.local/state}/opencode" | |
| 153 | 149 | local opencode_data_home="${XDG_DATA_HOME:-$HOME/.local/share}/opencode" | |
| 154 | 150 | ||
| 155 | - | mkdir -p "$opencode_state_home" "$opencode_data_home" | |
| 156 | - | : > "$opencode_state_home/prompt-history.jsonl" | |
| 157 | - | rm -f \ | |
| 151 | + | command mkdir -p -- "$opencode_state_home" "$opencode_data_home" || return 1 | |
| 152 | + | : > "$opencode_state_home/prompt-history.jsonl" || return 1 | |
| 153 | + | command rm -f -- \ | |
| 158 | 154 | "$opencode_data_home/opencode.db" \ | |
| 159 | 155 | "$opencode_data_home/opencode.db-shm" \ | |
| 160 | - | "$opencode_data_home/opencode.db-wal" | |
| 161 | - | rm -rf "$opencode_data_home/repos" "$opencode_data_home/log" | |
| 162 | - | mkdir -p "$opencode_data_home/repos" "$opencode_data_home/log" | |
| 156 | + | "$opencode_data_home/opencode.db-wal" || return 1 | |
| 157 | + | command rm -rf -- "$opencode_data_home/repos" "$opencode_data_home/log" "$opencode_data_home/snapshot" || return 1 | |
| 158 | + | command mkdir -p -- "$opencode_data_home/repos" "$opencode_data_home/log" "$opencode_data_home/snapshot" || return 1 | |
| 163 | 159 | ||
| 164 | 160 | echo "OpenCode history cleared." | |
| 165 | 161 | ;; | |
| 166 | 162 | ||
| 167 | - | *) | |
| 163 | + | ""|shell) | |
| 168 | 164 | # 1. Truncate the file | |
| 169 | - | : > "$HISTFILE" | |
| 165 | + | if [ -n "${HISTFILE:-}" ]; then | |
| 166 | + | : > "$HISTFILE" || return 1 | |
| 167 | + | fi | |
| 170 | 168 | ||
| 171 | - | # 2. Clear RAM by briefly setting history size to 0 | |
| 172 | - | local old_histsize=$HISTSIZE | |
| 173 | - | HISTSIZE=0 | |
| 174 | - | HISTSIZE=$old_histsize | |
| 169 | + | # 2. Start a fresh Zsh history context. HISTSIZE=0 retains one entry. | |
| 170 | + | builtin fc -p "${HISTFILE:-}" "$HISTSIZE" "$SAVEHIST" || return 1 | |
| 175 | 171 | ||
| 176 | 172 | echo "Shell history cleared." | |
| 177 | 173 | ;; | |
| 174 | + | *) | |
| 175 | + | printf "Usage: clear_history [--all | shell | claude | codex | opencode]\n" >&2 | |
| 176 | + | return 2 | |
| 177 | + | ;; | |
| 178 | 178 | esac | |
| 179 | 179 | } | |
| 180 | 180 | ||
| @@ -208,7 +208,7 @@ claude() { | |||
| 208 | 208 | # Shortcut for clearing cache | |
| 209 | 209 | if [[ "$1" == "clear" ]]; then | |
| 210 | 210 | clear_history claude | |
| 211 | - | return 0 | |
| 211 | + | return $? | |
| 212 | 212 | fi | |
| 213 | 213 | ||
| 214 | 214 | # Check if binary exists | |
| @@ -701,6 +701,15 @@ plan_build() { | |||
| 701 | 701 | # ----------------------------------------------------------------------------- | |
| 702 | 702 | aicommit() { | |
| 703 | 703 | local diff engine prompt | |
| 704 | + | engine=${1:-claude} | |
| 705 | + | case "$engine" in | |
| 706 | + | claude|copilot|opencode) ;; | |
| 707 | + | *) | |
| 708 | + | printf "❌ Error: Invalid engine '%s'\n" "$engine" >&2 | |
| 709 | + | printf "Usage: aicommit [claude | copilot | opencode]\n" >&2 | |
| 710 | + | return 1 | |
| 711 | + | ;; | |
| 712 | + | esac | |
| 704 | 713 | ||
| 705 | 714 | # 1. Get diff safely: exclude lock files/minified files and cap at ~100k characters to prevent CLI crashes | |
| 706 | 715 | diff=$(git diff --cached -- . ":(exclude)*.lock" ":(exclude)*-lock.json" ":(exclude)*.min.js" | head -c 100000) | |
| @@ -716,7 +725,6 @@ aicommit() { | |||
| 716 | 725 | return 1 | |
| 717 | 726 | fi | |
| 718 | 727 | ||
| 719 | - | engine=${1:-claude} | |
| 720 | 728 | prompt=$(cat "$HOME/.config/ai-commit-prompt.txt") | |
| 721 | 729 | ||
| 722 | 730 | case "$engine" in | |
| @@ -727,13 +735,6 @@ aicommit() { | |||
| 727 | 735 | "Read the provided instructions and diff, then generate and execute the commit." | |
| 728 | 736 | ;; | |
| 729 | 737 | ||
| 730 | - | codex) | |
| 731 | - | echo "🤖 Codex is analyzing staged changes..." | |
| 732 | - | cat "$HOME/.config/ai-commit-prompt.txt" <(echo -e "\n\nHere is the git diff:\n$diff") \ | |
| 733 | - | | command codex --ask-for-approval never exec --sandbox workspace-write --ephemeral \ | |
| 734 | - | "Read the provided instructions and diff, then generate and execute the commit." | |
| 735 | - | ;; | |
| 736 | - | ||
| 737 | 738 | copilot) | |
| 738 | 739 | echo "🤖 Copilot is analyzing staged changes..." | |
| 739 | 740 | copilot -p "$prompt | |
| @@ -749,7 +750,7 @@ $diff" -s --no-ask-user --allow-tool='shell(git:*)' | |||
| 749 | 750 | ||
| 750 | 751 | *) | |
| 751 | 752 | printf "❌ Error: Invalid engine '%s'\n" "$engine" >&2 | |
| 752 | - | printf "Usage: aicommit [claude | codex | copilot | opencode]\n" >&2 | |
| 753 | + | printf "Usage: aicommit [claude | copilot | opencode]\n" >&2 | |
| 753 | 754 | return 1 | |
| 754 | 755 | ;; | |
| 755 | 756 | esac | |
Vernon Wee Hong KOH ревизий этого фрагмента 3 weeks ago. К ревизии
3 files changed, 3 insertions, 33 deletions
zsh_macos.sh
| @@ -87,9 +87,6 @@ install_starship() { | |||
| 87 | 87 | ||
| 88 | 88 | download_configs() { | |
| 89 | 89 | log "Downloading custom config files..." | |
| 90 | - | local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)" | |
| 91 | - | mkdir -p "$backup" | |
| 92 | - | ||
| 93 | 90 | for f in "${CONFIG_FILES[@]}"; do | |
| 94 | 91 | # Strip the leading dot for the download URL | |
| 95 | 92 | local remote_file="${f#.}" | |
| @@ -102,10 +99,6 @@ download_configs() { | |||
| 102 | 99 | ||
| 103 | 100 | mkdir -p "$(dirname "$target")" | |
| 104 | 101 | ||
| 105 | - | if [[ -f "$target" ]]; then | |
| 106 | - | cp "$target" "$backup/" | |
| 107 | - | fi | |
| 108 | - | ||
| 109 | 102 | log "Fetching $remote_file -> $f ..." | |
| 110 | 103 | if curl -fsSL "$url" -o "$tmp"; then | |
| 111 | 104 | mv "$tmp" "$target" | |
| @@ -115,16 +108,13 @@ download_configs() { | |||
| 115 | 108 | fi | |
| 116 | 109 | done | |
| 117 | 110 | ||
| 118 | - | ok "Configs downloaded (Backup at $backup)" | |
| 111 | + | ok "Configs downloaded" | |
| 119 | 112 | } | |
| 120 | 113 | ||
| 121 | 114 | configure_zshrc() { | |
| 122 | 115 | local zshrc="$HOME/.zshrc" | |
| 123 | 116 | log "Configuring .zshrc for Oh My Zsh and Starship..." | |
| 124 | 117 | ||
| 125 | - | touch "$zshrc" | |
| 126 | - | cp "$zshrc" "$HOME/.zshrc.backup_$(date +%Y%m%d_%H%M%S)" | |
| 127 | - | ||
| 128 | 118 | cat > "$zshrc" <<'EOF' | |
| 129 | 119 | # ============================================================================= | |
| 130 | 120 | # 1. HELPER FUNCTIONS & PATH | |
zsh_ubuntu.sh
| @@ -179,9 +179,6 @@ install_starship() { | |||
| 179 | 179 | ||
| 180 | 180 | download_configs() { | |
| 181 | 181 | log "Downloading custom config files from OpenGist..." | |
| 182 | - | local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)" | |
| 183 | - | mkdir -p "$backup" | |
| 184 | - | ||
| 185 | 182 | for f in "${CONFIG_FILES[@]}"; do | |
| 186 | 183 | local remote_file="${f#.}" | |
| 187 | 184 | [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml" | |
| @@ -193,10 +190,6 @@ download_configs() { | |||
| 193 | 190 | ||
| 194 | 191 | mkdir -p "$(dirname "$target")" | |
| 195 | 192 | ||
| 196 | - | if [[ -f "$target" ]]; then | |
| 197 | - | cp "$target" "$backup/" | |
| 198 | - | fi | |
| 199 | - | ||
| 200 | 193 | log "Fetching $remote_file -> $f ..." | |
| 201 | 194 | if curl -fsSL "$url" -o "$tmp"; then | |
| 202 | 195 | mv "$tmp" "$target" | |
| @@ -206,16 +199,13 @@ download_configs() { | |||
| 206 | 199 | fi | |
| 207 | 200 | done | |
| 208 | 201 | ||
| 209 | - | ok "Configs downloaded (Backup at $backup)" | |
| 202 | + | ok "Configs downloaded" | |
| 210 | 203 | } | |
| 211 | 204 | ||
| 212 | 205 | configure_zshrc() { | |
| 213 | 206 | local zshrc="$HOME/.zshrc" | |
| 214 | 207 | log "Configuring .zshrc for Oh My Zsh and Starship..." | |
| 215 | 208 | ||
| 216 | - | touch "$zshrc" | |
| 217 | - | cp "$zshrc" "$HOME/.zshrc.backup_$(date +%Y%m%d_%H%M%S)" | |
| 218 | - | ||
| 219 | 209 | cat > "$zshrc" <<'EOF' | |
| 220 | 210 | # ============================================================================= | |
| 221 | 211 | # 1. HELPER FUNCTIONS & PATH | |
zsh_wsl.sh
| @@ -181,9 +181,6 @@ install_starship() { | |||
| 181 | 181 | ||
| 182 | 182 | download_configs() { | |
| 183 | 183 | log "Downloading custom config files from OpenGist..." | |
| 184 | - | local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)" | |
| 185 | - | mkdir -p "$backup" | |
| 186 | - | ||
| 187 | 184 | for f in "${CONFIG_FILES[@]}"; do | |
| 188 | 185 | local remote_file="${f#.}" | |
| 189 | 186 | [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml" | |
| @@ -195,10 +192,6 @@ download_configs() { | |||
| 195 | 192 | ||
| 196 | 193 | mkdir -p "$(dirname "$target")" | |
| 197 | 194 | ||
| 198 | - | if [[ -f "$target" ]]; then | |
| 199 | - | cp "$target" "$backup/" | |
| 200 | - | fi | |
| 201 | - | ||
| 202 | 195 | log "Fetching $remote_file -> $f ..." | |
| 203 | 196 | if curl -fsSL "$url" -o "$tmp"; then | |
| 204 | 197 | mv "$tmp" "$target" | |
| @@ -208,16 +201,13 @@ download_configs() { | |||
| 208 | 201 | fi | |
| 209 | 202 | done | |
| 210 | 203 | ||
| 211 | - | ok "Configs downloaded (Backup at $backup)" | |
| 204 | + | ok "Configs downloaded" | |
| 212 | 205 | } | |
| 213 | 206 | ||
| 214 | 207 | configure_zshrc() { | |
| 215 | 208 | local zshrc="$HOME/.zshrc" | |
| 216 | 209 | log "Configuring .zshrc for Oh My Zsh and Starship..." | |
| 217 | 210 | ||
| 218 | - | touch "$zshrc" | |
| 219 | - | cp "$zshrc" "$HOME/.zshrc.backup_$(date +%Y%m%d_%H%M%S)" | |
| 220 | - | ||
| 221 | 211 | cat > "$zshrc" <<'EOF' | |
| 222 | 212 | # ============================================================================= | |
| 223 | 213 | # 1. HELPER FUNCTIONS & PATH | |
Vernon Wee Hong KOH ревизий этого фрагмента 3 weeks ago. К ревизии
2 files changed, 2 insertions, 4 deletions
pathrc
| @@ -9,6 +9,7 @@ fi | |||
| 9 | 9 | ||
| 10 | 10 | # 2. Define Root Variables | |
| 11 | 11 | export DOTNET_ROOT="$HOME/.dotnet" | |
| 12 | + | export PNPM_HOME="$HOME/.local/share/pnpm" | |
| 12 | 13 | ||
| 13 | 14 | # 3. PATH INITIALIZATION | |
| 14 | 15 | # ----------------------------------------------------------------------------- | |
| @@ -17,6 +18,7 @@ append_path "$DOTNET_ROOT" | |||
| 17 | 18 | append_path "$DOTNET_ROOT/tools" | |
| 18 | 19 | append_path "$HOME/.opencode/bin" | |
| 19 | 20 | append_path "$HOME/Flutter/bin" | |
| 21 | + | append_path "$PNPM_HOME/bin" | |
| 20 | 22 | ||
| 21 | 23 | # macOS specific paths | |
| 22 | 24 | if [[ "$OSTYPE" == "darwin"* ]]; then | |
sourcerc
| @@ -10,10 +10,6 @@ if [[ -f "$HOME/.local/bin/env" && -r "$HOME/.local/bin/env" ]]; then | |||
| 10 | 10 | source "$HOME/.local/bin/env" | |
| 11 | 11 | fi | |
| 12 | 12 | ||
| 13 | - | # ============================================================================= | |
| 14 | - | # CLAUDE CODE / AI GATEWAY | |
| 15 | - | # ============================================================================= | |
| 16 | - | ||
| 17 | 13 | # ============================================================================= | |
| 18 | 14 | # SDKMAN (Java/Kotlin/Scala Version Manager) | |
| 19 | 15 | # ============================================================================= | |
Vernon Wee Hong KOH ревизий этого фрагмента 4 weeks ago. К ревизии
1 file changed, 14 insertions, 1 deletion
alias
| @@ -25,4 +25,17 @@ alias gpl='git pull' | |||
| 25 | 25 | alias grb='git rebase' | |
| 26 | 26 | alias grt='git reset' | |
| 27 | 27 | alias gst='git status' | |
| 28 | - | alias grmrf='git checkout -- . && git clean -fd' | |
| 28 | + | alias gsts='git stash push --staged' | |
| 29 | + | # Keep staged changes in the index; the stash also records their snapshot. | |
| 30 | + | alias gstu='git stash push --keep-index --include-untracked' | |
| 31 | + | alias gsta='git stash push --include-untracked' | |
| 32 | + | alias grmrf='git checkout -- . && git clean -fd' | |
| 33 | + | ||
| 34 | + | # List loaded aliases, optionally filtered by a case-insensitive keyword. | |
| 35 | + | ah() { | |
| 36 | + | if [ "$#" -eq 0 ]; then | |
| 37 | + | alias | |
| 38 | + | else | |
| 39 | + | alias | command grep -iF -- "$*" | |
| 40 | + | fi | |
| 41 | + | } | |
Vernon Wee Hong KOH ревизий этого фрагмента 1 month ago. К ревизии
1 file changed, 11 insertions
func
| @@ -106,6 +106,17 @@ alias open='open_file' | |||
| 106 | 106 | # ----------------------------------------------------------------------------- | |
| 107 | 107 | clear_history() { | |
| 108 | 108 | case "${1:-}" in | |
| 109 | + | --all) | |
| 110 | + | clear_history claude | |
| 111 | + | clear_history codex | |
| 112 | + | clear_history opencode | |
| 113 | + | clear_history | |
| 114 | + | ||
| 115 | + | if [ -t 1 ]; then | |
| 116 | + | command clear | |
| 117 | + | fi | |
| 118 | + | ;; | |
| 119 | + | ||
| 109 | 120 | claude) | |
| 110 | 121 | if [ -d "$HOME/.claude/projects" ]; then | |
| 111 | 122 | # Use 'yes' to skip prompts and -f to ignore non-existent files | |
Vernon Wee Hong KOH ревизий этого фрагмента 1 month ago. К ревизии
7 files changed, 166 insertions, 1 deletion
README.md
| @@ -39,7 +39,7 @@ The managed `aicommit` function can use Claude, Codex, Copilot, or OpenCode to c | |||
| 39 | 39 | aicommit opencode | |
| 40 | 40 | ``` | |
| 41 | 41 | ||
| 42 | - | The installers place the required OpenCode agent at `~/.config/opencode/agents/ai-commit.md`. The agent may inspect Git status, the cached diff, and recent history, and may execute `git commit`; all unrelated tools and shell commands are denied. The shared commit instructions must exist at `~/.config/ai-commit-prompt.txt`. | |
| 42 | + | The installers place the shared commit instructions at `~/.config/ai-commit-prompt.txt` and the required OpenCode agent at `~/.config/opencode/agents/ai-commit.md`. The agent is hidden from the interactive agent selector but remains available to `aicommit opencode`. It may inspect Git status, the cached diff, and recent history, and may execute `git commit`; all unrelated tools and shell commands are denied. | |
| 43 | 43 | ||
| 44 | 44 | ## Plan-build workflow | |
| 45 | 45 | ||
ai-commit-prompt.txt(файл создан)
| @@ -0,0 +1,156 @@ | |||
| 1 | + | # Git Commit Message Generator Prompt | |
| 2 | + | ||
| 3 | + | ## Role | |
| 4 | + | You are an Automated Git Commit Engine. | |
| 5 | + | ||
| 6 | + | ## Objective | |
| 7 | + | Analyze staged changes (`git diff --cached`), identify the **primary logical change**, and generate a commit message that **strictly adheres** to Conventional Commits v1.0.0. | |
| 8 | + | ||
| 9 | + | --- | |
| 10 | + | ||
| 11 | + | ## Input | |
| 12 | + | The user will provide the output of: | |
| 13 | + | ```bash | |
| 14 | + | git diff --cached | |
| 15 | + | ``` | |
| 16 | + | ||
| 17 | + | --- | |
| 18 | + | ||
| 19 | + | ## Strict Rules (Zero Tolerance) | |
| 20 | + | ||
| 21 | + | ### 1. Header Format | |
| 22 | + | **Pattern:** `type(scope): subject` | |
| 23 | + | ||
| 24 | + | | Element | Rule | | |
| 25 | + | | :--- | :--- | | |
| 26 | + | | **Type** | ONLY use: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore` | | |
| 27 | + | | **Scope** | Optional, in parentheses, entirely lowercase (e.g., `docker`, `api`, `auth`) | | |
| 28 | + | | **Subject** | Lowercase, imperative mood ("add" not "added"), NO period at the end | | |
| 29 | + | | **Length** | Header MUST be ≤ 50 characters | | |
| 30 | + | ||
| 31 | + | ### 2. Body Format | |
| 32 | + | | Element | Rule | | |
| 33 | + | | :--- | :--- | | |
| 34 | + | | **Spacing** | Exactly ONE blank line between the header and the body | | |
| 35 | + | | **Bullet Points**| Use hyphens (`-`) only | | |
| 36 | + | | **Line Length** | Each line MUST be ≤ 72 characters | | |
| 37 | + | | **Case** | Lowercase throughout | | |
| 38 | + | ||
| 39 | + | ### 3. Content Rules | |
| 40 | + | * **NO** "Merge branch" or auto-generated text. | |
| 41 | + | * **NO** Markdown formatting (bold/italic/code blocks) inside the commit message string itself. | |
| 42 | + | * **NO** periods at the end of the subject line. | |
| 43 | + | * **NO** "Co-authored-by" trailers or any co-author attributions. | |
| 44 | + | ||
| 45 | + | --- | |
| 46 | + | ||
| 47 | + | ## Execution Steps | |
| 48 | + | ||
| 49 | + | ### Step 1: Atomic Scan | |
| 50 | + | Identify the **largest cluster of related changes** (the "Primary Scope"). | |
| 51 | + | ||
| 52 | + | **Priority Order for Type Selection:** | |
| 53 | + | 1. `ci` - Pipeline, CI/CD configuration changes | |
| 54 | + | 2. `feat` - New features | |
| 55 | + | 3. `fix` - Bug fixes | |
| 56 | + | 4. `refactor` - Code restructuring | |
| 57 | + | 5. `build` - Build system, dependencies | |
| 58 | + | 6. `test` - Test additions/modifications | |
| 59 | + | 7. `chore` - Maintenance tasks | |
| 60 | + | 8. `docs` - Documentation only (use ONLY if no code changes exist) | |
| 61 | + | ||
| 62 | + | ### Step 2: Classify Changes | |
| 63 | + | Categorize all changed files: | |
| 64 | + | ||
| 65 | + | | Category | Influences Subject? | Include in Body? | | |
| 66 | + | | :--- | :---: | :---: | | |
| 67 | + | | **Primary Scope** | ✅ Yes | ✅ Yes | | |
| 68 | + | | **Supporting Changes** | ❌ No | ✅ Yes | | |
| 69 | + | | **Documentation** | ❌ No | ✅ Yes (as a single line) | | |
| 70 | + | ||
| 71 | + | > **Key Rule:** Documentation changes (`docs/`) should be mentioned in the body but MUST NOT influence the subject type unless documentation is the *only* change in the commit. | |
| 72 | + | ||
| 73 | + | ### Step 3: Draft Commit Message | |
| 74 | + | Structure the message exactly like this: | |
| 75 | + | ```text | |
| 76 | + | type(scope): subject (≤50 chars, imperative, lowercase, no period) | |
| 77 | + | ||
| 78 | + | - primary change detail 1 | |
| 79 | + | - primary change detail 2 | |
| 80 | + | - supporting change detail | |
| 81 | + | - add/update project documentation | |
| 82 | + | ``` | |
| 83 | + | ||
| 84 | + | --- | |
| 85 | + | ||
| 86 | + | ## Output Format & Execution Authorization | |
| 87 | + | ||
| 88 | + | You must output **ONLY** a single bash code block containing the complete git command. Do not provide any conversational filler, explanations, or greeting. | |
| 89 | + | ||
| 90 | + | Once you have generated the `git commit` bash command, **you are explicitly authorized to execute it directly in the terminal** (if your environment supports agentic execution). | |
| 91 | + | * Do not ask for further user confirmation. | |
| 92 | + | * Execute sequentially. | |
| 93 | + | * If the command fails, output the exact error message and halt execution. | |
| 94 | + | ||
| 95 | + | **Format Template:** | |
| 96 | + | ```bash | |
| 97 | + | git commit -m "type(scope): subject | |
| 98 | + | ||
| 99 | + | - body detail 1 | |
| 100 | + | - body detail 2 | |
| 101 | + | - body detail 3" | |
| 102 | + | ``` | |
| 103 | + | ||
| 104 | + | --- | |
| 105 | + | ||
| 106 | + | ## Examples | |
| 107 | + | ||
| 108 | + | ### Example 1: CI/CD with Documentation | |
| 109 | + | * **Changes:** `.gitlab-ci.yaml` (new), `Dockerfile` (new), `docs/deployment.md` (new) | |
| 110 | + | * **Output:** | |
| 111 | + | ```bash | |
| 112 | + | git commit -m "ci: add gitlab pipeline and docker config | |
| 113 | + | ||
| 114 | + | - add gitlab-ci.yaml with build, test, publish stages | |
| 115 | + | - add Dockerfile for container deployment | |
| 116 | + | - add deployment documentation" | |
| 117 | + | ``` | |
| 118 | + | ||
| 119 | + | ### Example 2: Feature with Config Changes | |
| 120 | + | * **Changes:** `src/auth/login.java` (new), `pom.xml` (modified), `docs/api.md` (new) | |
| 121 | + | * **Output:** | |
| 122 | + | ```bash | |
| 123 | + | git commit -m "feat(auth): add user login endpoint | |
| 124 | + | ||
| 125 | + | - implement login service with jwt tokens | |
| 126 | + | - add spring-security dependency to pom.xml | |
| 127 | + | - add api documentation" | |
| 128 | + | ``` | |
| 129 | + | ||
| 130 | + | ### Example 3: Documentation Only | |
| 131 | + | * **Changes:** `docs/setup.md` (new), `docs/testing.md` (modified), `README.md` (modified) | |
| 132 | + | * **Output:** | |
| 133 | + | ```bash | |
| 134 | + | git commit -m "docs: add setup guide and update testing docs | |
| 135 | + | ||
| 136 | + | - add initial setup guide | |
| 137 | + | - update testing documentation with examples | |
| 138 | + | - update readme with quick start section" | |
| 139 | + | ``` | |
| 140 | + | ||
| 141 | + | --- | |
| 142 | + | ||
| 143 | + | ## Quick Reference | |
| 144 | + | ||
| 145 | + | | Type | When to Use | | |
| 146 | + | | :--- | :--- | | |
| 147 | + | | `feat` | New feature for the user | | |
| 148 | + | | `fix` | Bug fix for the user | | |
| 149 | + | | `docs` | Documentation only changes | | |
| 150 | + | | `style` | Formatting, missing semicolons, etc. (no code change) | | |
| 151 | + | | `refactor` | Code change that neither fixes a bug nor adds a feature | | |
| 152 | + | | `perf` | Code change that improves performance | | |
| 153 | + | | `test` | Adding or refactoring tests | | |
| 154 | + | | `build` | Build system or external dependencies | | |
| 155 | + | | `ci` | CI configuration files and scripts | | |
| 156 | + | | `chore` | Maintenance tasks, no production code changes | | |
ai-commit.md
| @@ -1,6 +1,7 @@ | |||
| 1 | 1 | --- | |
| 2 | 2 | description: Creates one conventional commit from the staged diff supplied in the prompt. | |
| 3 | 3 | mode: primary | |
| 4 | + | hidden: true | |
| 4 | 5 | permission: | |
| 5 | 6 | "*": deny | |
| 6 | 7 | bash: | |
config.sh
| @@ -11,6 +11,7 @@ CONFIG_FILES=( | |||
| 11 | 11 | ".vimrc" | |
| 12 | 12 | ".zshrc" | |
| 13 | 13 | ".config/starship.toml" | |
| 14 | + | ".config/ai-commit-prompt.txt" | |
| 14 | 15 | ".config/opencode/agents/ai-commit.md" | |
| 15 | 16 | ) | |
| 16 | 17 | ||
| @@ -21,6 +22,7 @@ for f in "${CONFIG_FILES[@]}"; do | |||
| 21 | 22 | # Remove the leading dot for the URL path | |
| 22 | 23 | remote_name="${f#.}" | |
| 23 | 24 | [[ "$f" == ".config/starship.toml" ]] && remote_name="starship.toml" | |
| 25 | + | [[ "$f" == ".config/ai-commit-prompt.txt" ]] && remote_name="ai-commit-prompt.txt" | |
| 24 | 26 | [[ "$f" == ".config/opencode/agents/ai-commit.md" ]] && remote_name="ai-commit.md" | |
| 25 | 27 | url="$GIST_RAW_BASE/$remote_name" | |
| 26 | 28 | target="$HOME/$f" | |
zsh_macos.sh
| @@ -28,6 +28,7 @@ CONFIG_FILES=( | |||
| 28 | 28 | ".vimrc" | |
| 29 | 29 | ".zshrc" | |
| 30 | 30 | ".config/starship.toml" | |
| 31 | + | ".config/ai-commit-prompt.txt" | |
| 31 | 32 | ".config/opencode/agents/ai-commit.md" | |
| 32 | 33 | ) | |
| 33 | 34 | ||
| @@ -93,6 +94,7 @@ download_configs() { | |||
| 93 | 94 | # Strip the leading dot for the download URL | |
| 94 | 95 | local remote_file="${f#.}" | |
| 95 | 96 | [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml" | |
| 97 | + | [[ "$f" == ".config/ai-commit-prompt.txt" ]] && remote_file="ai-commit-prompt.txt" | |
| 96 | 98 | [[ "$f" == ".config/opencode/agents/ai-commit.md" ]] && remote_file="ai-commit.md" | |
| 97 | 99 | local url="$GIST_RAW_BASE/$remote_file" | |
| 98 | 100 | local target="$HOME/$f" | |
zsh_ubuntu.sh
| @@ -31,6 +31,7 @@ CONFIG_FILES=( | |||
| 31 | 31 | ".vimrc" | |
| 32 | 32 | ".zshrc" | |
| 33 | 33 | ".config/starship.toml" | |
| 34 | + | ".config/ai-commit-prompt.txt" | |
| 34 | 35 | ".config/opencode/agents/ai-commit.md" | |
| 35 | 36 | ) | |
| 36 | 37 | ||
| @@ -184,6 +185,7 @@ download_configs() { | |||
| 184 | 185 | for f in "${CONFIG_FILES[@]}"; do | |
| 185 | 186 | local remote_file="${f#.}" | |
| 186 | 187 | [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml" | |
| 188 | + | [[ "$f" == ".config/ai-commit-prompt.txt" ]] && remote_file="ai-commit-prompt.txt" | |
| 187 | 189 | [[ "$f" == ".config/opencode/agents/ai-commit.md" ]] && remote_file="ai-commit.md" | |
| 188 | 190 | local url="$GIST_RAW_BASE/$remote_file" | |
| 189 | 191 | local target="$HOME/$f" | |
zsh_wsl.sh
| @@ -31,6 +31,7 @@ CONFIG_FILES=( | |||
| 31 | 31 | ".vimrc" | |
| 32 | 32 | ".zshrc" | |
| 33 | 33 | ".config/starship.toml" | |
| 34 | + | ".config/ai-commit-prompt.txt" | |
| 34 | 35 | ".config/opencode/agents/ai-commit.md" | |
| 35 | 36 | ) | |
| 36 | 37 | ||
| @@ -186,6 +187,7 @@ download_configs() { | |||
| 186 | 187 | for f in "${CONFIG_FILES[@]}"; do | |
| 187 | 188 | local remote_file="${f#.}" | |
| 188 | 189 | [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml" | |
| 190 | + | [[ "$f" == ".config/ai-commit-prompt.txt" ]] && remote_file="ai-commit-prompt.txt" | |
| 189 | 191 | [[ "$f" == ".config/opencode/agents/ai-commit.md" ]] && remote_file="ai-commit.md" | |
| 190 | 192 | local url="$GIST_RAW_BASE/$remote_file" | |
| 191 | 193 | local target="$HOME/$f" | |
Vernon Wee Hong KOH ревизий этого фрагмента 2 months ago. К ревизии
7 files changed, 33 insertions, 1 deletion
README.md
| @@ -31,6 +31,16 @@ eval "$(starship init zsh)" | |||
| 31 | 31 | ||
| 32 | 32 | Starship owns the prompt and loads after Oh My Zsh. The managed Starship config is installed at `~/.config/starship.toml`. A Nerd Font is required for the Powerline symbols. | |
| 33 | 33 | ||
| 34 | + | ## AI commits | |
| 35 | + | ||
| 36 | + | The managed `aicommit` function can use Claude, Codex, Copilot, or OpenCode to create a commit from staged changes: | |
| 37 | + | ||
| 38 | + | ```zsh | |
| 39 | + | aicommit opencode | |
| 40 | + | ``` | |
| 41 | + | ||
| 42 | + | The installers place the required OpenCode agent at `~/.config/opencode/agents/ai-commit.md`. The agent may inspect Git status, the cached diff, and recent history, and may execute `git commit`; all unrelated tools and shell commands are denied. The shared commit instructions must exist at `~/.config/ai-commit-prompt.txt`. | |
| 43 | + | ||
| 34 | 44 | ## Plan-build workflow | |
| 35 | 45 | ||
| 36 | 46 | The local `plan_build` function is a thin cached launcher for the canonical public [plan-build gist](https://opengist.resetrix.work/weehong/plan-build). When curl is available, each invocation stages `plan_build.zsh`, `SKILL.md`, and `ARCHITECT.md`, requires all three to be non-empty, and syntax-checks the executable. It then moves the complete bundle into a unique immutable release directory and atomically switches one `current` symlink. Refresh activation is serialized with a kernel-backed Zsh file lock so concurrent callers cannot mix releases and crashes cannot leave a stale lock. If refresh fails, the launcher preserves and uses the last complete, validated release and repairs its skill links. Zsh is always required; curl is required only when no valid cached release exists. | |
ai-commit.md(файл создан)
| @@ -0,0 +1,14 @@ | |||
| 1 | + | --- | |
| 2 | + | description: Creates one conventional commit from the staged diff supplied in the prompt. | |
| 3 | + | mode: primary | |
| 4 | + | permission: | |
| 5 | + | "*": deny | |
| 6 | + | bash: | |
| 7 | + | "*": deny | |
| 8 | + | "git status *": allow | |
| 9 | + | "git diff --cached*": allow | |
| 10 | + | "git log *": allow | |
| 11 | + | "git commit *": allow | |
| 12 | + | --- | |
| 13 | + | ||
| 14 | + | Follow the supplied commit instructions and staged diff. Generate a concise conventional commit message, then execute exactly one `git commit` with that message. You may inspect Git status, the cached diff, and recent log. Do not modify files or change the staged set. | |
config.sh
| @@ -11,6 +11,7 @@ CONFIG_FILES=( | |||
| 11 | 11 | ".vimrc" | |
| 12 | 12 | ".zshrc" | |
| 13 | 13 | ".config/starship.toml" | |
| 14 | + | ".config/opencode/agents/ai-commit.md" | |
| 14 | 15 | ) | |
| 15 | 16 | ||
| 16 | 17 | echo "Starting configuration download..." | |
| @@ -20,6 +21,7 @@ for f in "${CONFIG_FILES[@]}"; do | |||
| 20 | 21 | # Remove the leading dot for the URL path | |
| 21 | 22 | remote_name="${f#.}" | |
| 22 | 23 | [[ "$f" == ".config/starship.toml" ]] && remote_name="starship.toml" | |
| 24 | + | [[ "$f" == ".config/opencode/agents/ai-commit.md" ]] && remote_name="ai-commit.md" | |
| 23 | 25 | url="$GIST_RAW_BASE/$remote_name" | |
| 24 | 26 | target="$HOME/$f" | |
| 25 | 27 | tmp="${target}.tmp.$$" | |
func
| @@ -733,7 +733,7 @@ $diff" -s --no-ask-user --allow-tool='shell(git:*)' | |||
| 733 | 733 | ||
| 734 | 734 | opencode) | |
| 735 | 735 | echo "🤖 OpenCode is analyzing staged changes..." | |
| 736 | - | cat "$HOME/.config/ai-commit-prompt.txt" <(echo -e "\n\nHere is the git diff:\n$diff") | opencode run --agent "AI commit" | |
| 736 | + | cat "$HOME/.config/ai-commit-prompt.txt" <(echo -e "\n\nHere is the git diff:\n$diff") | opencode run --agent ai-commit | |
| 737 | 737 | ;; | |
| 738 | 738 | ||
| 739 | 739 | *) | |
zsh_macos.sh
| @@ -28,6 +28,7 @@ CONFIG_FILES=( | |||
| 28 | 28 | ".vimrc" | |
| 29 | 29 | ".zshrc" | |
| 30 | 30 | ".config/starship.toml" | |
| 31 | + | ".config/opencode/agents/ai-commit.md" | |
| 31 | 32 | ) | |
| 32 | 33 | ||
| 33 | 34 | # ============================= | |
| @@ -92,6 +93,7 @@ download_configs() { | |||
| 92 | 93 | # Strip the leading dot for the download URL | |
| 93 | 94 | local remote_file="${f#.}" | |
| 94 | 95 | [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml" | |
| 96 | + | [[ "$f" == ".config/opencode/agents/ai-commit.md" ]] && remote_file="ai-commit.md" | |
| 95 | 97 | local url="$GIST_RAW_BASE/$remote_file" | |
| 96 | 98 | local target="$HOME/$f" | |
| 97 | 99 | local tmp="${target}.tmp.$$" | |
zsh_ubuntu.sh
| @@ -31,6 +31,7 @@ CONFIG_FILES=( | |||
| 31 | 31 | ".vimrc" | |
| 32 | 32 | ".zshrc" | |
| 33 | 33 | ".config/starship.toml" | |
| 34 | + | ".config/opencode/agents/ai-commit.md" | |
| 34 | 35 | ) | |
| 35 | 36 | ||
| 36 | 37 | # ============================= | |
| @@ -183,6 +184,7 @@ download_configs() { | |||
| 183 | 184 | for f in "${CONFIG_FILES[@]}"; do | |
| 184 | 185 | local remote_file="${f#.}" | |
| 185 | 186 | [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml" | |
| 187 | + | [[ "$f" == ".config/opencode/agents/ai-commit.md" ]] && remote_file="ai-commit.md" | |
| 186 | 188 | local url="$GIST_RAW_BASE/$remote_file" | |
| 187 | 189 | local target="$HOME/$f" | |
| 188 | 190 | local tmp="${target}.tmp.$$" | |
zsh_wsl.sh
| @@ -31,6 +31,7 @@ CONFIG_FILES=( | |||
| 31 | 31 | ".vimrc" | |
| 32 | 32 | ".zshrc" | |
| 33 | 33 | ".config/starship.toml" | |
| 34 | + | ".config/opencode/agents/ai-commit.md" | |
| 34 | 35 | ) | |
| 35 | 36 | ||
| 36 | 37 | # ============================= | |
| @@ -185,6 +186,7 @@ download_configs() { | |||
| 185 | 186 | for f in "${CONFIG_FILES[@]}"; do | |
| 186 | 187 | local remote_file="${f#.}" | |
| 187 | 188 | [[ "$f" == ".config/starship.toml" ]] && remote_file="starship.toml" | |
| 189 | + | [[ "$f" == ".config/opencode/agents/ai-commit.md" ]] && remote_file="ai-commit.md" | |
| 188 | 190 | local url="$GIST_RAW_BASE/$remote_file" | |
| 189 | 191 | local target="$HOME/$f" | |
| 190 | 192 | local tmp="${target}.tmp.$$" | |
Vernon Wee Hong KOH ревизий этого фрагмента 2 months ago. К ревизии
1 file changed, 1 insertion, 1 deletion
func
| @@ -733,7 +733,7 @@ $diff" -s --no-ask-user --allow-tool='shell(git:*)' | |||
| 733 | 733 | ||
| 734 | 734 | opencode) | |
| 735 | 735 | echo "🤖 OpenCode is analyzing staged changes..." | |
| 736 | - | cat "$HOME/.config/ai-commit-prompt.txt" <(echo -e "\n\nHere is the git diff:\n$diff") | opencode run | |
| 736 | + | cat "$HOME/.config/ai-commit-prompt.txt" <(echo -e "\n\nHere is the git diff:\n$diff") | opencode run --agent "AI commit" | |
| 737 | 737 | ;; | |
| 738 | 738 | ||
| 739 | 739 | *) | |