feat: role-based skill installation via role-skills.json

learn.sh now installs skills in three layers:
1. mandatory (.mandatory) - all agents
2. role/position (role-skills.json) - based on ego-mgr fields
3. agent-specific (.skill-list) - optional per-agent extras

Deduplicated across layers. ego-mgr unavailable = graceful skip.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
zhi
2026-04-18 17:05:40 +00:00
parent 840707b604
commit 4cca810c15
2 changed files with 104 additions and 24 deletions

View File

@@ -6,44 +6,85 @@ if [[ -z "${AGENT_WORKSPACE:-}" ]]; then
exit 1
fi
SKILL_LIST="${AGENT_WORKSPACE}/.skill-list"
TARGET_DIR="${AGENT_WORKSPACE}/skills"
CLAW_DIR="$(cd "$(dirname "$0")" && pwd)"
MANDATORY_FILE="${CLAW_DIR}/.mandatory"
ROLE_SKILLS_FILE="${CLAW_DIR}/role-skills.json"
SKILL_LIST="${AGENT_WORKSPACE}/.skill-list"
mkdir -p "$TARGET_DIR"
# First: install mandatory skills from .mandatory (one per line)
# Track installed skills to avoid duplicates
declare -A INSTALLED
install_skill() {
local skill_name="$1"
local source="$2"
[[ -z "$skill_name" || "$skill_name" == \#* ]] && return
if [[ -n "${INSTALLED[$skill_name]:-}" ]]; then
return
fi
local skill_dir="${CLAW_DIR}/${skill_name}"
if [[ -d "$skill_dir" ]]; then
echo "Installing ($source): $skill_name"
cp -r "$skill_dir" "${TARGET_DIR}/"
INSTALLED[$skill_name]=1
else
echo "Skipping (not found): $skill_name"
fi
}
# 1. Install mandatory skills
if [[ -f "$MANDATORY_FILE" ]]; then
while IFS= read -r skill_name || [[ -n "$skill_name" ]]; do
[[ -z "$skill_name" || "$skill_name" == \#* ]] && continue
skill_dir="${CLAW_DIR}/${skill_name}"
if [[ -d "$skill_dir" ]]; then
echo "Installing (mandatory): $skill_name"
cp -r "$skill_dir" "${TARGET_DIR}/"
else
echo "Skipping (not found): $skill_name"
fi
install_skill "$skill_name" "mandatory"
done < "$MANDATORY_FILE"
fi
# Then: install skills from .skill-list
# 2. Install role-based skills from role-skills.json
if [[ -f "$ROLE_SKILLS_FILE" ]]; then
ROLE=$(ego-mgr get role 2>/dev/null || true)
POSITION=$(ego-mgr get position 2>/dev/null || true)
if [[ -n "$ROLE" ]]; then
ROLE_SKILLS=$(python3 -c "
import json, sys
with open('$ROLE_SKILLS_FILE') as f:
data = json.load(f)
skills = data.get('roles', {}).get('$ROLE', [])
print('\n'.join(skills))
" 2>/dev/null || true)
while IFS= read -r skill_name; do
[[ -n "$skill_name" ]] && install_skill "$skill_name" "role:$ROLE"
done <<< "$ROLE_SKILLS"
fi
if [[ -n "$POSITION" ]]; then
POS_SKILLS=$(python3 -c "
import json, sys
with open('$ROLE_SKILLS_FILE') as f:
data = json.load(f)
skills = data.get('positions', {}).get('$POSITION', [])
print('\n'.join(skills))
" 2>/dev/null || true)
while IFS= read -r skill_name; do
[[ -n "$skill_name" ]] && install_skill "$skill_name" "position:$POSITION"
done <<< "$POS_SKILLS"
fi
else
echo "Warning: role-skills.json not found, skipping role-based skills"
fi
# 3. Install agent-specific skills from .skill-list (if exists)
if [[ -f "$SKILL_LIST" ]]; then
while IFS= read -r skill_name || [[ -n "$skill_name" ]]; do
[[ -z "$skill_name" || "$skill_name" == \#* ]] && continue
skill_dir="${CLAW_DIR}/${skill_name}"
if [[ -d "$skill_dir" ]]; then
echo "Installing: $skill_name"
cp -r "$skill_dir" "${TARGET_DIR}/"
else
echo "Skipping (not found): $skill_name"
fi
install_skill "$skill_name" "skill-list"
done < "$SKILL_LIST"
else
echo "Error: .skill-list not found at $SKILL_LIST"
exit 1
fi
echo "Done."