Full Code of wulfgarpro/history-sync for AI

master ea22b3c50768 cached
8 files
21.5 KB
6.2k tokens
1 requests
Download .txt
Repository: wulfgarpro/history-sync
Branch: master
Commit: ea22b3c50768
Files: 8
Total size: 21.5 KB

Directory structure:
gitextract_g9lsxsyn/

├── .github/
│   └── workflows/
│       └── actions.yml
├── .gitignore
├── LICENSE
├── README.md
├── history-sync.plugin.zsh
└── test/
    ├── Dockerfile
    ├── test.zsh
    └── zshrc

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/actions.yml
================================================
name: history-sync
env:
  ACCESS_KEY: ${{ secrets.ACCESS_KEY }}
on: [push, workflow_dispatch]
jobs:
  setup_and_test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: docker build . --file test/Dockerfile --build-arg ACCESS_KEY=${ACCESS_KEY} --tag test/history-sync:latest
      - run: docker run test/history-sync:latest; exit $?


================================================
FILE: .gitignore
================================================
zsh_history_test*
.*.swp
*.swp


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2017 James Fraser <wulfgar.pro@gmail.com> (https://www.wulfgar.pro)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: README.md
================================================
[![history-sync](https://github.com/wulfgarpro/history-sync/actions/workflows/actions.yml/badge.svg)](https://github.com/wulfgarpro/history-sync/actions/workflows/actions.yml)

# history-sync

> An Oh My Zsh plugin for GPG encrypted, Internet synchronized Zsh history using Git.

## Installation

```bash
sudo apt install gpg git
git clone git@github.com:wulfgarpro/history-sync.git
cp -r history-sync ~/.oh-my-zsh/plugins
```

Open `.zshrc` file and add `history-sync` to the plugins list:

```bash
plugins=(... history-sync)
```

The reaload Zsh:

```bash
exec zsh
```

## Usage

Before using `history-sync`, ensure you have:

1. A hosted Git repository, e.g. GitHub, Bitbucket, with SSH key access.
2. A configured GPG key pair for encrypting/decrypting your history file, and the public keys of all
   nodes in your web-of-trust.
   * See [the GnuPG documentation](https://www.gnupg.org/documentation/) for details.

Once set up, configure the following environment variables:

* `ZSH_HISTORY_FILE`: your `zsh_history` file location
* `ZSH_HISTORY_PROJ`: Git project for storing `zsh_history`
* `ZSH_HISTORY_FILE_ENC`: encrypted history file location
* `ZSH_HISTORY_COMMIT_MSG`: default commit message when pushing
* `ZSH_HISTORY_DEFAULT_RECIPIENT`: default recipient for `zhps`

Defaults:

```bash
ZSH_HISTORY_FILE_NAME=".zsh_history"
ZSH_HISTORY_FILE="${HOME}/${ZSH_HISTORY_FILE_NAME}"
ZSH_HISTORY_PROJ="${HOME}/.zsh_history_proj"
ZSH_HISTORY_FILE_ENC_NAME="zsh_history"
ZSH_HISTORY_FILE_ENC="${ZSH_HISTORY_PROJ}/${ZSH_HISTORY_FILE_ENC_NAME}"
ZSH_HISTORY_COMMIT_MSG="latest $(date)"
ZSH_HISTORY_DEFAULT_RECIPIENT=""
```

Optional:

* `ZSH_HISTORY_GIT_REMOTE`: if set, the plugin clones the remote repo on first use

## Commands

```bash
# Pull history
zhpl

# Push history
zhps -r "John Brown" -r 876T3F78 -r ...

# Or set a default recipient to omit -r:
# ZSH_HISTORY_DEFAULT_RECIPIENT="John Brown"

# Pull + push history
zhsync
```

## Demo

Check out the [screen cast](https://asciinema.org/a/43575).

## Licence

MIT @ [James Fraser](https://www.wulfgar.pro)


================================================
FILE: history-sync.plugin.zsh
================================================
# ----------------------------------------------------------------
# Description
# ----------------------------------------------------------------
# An Oh My Zsh plugin for GPG encrypted, Internet synchronized Zsh
# history using Git.
#
# ----------------------------------------------------------------
# James Fraser <wulfgar.pro@gmail.com> - https://www.wulfgar.pro
# ----------------------------------------------------------------

autoload -U colors && colors

alias zhpl=history_sync_pull
alias zhps=history_sync_push
alias zhsync="history_sync_pull && history_sync_push"

CP() { command cp "$@"; }
MV() { command mv "$@"; }
RM() { command rm "$@"; }
TR() { LC_ALL=C command tr "$@"; }
AWK() { command awk "$@"; }
CAT() { command cat "$@"; }
GIT() { command git "$@"; }
GPG() { command gpg "$@"; }
SED() { command sed "$@"; }
DATE() { command date "$@"; }
FOLD() { command fold "$@"; }
GREP() { command grep "$@"; }
HEAD() { command head "$@"; }
PERL() { command perl "$@"; }
SORT() { LC_ALL=C command sort "$@"; }
MKTEMP() { command mktemp "$@"; }

ZSH_HISTORY_PROJ="${ZSH_HISTORY_PROJ:-${HOME}/.zsh_history_proj}"
ZSH_HISTORY_FILE_NAME="${ZSH_HISTORY_FILE_NAME:-.zsh_history}"
ZSH_HISTORY_FILE="${ZSH_HISTORY_FILE:-${HOME}/${ZSH_HISTORY_FILE_NAME}}"
ZSH_HISTORY_FILE_ENC_NAME="${ZSH_HISTORY_FILE_ENC_NAME:-zsh_history}"
ZSH_HISTORY_FILE_ENC="${ZSH_HISTORY_FILE_ENC:-${ZSH_HISTORY_PROJ}/${ZSH_HISTORY_FILE_ENC_NAME}}"
ZSH_HISTORY_FILE_DECRYPT_NAME="${ZSH_HISTORY_FILE_DECRYPT_NAME:-zsh_history_decrypted}"
ZSH_HISTORY_FILE_MERGED_NAME="${ZSH_HISTORY_FILE_MERGED_NAME:-zsh_history_merged}"
ZSH_HISTORY_COMMIT_MSG="${ZSH_HISTORY_COMMIT_MSG:-latest $(DATE)}"
ZSH_HISTORY_DEFAULT_RECIPIENT="${ZSH_HISTORY_DEFAULT_RECIPIENT:-}"

_print_git_error_msg() {
    echo "$bold_color${fg[red]}There's a problem with git repository: ${ZSH_HISTORY_PROJ}.$reset_color"
    return
}

_print_gpg_encrypt_error_msg() {
    echo "$bold_color${fg[red]}GPG failed to encrypt history file.$reset_color"
    return
}

_print_gpg_decrypt_error_msg() {
    echo "$bold_color${fg[red]}GPG failed to decrypt history file.$reset_color"
    return
}

_usage() {
    echo "Usage: [ [-r <string> ...] [-y] ]" 1>&2
    echo
    echo "Optional args:"
    echo
    echo "      -r recipients"
    echo "      -s signers"
    echo "      -y force"
    return
}

# "Squash" each multi-line command in the passed history files to one line
_squash_multiline_commands_in_files() {
    # Create temporary files
    # Use global variables to use same path's in the restore-multi-line commands
    # function
    TMP_FILE_1=$(mktemp)
    TMP_FILE_2=$(mktemp)

    # Generate random character sequences to replace \n and anchor the first
    # line of a command (use global variable for new-line-replacement to use it
    # in the restore-multi-line commands function)
    NL_REPLACEMENT=$(TR -dc 'a-zA-Z0-9' < /dev/urandom |
        FOLD -w 32 | HEAD -n 1)
    local FIRST_LINE_ANCHOR=$(TR -dc 'a-zA-Z0-9' < /dev/urandom |
        FOLD -w 32 | HEAD -n 1)

    for i in "$ZSH_HISTORY_FILE" "$ZSH_HISTORY_FILE_DECRYPT_NAME"; do
        # Filter out multi-line commands and save them to a separate file
        GREP -v -B 1 '^: [0-9]\{1,10\}:[0-9]\+;' "${i}" |
            GREP -v -e '^--$' > "${TMP_FILE_1}"

        # Filter out multi-line commands and remove them from the original file
        GREP -v -x -F -f "${TMP_FILE_1}" "${i}" > "${TMP_FILE_2}" \
            && MV "${TMP_FILE_2}" "${i}"

        # Add anchor before the first line of each command
        SED "s/\(^: [0-9]\{1,10\}:[0-9]\+;\)/${FIRST_LINE_ANCHOR} \1/" \
            "${TMP_FILE_1}" > "${TMP_FILE_2}" \
            && MV "${TMP_FILE_2}" "${TMP_FILE_1}"

        # Replace all \n with a sequence of symbols
        if [[ "$(SED --version 2>&1)"  == *"GNU"* ]]; then
          SED ':a;N;$!ba;s/\n/'" ${NL_REPLACEMENT} "'/g' \
              "${TMP_FILE_1}" > "${TMP_FILE_2}"
        else
          # Assume BSD `sed`
          PERL -0777 -pe 's/\n/'" ${NL_REPLACEMENT} "'/g' \
            "${TMP_FILE_1}" > "${TMP_FILE_2}"
        fi
        MV "${TMP_FILE_2}" "${TMP_FILE_1}"

        # Replace first line anchor by \n
        SED "s/${FIRST_LINE_ANCHOR} \(: [0-9]\{1,10\}:[0-9]\+;\)/\n\1/g" \
            "${TMP_FILE_1}" > "${TMP_FILE_2}" \
            && MV "${TMP_FILE_2}" "${TMP_FILE_1}"

        # Merge squashed multiline commands to the history file
        CAT "${TMP_FILE_1}" >> "${i}"

        # Sort history file
        SORT -n < "${i}" > "${TMP_FILE_1}" && MV "${TMP_FILE_1}" "${i}"
    done
}

# Restore multi-line commands in the history file
_restore_multiline_commands_in_file() {
    # Filter unnecessary lines from the history file (Binary file ... matches)
    # and save them in a separate file
    GREP -v '^: [0-9]\{1,10\}:[0-9]\+;' "$ZSH_HISTORY_FILE" > "${TMP_FILE_1}"

    # Filter out unnecessary lines and remove them from the original file
    GREP -v -x -F -f "${TMP_FILE_1}" "$ZSH_HISTORY_FILE" > "${TMP_FILE_2}" && \
        MV "${TMP_FILE_2}" "$ZSH_HISTORY_FILE"

    # Replace the sequence of symbols by \n to restore multi-line commands
    SED "s/ ${NL_REPLACEMENT} /\n/g" "$ZSH_HISTORY_FILE" > "${TMP_FILE_1}" \
        && MV "${TMP_FILE_1}" "$ZSH_HISTORY_FILE"

    # Unset global variables
    unset NL_REPLACEMENT TMP_FILE_1 TMP_FILE_2
}

# Pull current master, decrypt, and merge with .zsh_history
history_sync_pull() {
    # Get options force
    local force=false
    while getopts y opt; do
        case "$opt" in
            y)
                force=true
                ;;
        esac
    done
    DIR=$(pwd)

    # Backup
    if [[ $force = false ]]; then
        CP -av "$ZSH_HISTORY_FILE" "$ZSH_HISTORY_FILE.backup" 1>&2
    fi


    # Clone if not exist
    if [[ ! -d "$ZSH_HISTORY_PROJ" ]]; then
        if [[ ! -v ZSH_HISTORY_GIT_REMOTE ]]; then
            _print_git_error_msg
            return
        fi

        "$GIT" clone "$ZSH_HISTORY_GIT_REMOTE" "$ZSH_HISTORY_PROJ"
        if [[ "$?" != 0 ]]; then
            _print_git_error_msg
            return
        fi
    fi

    # Pull
    cd "$ZSH_HISTORY_PROJ" && GIT pull
    if [[ "$?" != 0 ]]; then
        _print_git_error_msg
        cd "$DIR"
        return
    fi

    # Decrypt
    GPG --output "$ZSH_HISTORY_FILE_DECRYPT_NAME" --decrypt "$ZSH_HISTORY_FILE_ENC"
    if [[ "$?" != 0 ]]; then
        _print_gpg_decrypt_error_msg
        cd "$DIR"
        return
    fi

    # Check if EXTENDED_HISTORY is enabled, and if so, "squash" each multi-line
    # command in local and decrypted history files to one line
    [[ -o extendedhistory ]] && _squash_multiline_commands_in_files

    # Merge
    CAT "$ZSH_HISTORY_FILE" "$ZSH_HISTORY_FILE_DECRYPT_NAME" | \
      AWK '/:[0-9]/ { if(s) { print s } s=$0 } !/:[0-9]/ { s=s"\n"$0 } END { print s }' | \
      SORT -u > "$ZSH_HISTORY_FILE_MERGED_NAME"
    MV "$ZSH_HISTORY_FILE_MERGED_NAME" "$ZSH_HISTORY_FILE"
    RM  "$ZSH_HISTORY_FILE_DECRYPT_NAME"
    cd  "$DIR"

    # Check if EXTENDED_HISTORY is enabled, and if so, restore multi-line
    # commands in the local history file
    [[ -o extendedhistory ]] && _restore_multiline_commands_in_file
    # Strip trailing '\' if the next line is blank
    SED -E -i '/\\$/ { N; s/\\+\n$/\n/ }' "$ZSH_HISTORY_FILE"
    # Strip blank lines
    SED -i '/^$/d' "$ZSH_HISTORY_FILE"
}

# Encrypt and push current history to master
history_sync_push() {
    # Get options recipients, force
    local recipients=()
    local signers=()
    local force=false
    while getopts r:s:y opt; do
        case "$opt" in
            r)
                recipients+=("$OPTARG")
                ;;
            s)
                signers+=("$OPTARG")
                ;;
            y)
                force=true
                ;;
            *)
                _usage
                return
                ;;
        esac
    done

    # Encrypt
    if ! [[ "${#recipients[@]}" > 0 ]]; then
        if [[ -n "$ZSH_HISTORY_DEFAULT_RECIPIENT" ]]; then
            recipients+=("$ZSH_HISTORY_DEFAULT_RECIPIENT")
        else
            echo -n "Please enter GPG recipient name: "
            read name
            recipients+=("$name")
        fi
    fi

    GPG_ENCRYPT_CMD_OPT="--yes -v "
    for r in "${recipients[@]}"; do
        GPG_ENCRYPT_CMD_OPT+="-r \"$r\" "
    done
    if [[ "${#signers[@]}" > 0 ]]; then
        GPG_ENCRYPT_CMD_OPT+="--sign "
        for s in "${signers[@]}"; do
            GPG_ENCRYPT_CMD_OPT+="--default-key \"$s\" "
        done
    fi

    if [[ "$GPG_ENCRYPT_CMD_OPT" != *"--sign"* ]]; then
        if [[ $force = false ]]; then
            echo -n "$bold_color${fg[yellow]}Do you want to sign with first key found in secret keyring (y/N)?$reset_color "
            read sign
        else
            sign='y'
        fi

        case "$sign" in
            [Yy]* )
                    GPG_ENCRYPT_CMD_OPT+="--sign "
                    ;;
                * )
                    ;;
        esac
    fi

    if [[ "$GPG_ENCRYPT_CMD_OPT" =~ '.(-r).+.' ]]; then
        GPG_ENCRYPT_CMD_OPT+="--encrypt --armor --output \"$ZSH_HISTORY_FILE_ENC\" \"$ZSH_HISTORY_FILE\""
        eval GPG "$GPG_ENCRYPT_CMD_OPT"
        if [[ "$?" != 0 ]]; then
            _print_gpg_encrypt_error_msg
            return
        fi

        # Commit
        if [[ $force = false ]]; then
            echo -n "$bold_color${fg[yellow]}Do you want to commit current local history file (y/N)?$reset_color "
            read commit
        else
            commit='y'
        fi

        if [[ -n "$commit" ]]; then
            case "$commit" in
                [Yy]* )
                    DIR=$(pwd)
                    cd "$ZSH_HISTORY_PROJ" && GIT add * && GIT commit -m "$ZSH_HISTORY_COMMIT_MSG"
                    local local_status=$?

                    if [[ $force = false ]]; then
                        echo -n "$bold_color${fg[yellow]}Do you want to push to remote (y/N)?$reset_color "
                        read push
                    else
                        push='y'
                    fi

                    if [[ -n "$push" ]]; then
                        case "$push" in
                            [Yy]* )
                                GIT push
                                local_status=$?
                                ;;
                        esac
                    fi

                    cd "$DIR"
                    if [[ "$local_status" != 0 ]]; then
                        _print_git_error_msg
                        return
                    fi
                    ;;
                * )
                    ;;
            esac
        fi
    fi
}


================================================
FILE: test/Dockerfile
================================================
FROM ubuntu:22.04

# Install system packages
RUN apt-get update \
  && apt-get install -y --no-install-recommends \
    ca-certificates \
    curl \
    git \
    zsh \
    gpg \
    gpg-agent \
    ripgrep \
  && rm -rf /var/lib/apt/lists/*

# Install oh-my-zsh and history-sync plugin
RUN bash -c 'set -o pipefail && curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh | sh -e' \
  && mkdir -p /root/.oh-my-zsh/plugins/history-sync
COPY history-sync.plugin.zsh /root/.oh-my-zsh/plugins/history-sync/
# Install a basic `zshrc`
COPY test/zshrc /root/.zshrc
# Install the test script
COPY test/test.zsh /root
RUN chmod +x /root/test.zsh

ARG ACCESS_KEY
ENV ACCESS_KEY=${ACCESS_KEY}
ENTRYPOINT ["/usr/bin/zsh"]
CMD ["-i", "-c", "source /root/test.zsh ${ACCESS_KEY}"]


================================================
FILE: test/test.zsh
================================================
#!/usr/bin/env zsh

ACCESS_KEY=$1

set -e
gpg -q --quick-gen-key --yes --batch --passphrase '' $UID
git config --global user.name "James Fraser"
git config --global user.email "wulfgar.pro@gmail.com"
git clone "https://$ACCESS_KEY@github.com/wulfgarpro/history-sync-test" ~/.zsh_history_proj
set +e

function success() {
    echo $fg[green]"$1"$reset_color
}

function failure() {
    echo $fg[red]"$1"$reset_color
    exit 1
}

function info() {
    echo $fg[yellow]"$1"$reset_color
}

function check_fn_exists() {
    typeset -f "$1" >/dev/null
    [[ $? -eq 0 ]] || {failure "FAILURE: Function '$1' missing"}
}

function check_alias_exists() {
    alias "$1" >/dev/null
    [[ $? -eq 0 ]] || {failure "FAILURE: Alias '$1' missing"}
}

function check_env_exists() {
    [[ -v $1 ]]
    [[ $? -eq 0 ]] || {failure "FAILURE: Environment variable '$1' missing"}
}

function check_history() {
    cat ~/.zsh_history 
    rg -U "$1" ~/.zsh_history >/dev/null
    [[ $? -eq 0 ]] || {failure "FAILURE: History did not match '$1'"}
}

function setup() {
    set -e
    [[ -d ~/.zsh_history_proj ]]
    # Clear existing history file
    echo -n "" > ~/.zsh_history_proj/zsh_history
    set +e
}

info "TEST HISTORY-SYNC FUNCTIONS EXIST"
check_fn_exists _print_git_error_msg
check_fn_exists _print_gpg_encrypt_error_msg
check_fn_exists _print_gpg_decrypt_error_msg
check_fn_exists _usage
check_fn_exists history_sync_pull
check_fn_exists history_sync_push
success "SUCCESS"

info "TEST HISTORY-SYNC ALIASES EXIST"
check_alias_exists zhps
check_alias_exists zhpl
check_alias_exists zhsync
success "SUCCESS"

info "TEST ENVIRONMENT VARIABLES EXIST"
check_env_exists ZSH_HISTORY_PROJ
check_env_exists ZSH_HISTORY_FILE_NAME
check_env_exists ZSH_HISTORY_FILE
check_env_exists ZSH_HISTORY_FILE_ENC_NAME
check_env_exists ZSH_HISTORY_FILE_ENC
check_env_exists ZSH_HISTORY_FILE_DECRYPT_NAME
check_env_exists ZSH_HISTORY_COMMIT_MSG
success "SUCCESS"

info "TEST SYNC HISTORY BASIC 0"
setup
RAND=$RANDOM
echo "1 echo $RAND" >> ~/.zsh_history
zhps -y -r $UID && zhpl -y
check_history "^1 echo $RAND$"
success "SUCCESS"

info "TEST SYNC HISTORY BASIC 1"
setup
RAND0=$RANDOM
RAND1=$RANDOM
RAND2=$RANDOM
RAND3=$RANDOM
RAND4=$RANDOM
echo "1 echo $RAND0" >> ~/.zsh_history
echo "2 echo $RAND1" >> ~/.zsh_history
echo "3 echo $RAND2" >> ~/.zsh_history
echo "4 echo $RAND3" >> ~/.zsh_history
echo "5 echo $RAND4" >> ~/.zsh_history
zhps -y -r $UID -s $UID && zhpl -y
check_history "^1 echo $RAND0$"
check_history "^2 echo $RAND1$"
check_history "^3 echo $RAND2$"
check_history "^4 echo $RAND3$"
check_history "^5 echo $RAND4$"
success "SUCCESS"

info "TEST SYNC HISTORY MULTI-LINE 0"
setup
echo "1 for i in {1..3}; do
echo \$i
done" >> ~/.zsh_history
zhps -y -r $UID && zhpl -y
check_history "^1 for i in \{1..3\}; do\necho \\\$i\ndone$"
success "SUCCESS"

info "TEST SYNC HISTORY MULTI-LINE PERL"
setup
alias sed="echo"
echo "1 for i in {1..3}; do
echo \$i
done" >> ~/.zsh_history
zhps -y -r $UID && zhpl -y
check_history "^1 for i in \{1..3\}; do\necho \\\$i\ndone$"
unalias sed
success "SUCCESS"


================================================
FILE: test/zshrc
================================================
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH

# Path to your oh-my-zsh installation.
export ZSH="/root/.oh-my-zsh"

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="robbyrussell"

# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in $ZSH/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )

# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"

# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE="true"

# Uncomment one of the following lines to change the auto-update behavior
# zstyle ':omz:update' mode disabled  # disable automatic updates
# zstyle ':omz:update' mode auto      # update automatically without asking
# zstyle ':omz:update' mode reminder  # just remind me to update when it's time

# Uncomment the following line to change how often to auto-update (in days).
# zstyle ':omz:update' frequency 13

# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS="true"

# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"

# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"

# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION="true"

# Uncomment the following line to display red dots whilst waiting for completion.
# You can also set it to another string to have that shown instead of the default red dots.
# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
# COMPLETION_WAITING_DOTS="true"

# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"

# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# You can set one of the optional three formats:
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# or set a custom format using the strftime function format specifications,
# see 'man strftime' for details.
# HIST_STAMPS="mm/dd/yyyy"

# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder

# Which plugins would you like to load?
# Standard plugins can be found in $ZSH/plugins/
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(git history-sync)

source $ZSH/oh-my-zsh.sh

# User configuration

# export MANPATH="/usr/local/man:$MANPATH"

# You may need to manually set your language environment
# export LANG=en_US.UTF-8

# Preferred editor for local and remote sessions
# if [[ -n $SSH_CONNECTION ]]; then
#   export EDITOR='vim'
# else
#   export EDITOR='mvim'
# fi

# Compilation flags
# export ARCHFLAGS="-arch x86_64"

# Set personal aliases, overriding those provided by oh-my-zsh libs,
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
# For a full list of active aliases, run `alias`.
#
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"
Download .txt
gitextract_g9lsxsyn/

├── .github/
│   └── workflows/
│       └── actions.yml
├── .gitignore
├── LICENSE
├── README.md
├── history-sync.plugin.zsh
└── test/
    ├── Dockerfile
    ├── test.zsh
    └── zshrc
Condensed preview — 8 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (24K chars).
[
  {
    "path": ".github/workflows/actions.yml",
    "chars": 367,
    "preview": "name: history-sync\nenv:\n  ACCESS_KEY: ${{ secrets.ACCESS_KEY }}\non: [push, workflow_dispatch]\njobs:\n  setup_and_test:\n  "
  },
  {
    "path": ".gitignore",
    "chars": 31,
    "preview": "zsh_history_test*\n.*.swp\n*.swp\n"
  },
  {
    "path": "LICENSE",
    "chars": 1129,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2017 James Fraser <wulfgar.pro@gmail.com> (https://www.wulfgar.pro)\n\nPermission is "
  },
  {
    "path": "README.md",
    "chars": 2069,
    "preview": "[![history-sync](https://github.com/wulfgarpro/history-sync/actions/workflows/actions.yml/badge.svg)](https://github.com"
  },
  {
    "path": "history-sync.plugin.zsh",
    "chars": 10647,
    "preview": "# ----------------------------------------------------------------\n# Description\n# -------------------------------------"
  },
  {
    "path": "test/Dockerfile",
    "chars": 798,
    "preview": "FROM ubuntu:22.04\n\n# Install system packages\nRUN apt-get update \\\n  && apt-get install -y --no-install-recommends \\\n    "
  },
  {
    "path": "test/test.zsh",
    "chars": 3071,
    "preview": "#!/usr/bin/env zsh\n\nACCESS_KEY=$1\n\nset -e\ngpg -q --quick-gen-key --yes --batch --passphrase '' $UID\ngit config --global "
  },
  {
    "path": "test/zshrc",
    "chars": 3879,
    "preview": "# If you come from bash you might have to change your $PATH.\n# export PATH=$HOME/bin:/usr/local/bin:$PATH\n\n# Path to you"
  }
]

About this extraction

This page contains the full source code of the wulfgarpro/history-sync GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 8 files (21.5 KB), approximately 6.2k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!