Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions packs/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,68 @@
# shared. Override at install time with: LOKI_SKILLS_REPO_URL=...
export LOKI_SKILLS_REPO_URL="${LOKI_SKILLS_REPO_URL:-https://github.com/inceptionstack/loki-skills.git}"

# ── ensure_skills_clone ───────────────────────────────────────────────────────
# Clone loki-skills library to target directory (best-effort, non-fatal).
# Handles update path, partial directory recovery, missing git gracefully.
#
# Usage: ensure_skills_clone <target_dir> [<repo_url>] [<branch>] [<mode>]
# target_dir: where to clone (e.g. ~/.openclaw/workspace/skills)
# repo_url: git repo (default: $LOKI_SKILLS_REPO_URL)
# branch: git branch (default: main)
# mode: 'warn' (default) or 'fail' — controls error handling
#
# Returns: 0 on success, non-zero on failure (caller decides via || true)
ensure_skills_clone() {
local target_dir="${1:?target_dir required}"
local repo_url="${2:-${LOKI_SKILLS_REPO_URL}}"
local branch="${3:-main}"
local mode="${4:-warn}"
local rc=0

# Check git available
if ! command -v git &>/dev/null; then
local msg="git not found; skills clone skipped"
[[ "$mode" == "fail" ]] && { log "$msg (FATAL)"; return 1; } || log "$msg (warn)"
return 0
fi

# Existing repo: try update
if [[ -d "$target_dir" ]] && [[ -d "$target_dir/.git" ]]; then
local origin_url="$(cd "$target_dir" && git config --get remote.origin.url 2>/dev/null)"
if [[ "$origin_url" == "$repo_url" ]]; then
# Same origin, safe to update
if (cd "$target_dir" && git fetch origin "$branch" && git checkout "$branch") &>/dev/null; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Advance branch to fetched tip before reporting update

git fetch origin "$branch" && git checkout "$branch" does not move an existing local branch to the newly fetched origin/$branch, so this path can return success while leaving an outdated skills checkout. In practice, if the local branch is behind, the function logs "updated" and exits 0 even though no new commits were applied; use a fast-forward/pull/reset step after fetch to ensure the working tree matches the remote tip.

Useful? React with 👍 / 👎.

log "Skills repo updated at $target_dir"
return 0
else
log "Skills repo update failed; moving aside and re-cloning"
mv "$target_dir" "${target_dir}.bak.$RANDOM" || true
fi
else
# Different origin: move aside and re-clone
log "Skills origin mismatch; moving aside and re-cloning"
mv "$target_dir" "${target_dir}.bak.$RANDOM" || true
fi
fi

# Partial dir (no .git): remove and re-clone
if [[ -d "$target_dir" ]] && [[ ! -d "$target_dir/.git" ]]; then
log "Incomplete skills dir; removing and re-cloning"
rm -rf "$target_dir" || true
fi

# Fresh clone (shallow)
if ! git clone --depth 1 --branch "$branch" "$repo_url" "$target_dir" &>/dev/null; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Create clone parent directory before invoking git clone

The fresh-clone path calls git clone directly into target_dir but never creates $(dirname "$target_dir"). On first-run installs where that parent path does not exist (for example ~/.local/share/lowkey/skills), clone fails immediately and skills are not installed, even though the installers continue via || true.

Useful? React with 👍 / 👎.

local msg="Skills clone failed (repo: $repo_url, branch: $branch)"
[[ "$mode" == "fail" ]] && { log "$msg (FATAL)"; return 1; } || log "$msg (warn, continuing)"
rc=1
else
log "Skills cloned to $target_dir"
fi

return $rc
}

# Colors
_CLR_GREEN='\033[0;32m'
_CLR_CYAN='\033[0;36m'
Expand Down