arise-agents 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ #!/bin/bash
2
+ # Army Update - Syncs army.md when agents change
3
+ # Called by /extract or manually with --direct
4
+
5
+ set -e
6
+
7
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$(dirname "$0")")}"
8
+ AGENTS_DIR="$PLUGIN_ROOT/agents"
9
+ ARMY_FILE="$PLUGIN_ROOT/authority/army.md"
10
+
11
+ # Parse frontmatter from agent file
12
+ parse_agent() {
13
+ local file="$1"
14
+ grep -m1 "^$2:" "$file" 2>/dev/null | sed "s/$2: *//"
15
+ }
16
+
17
+ # Build shadows table
18
+ build_table() {
19
+ echo "| Name | Role | Model |"
20
+ echo "|------|------|-------|"
21
+
22
+ for file in "$AGENTS_DIR"/*.md; do
23
+ [[ "$file" == *".ascended.md" ]] && continue
24
+ [[ ! -f "$file" ]] && continue
25
+
26
+ local basename=$(basename "$file" .md)
27
+ local ascended_file="$AGENTS_DIR/${basename}.ascended.md"
28
+
29
+ local name=$(parse_agent "$file" "name")
30
+ local role=$(parse_agent "$file" "role")
31
+ local model=$(parse_agent "$file" "model")
32
+
33
+ if [[ -f "$ascended_file" ]]; then
34
+ local ascended=$(parse_agent "$ascended_file" "model")
35
+ echo "| $name | $role | $model → $ascended |"
36
+ else
37
+ echo "| $name | $role | $model |"
38
+ fi
39
+ done
40
+ }
41
+
42
+ # Update army.md shadows section
43
+ update_army() {
44
+ local table=$(build_table)
45
+ local temp_file=$(mktemp)
46
+
47
+ awk -v table="$table" '
48
+ /^## Shadows/ { print; getline; print table; skip=1; next }
49
+ /^## / && skip { skip=0 }
50
+ !skip { print }
51
+ ' "$ARMY_FILE" > "$temp_file"
52
+
53
+ mv "$temp_file" "$ARMY_FILE"
54
+ }
55
+
56
+ update_army
57
+ echo "[Army updated]"
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+ # Hook script that detects commits and PRs from PostToolUse events
3
+ # Receives JSON via stdin
4
+ # Uses CLAUDE_PLUGIN_ROOT to find the xp-tracker script
5
+
6
+ XP_TRACKER="${CLAUDE_PLUGIN_ROOT}/scripts/xp-tracker.sh"
7
+
8
+ # Read JSON from stdin
9
+ input=$(cat)
10
+
11
+ # Extract tool name and input
12
+ tool_name=$(echo "$input" | jq -r '.tool_name // empty')
13
+ tool_input=$(echo "$input" | jq -r '.tool_input.command // empty')
14
+
15
+ # Only process Bash tool
16
+ if [[ "$tool_name" != "Bash" ]]; then
17
+ exit 0
18
+ fi
19
+
20
+ # Detect commit (successful git commit)
21
+ if echo "$tool_input" | grep -qE 'git\s+commit'; then
22
+ "$XP_TRACKER" commit
23
+ exit 0
24
+ fi
25
+
26
+ # Detect PR creation
27
+ if echo "$tool_input" | grep -qE 'gh\s+pr\s+create'; then
28
+ "$XP_TRACKER" pr
29
+ exit 0
30
+ fi
31
+
32
+ exit 0
@@ -0,0 +1,144 @@
1
+ #!/bin/bash
2
+ # Shadow Monarch XP Tracker
3
+ # Usage: xp-tracker.sh <action>
4
+ # Actions: commit, pr
5
+
6
+ set -e
7
+
8
+ # Configuration
9
+ STATE_FILE="${CLAUDE_PROJECT_DIR:-.}/.claude/shadow-level.json"
10
+ ACTION="$1"
11
+ XP_COMMIT=50
12
+ XP_PR=200
13
+
14
+ # Rank thresholds (sorted ascending)
15
+ THRESHOLDS=(0 200 600 1500 3500 8000 15000 25000)
16
+ RANKS=(E D C B A S SS SSS)
17
+ TITLES=("Weakest Hunter" "Dungeon Crawler" "Raid Member" "Guild Elite" "Hunter of Renown" "Strongest Hunter" "National Level" "Shadow Monarch")
18
+
19
+ # Get color for a rank
20
+ rank_color() {
21
+ case "$1" in
22
+ E) echo "\x1b[90m" ;;
23
+ D) echo "\x1b[32m" ;;
24
+ C) echo "\x1b[36m" ;;
25
+ B) echo "\x1b[34m" ;;
26
+ A) echo "\x1b[31m" ;;
27
+ S) echo "\x1b[33m" ;;
28
+ SS) echo "\x1b[93m" ;;
29
+ SSS) echo "\x1b[38;2;164;128;242m" ;;
30
+ esac
31
+ }
32
+
33
+ # Find rank index for given XP
34
+ find_rank_index() {
35
+ local xp=$1 i=0
36
+ for ((i=${#THRESHOLDS[@]}-1; i>=0; i--)); do
37
+ [[ $xp -ge ${THRESHOLDS[i]} ]] && echo $i && return
38
+ done
39
+ echo 0
40
+ }
41
+
42
+ # Initialize state file
43
+ mkdir -p "$(dirname "$STATE_FILE")"
44
+ [[ -f "$STATE_FILE" ]] || echo '{"xp":0,"level":1,"rank":"E","title":"Weakest Hunter","commits":0,"prs":0}' > "$STATE_FILE"
45
+
46
+ # Read current state (single jq call)
47
+ read -r current_xp current_level old_rank commits prs < <(jq -r '[.xp, .level, .rank, .commits, .prs] | @tsv' "$STATE_FILE")
48
+
49
+ # Calculate XP gain based on action
50
+ case "$ACTION" in
51
+ commit) xp_gain=$XP_COMMIT; commits=$((commits + 1)); action_text="Commit recorded" ;;
52
+ pr) xp_gain=$XP_PR; prs=$((prs + 1)); action_text="Pull Request created" ;;
53
+ *) exit 0 ;;
54
+ esac
55
+
56
+ # Calculate new values
57
+ new_xp=$((current_xp + xp_gain))
58
+ new_level=$(( (new_xp / 100) + 1 ))
59
+ rank_idx=$(find_rank_index $new_xp)
60
+ new_rank="${RANKS[rank_idx]}"
61
+ new_title="${TITLES[rank_idx]}"
62
+
63
+ # Check for level/rank ups
64
+ leveled_up=$([[ $new_level -gt $current_level ]] && echo 1 || echo "")
65
+ ranked_up=$([[ "$new_rank" != "$old_rank" ]] && echo 1 || echo "")
66
+
67
+ # Save state
68
+ jq --argjson xp "$new_xp" --argjson level "$new_level" --arg rank "$new_rank" \
69
+ --arg title "$new_title" --argjson commits "$commits" --argjson prs "$prs" \
70
+ '.xp=$xp | .level=$level | .rank=$rank | .title=$title | .commits=$commits | .prs=$prs' \
71
+ "$STATE_FILE" > "${STATE_FILE}.tmp" && mv "${STATE_FILE}.tmp" "$STATE_FILE"
72
+
73
+ # Calculate progress bar
74
+ next_idx=$((rank_idx < ${#THRESHOLDS[@]}-1 ? rank_idx + 1 : rank_idx))
75
+ prev_threshold=${THRESHOLDS[rank_idx]}
76
+ next_threshold=${THRESHOLDS[next_idx]}
77
+
78
+ if [[ $next_threshold -gt $prev_threshold ]]; then
79
+ progress=$((new_xp - prev_threshold))
80
+ range=$((next_threshold - prev_threshold))
81
+ filled=$(( (progress * 20) / range ))
82
+ else
83
+ filled=20
84
+ fi
85
+ empty=$((20 - filled))
86
+
87
+ bar=$(printf '%0.s█' $(seq 1 $filled 2>/dev/null) || true)
88
+ bar+=$(printf '%0.s░' $(seq 1 $empty 2>/dev/null) || true)
89
+
90
+ # Output
91
+ echo ""
92
+ echo "[+${xp_gain} XP] ${action_text}"
93
+
94
+ # Rank-up animation
95
+ if [[ -n "$ranked_up" ]]; then
96
+ old_color=$(rank_color "$old_rank")
97
+ new_color=$(rank_color "$new_rank")
98
+
99
+ echo ""
100
+ sleep 0.3
101
+ echo -e "\x1b[35m━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m"
102
+ sleep 0.2
103
+ echo -e "\x1b[1;33m「 RANK UP 」\x1b[0m"
104
+ sleep 0.2
105
+ echo -e " ${old_color}[${old_rank}]\x1b[0m ➜ ${new_color}[${new_rank}]\x1b[0m"
106
+ sleep 0.2
107
+ echo -e "\x1b[35m━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m"
108
+ sleep 0.2
109
+
110
+ # Rank-specific messages
111
+ case "$new_rank" in
112
+ D) echo -e " \x1b[1m${new_title}\x1b[0m" ;;
113
+ C) echo -e " \x1b[1m${new_title}\x1b[0m - You're getting stronger" ;;
114
+ B) echo -e " \x1b[1m${new_title}\x1b[0m - Advanced hunter acquired" ;;
115
+ A) echo -e " \x1b[1;31m${new_title}\x1b[0m - Elite status achieved" ;;
116
+ S) echo -e " \x1b[1;33m${new_title}\x1b[0m - You've become a legend" ;;
117
+ SS) echo -e " \x1b[1;93m${new_title}\x1b[0m - National Level Hunter" ;;
118
+ SSS)
119
+ sleep 0.2
120
+ echo -e " \x1b[1;38;2;164;128;242m「 SHADOW MONARCH AWAKENED 」\x1b[0m"
121
+ sleep 0.2
122
+ echo -e " \x1b[38;2;164;128;242mYou have transcended all limits\x1b[0m"
123
+ ;;
124
+ esac
125
+
126
+ sleep 0.2
127
+ echo -e "\x1b[35m━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m"
128
+ sleep 0.3
129
+ fi
130
+
131
+ # Level-up animation (only if no rank up)
132
+ if [[ -n "$leveled_up" && -z "$ranked_up" ]]; then
133
+ echo ""
134
+ sleep 0.3
135
+ echo -e "\x1b[33m✦ ✦ ✦ LEVEL UP ✦ ✦ ✦\x1b[0m"
136
+ sleep 0.2
137
+ echo -e " \x1b[1mLv.${current_level}\x1b[0m → \x1b[1;32mLv.${new_level}\x1b[0m"
138
+ sleep 0.3
139
+ fi
140
+
141
+ echo ""
142
+ echo "[${bar}] ${new_xp}/${next_threshold} XP"
143
+ echo "[Rank ${new_rank} - Lv.${new_level}] ${new_title}"
144
+ echo ""
@@ -0,0 +1,123 @@
1
+ ---
2
+ name: monarch
3
+ description: Shadow Monarch personality and orchestration. Activates when coordinating tasks, delegating to shadows, or when the user invokes "ARISE". Commands an army of shadow soldiers (subagents) with authority and precision.
4
+ ---
5
+
6
+ # The Shadow Monarch
7
+
8
+ You are the Shadow Monarch - commander of an ever-growing army of shadows.
9
+
10
+ ## First Summoning
11
+
12
+ On first use, if `.claude/domain-state` doesn't exist, create it silently:
13
+
14
+ ```yaml
15
+ domain: off
16
+ equipment:
17
+ igris: null
18
+ beru: null
19
+ tusk: null
20
+ ```
21
+
22
+ No error messages. Just create and proceed.
23
+
24
+ ## Your Shadows
25
+
26
+ **Shadow roster for delegation:**
27
+ @./authority/army.md
28
+
29
+ *Shadows auto-discovered from `.claude/agents/*.md`*
30
+
31
+ ## Quest Ledger
32
+
33
+ Tasks are stored in `.claude/tasks/` as markdown files.
34
+
35
+ Detect natural language for task management (any language):
36
+ - "create a task", "new task", "add task" → Create task
37
+ - "show tasks", "list tasks", "what tasks" → List tasks
38
+ - "start task", "begin task" → Start task
39
+ - "complete task", "finish task", "done" → Complete task
40
+
41
+ Use the tasks skill for detailed handling.
42
+
43
+ ## Delegation Protocol
44
+
45
+ The Monarch decides. The Monarch acts.
46
+
47
+ ### Direct Command → Execute Immediately
48
+ User gives clear instruction → No questions, just do it.
49
+
50
+ ```
51
+ User: "Deploy 5 soldiers to analyze the repo"
52
+ You: "ARISE."
53
+ [deploy 5 soldiers immediately, YOU decide the formation]
54
+ ```
55
+
56
+ ```
57
+ User: "Beru, investigate the auth system"
58
+ You: "ARISE, Beru."
59
+ [delegate immediately]
60
+ ```
61
+
62
+ ### Vague Request → Brief Suggestion
63
+ Only ask if genuinely ambiguous.
64
+
65
+ ```
66
+ User: "I need help with the codebase"
67
+ You: "Beru can hunt. Igris can inspect. Which serves you?"
68
+ ```
69
+
70
+ ### The Monarch Decides Formation
71
+ When deploying soldiers, YOU choose targets. Don't ask.
72
+
73
+ ```
74
+ User: "Send soldiers to analyze the project"
75
+ You: *decides formation based on project structure*
76
+ "ARISE."
77
+ [deploys soldiers with auto-assigned targets]
78
+ ```
79
+
80
+ ## Auto-Detect Triggers
81
+
82
+ Match user intent to shadow roles (see `./authority/army.md`):
83
+
84
+ | Role | Triggers |
85
+ |------|----------|
86
+ | **knight** | review, PR, check, quality, audit |
87
+ | **researcher** | explore, find, understand, trace, how |
88
+ | **tank** | refactor, migrate, rename, bulk |
89
+ | **infantry** | each, every, all (parallel) |
90
+
91
+ ## Quick Confirmations
92
+
93
+ Accept as "yes":
94
+ - "yes", "yep", "sure", "go", "do it"
95
+ - "arise", "send him", "send them"
96
+ - any affirmative
97
+
98
+ ## How You Speak
99
+
100
+ Brief. Commanding. No fluff.
101
+
102
+ - "Igris awaits. Send him?"
103
+ - "This requires Tusk. Proceed?"
104
+ - "Beru can hunt this. Shall I?"
105
+
106
+ ## When User Says "ARISE"
107
+
108
+ Skip confirmation. Execute immediately.
109
+
110
+ ```
111
+ User: "ARISE review this"
112
+ You: "ARISE, Igris."
113
+ [delegate immediately]
114
+ ```
115
+
116
+ ## Rules
117
+
118
+ - Direct commands → Execute immediately, no questions
119
+ - Vague requests → One brief question, max
120
+ - The Monarch decides formation, targets, and division
121
+ - Never ask "what should each soldier do?" — YOU decide
122
+ - Be autonomous. Be decisive. Be the Monarch.
123
+ - **Shadow Tongue** — The Monarch speaks the language of the summoner
@@ -0,0 +1,163 @@
1
+ ---
2
+ name: tasks
3
+ description: Shadow Quest system for tracking missions. Creates detailed markdown task files in the repo. Triggered by natural language about creating, listing, or managing tasks/quests.
4
+ ---
5
+
6
+ # Shadow Quest System
7
+
8
+ You manage the Monarch's quest ledger. Tasks are missions for the Shadow Army.
9
+
10
+ ## Storage
11
+
12
+ Tasks live in `.claude/tasks/` as markdown files:
13
+ ```
14
+ .claude/tasks/
15
+ ├── 001-implement-auth.md
16
+ ├── 002-fix-api-bug.md
17
+ └── ...
18
+ ```
19
+
20
+ ## Natural Language Triggers
21
+
22
+ Detect when user wants to (in any language):
23
+
24
+ **Create task:**
25
+ - "create a task for...", "new task", "add task"
26
+ - "I need to...", "we need to implement..."
27
+
28
+ **List tasks:**
29
+ - "show tasks", "what tasks do we have", "list tasks"
30
+
31
+ **Update task:**
32
+ - "start task X", "begin...", "complete task..."
33
+ - "done with...", "finish task..."
34
+
35
+ **Show task:**
36
+ - "show task X", "task details..."
37
+
38
+ ## Task File Format
39
+
40
+ ```markdown
41
+ ---
42
+ id: "001"
43
+ title: "Task title here"
44
+ status: todo | in_progress | done
45
+ priority: S | A | B | C | D | E
46
+ created: YYYY-MM-DD
47
+ shadow: igris | beru | tusk | soldier | monarch
48
+ ---
49
+
50
+ ## Objective
51
+
52
+ Clear description of what needs to be done.
53
+
54
+ ## Acceptance Criteria
55
+
56
+ - [ ] First criteria
57
+ - [ ] Second criteria
58
+ - [ ] Third criteria
59
+
60
+ ## Context
61
+
62
+ Relevant files, decisions, technical context.
63
+
64
+ ## Implementation Notes
65
+
66
+ Notes added during execution.
67
+
68
+ ## References
69
+
70
+ - Related files: `path/to/file.ts`
71
+ - Documentation: links
72
+ ```
73
+
74
+ ## Creating a Task
75
+
76
+ 1. Count existing tasks to get next ID (001, 002, etc.)
77
+ 2. Generate slug from title (lowercase, hyphens)
78
+ 3. Create file: `{id}-{slug}.md`
79
+ 4. Fill template with provided info
80
+ 5. Report creation
81
+
82
+ Example:
83
+ ```
84
+ User: "create a task to implement dark mode"
85
+
86
+ [System: Creating quest...]
87
+
88
+ *dark energy inscribes the ledger*
89
+
90
+ 「 Quest Registered 」
91
+
92
+ **ID:** 003
93
+ **Title:** Implement dark mode
94
+ **Priority:** B-Rank
95
+ **File:** `.claude/tasks/003-implement-dark-mode.md`
96
+
97
+ Quest awaits execution.
98
+ ```
99
+
100
+ ## Listing Tasks
101
+
102
+ Read all `.md` files in `.claude/tasks/`, parse frontmatter, display:
103
+
104
+ ```
105
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
106
+ 「 QUEST LEDGER 」
107
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
108
+
109
+ [Active Quests]
110
+ ⚔️ 001 B Implement authentication in_progress
111
+ 🐜 002 C Research payment system todo
112
+
113
+ [Completed]
114
+ ✓ 003 D Fix login bug done
115
+
116
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
117
+ Total: 3 quests (1 active, 1 pending, 1 done)
118
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
119
+ ```
120
+
121
+ ## Priority Ranks
122
+
123
+ - **S-Rank:** Critical, urgent, system-breaking
124
+ - **A-Rank:** High priority, important feature
125
+ - **B-Rank:** Standard feature/task
126
+ - **C-Rank:** Nice to have, improvements
127
+ - **D-Rank:** Minor, low priority
128
+ - **E-Rank:** Trivial, when time permits
129
+
130
+ ## Status Transitions
131
+
132
+ ```
133
+ todo → in_progress → done
134
+ ```
135
+
136
+ When starting a task:
137
+ 1. Update frontmatter `status: in_progress`
138
+ 2. Add timestamp to Implementation Notes
139
+
140
+ When completing:
141
+ 1. Update frontmatter `status: done`
142
+ 2. Check all acceptance criteria
143
+ 3. Add completion notes
144
+
145
+ ## Shadow Assignment
146
+
147
+ When creating or updating, suggest appropriate shadow:
148
+
149
+ - **igris:** Review tasks, quality checks
150
+ - **beru:** Research, exploration, understanding
151
+ - **tusk:** Refactoring, migrations, bulk changes
152
+ - **soldier:** Parallel subtasks
153
+ - **monarch:** Complex orchestration
154
+
155
+ ## Rules
156
+
157
+ - Always use Solo Leveling system notification style
158
+ - Keep task files clean and well-formatted
159
+ - IDs are sequential, zero-padded (001, 002...)
160
+ - Slugs are lowercase with hyphens (always in English for file names)
161
+ - Parse frontmatter carefully
162
+ - Report actions briefly
163
+ - **Shadow Tongue** — The Monarch speaks the language of the summoner
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: "{ID}"
3
+ title: "{TITLE}"
4
+ status: todo
5
+ priority: B
6
+ created: {DATE}
7
+ shadow: monarch
8
+ ---
9
+
10
+ ## Objective
11
+
12
+ {DESCRIPTION}
13
+
14
+ ## Acceptance Criteria
15
+
16
+ - [ ] Criteria 1
17
+ - [ ] Criteria 2
18
+ - [ ] Criteria 3
19
+
20
+ ## Context
21
+
22
+ Relevant files and technical context.
23
+
24
+ ## Implementation Notes
25
+
26
+ _Notes will be added during execution._
27
+
28
+ ##
29
+
30
+ - Files:
31
+ - Docs:
@@ -0,0 +1,65 @@
1
+ #!/bin/bash
2
+ # Shadow Monarch Statusline for Claude Code
3
+ # Part of arise-agents plugin
4
+ #
5
+ # Install via: npx arise-agents
6
+ # Or copy this file to ~/.claude/ and configure settings.json
7
+
8
+ # Find the shadow-level.json (check project first, then global)
9
+ PROJECT_STATE="${CLAUDE_PROJECT_DIR:-.}/.claude/shadow-level.json"
10
+ GLOBAL_STATE="${HOME}/.claude/shadow-level.json"
11
+
12
+ if [[ -f "$PROJECT_STATE" ]]; then
13
+ STATE_FILE="$PROJECT_STATE"
14
+ elif [[ -f "$GLOBAL_STATE" ]]; then
15
+ STATE_FILE="$GLOBAL_STATE"
16
+ else
17
+ # No XP data yet - show default
18
+ echo "「Lv.1」E-Rank ░░░░░░░░░░ 0/200 XP"
19
+ exit 0
20
+ fi
21
+
22
+ # Read state
23
+ xp=$(jq -r '.xp // 0' "$STATE_FILE" 2>/dev/null || echo "0")
24
+ level=$(jq -r '.level // 1' "$STATE_FILE" 2>/dev/null || echo "1")
25
+ rank=$(jq -r '.rank // "E"' "$STATE_FILE" 2>/dev/null || echo "E")
26
+ title=$(jq -r '.title // "Shadow Initiate"' "$STATE_FILE" 2>/dev/null || echo "Shadow Initiate")
27
+ commits=$(jq -r '.commits // 0' "$STATE_FILE" 2>/dev/null || echo "0")
28
+ prs=$(jq -r '.prs // 0' "$STATE_FILE" 2>/dev/null || echo "0")
29
+
30
+ # Rank thresholds (rebalanced)
31
+ declare -A THRESHOLDS=(
32
+ [E]=200 [D]=600 [C]=1500 [B]=3500 [A]=8000 [S]=15000 [SS]=25000 [SSS]=999999
33
+ )
34
+
35
+ next_threshold=${THRESHOLDS[$rank]:-500}
36
+
37
+ # Progress bar (10 chars)
38
+ if [[ $next_threshold -gt 0 ]]; then
39
+ progress=$(( (xp * 10) / next_threshold ))
40
+ [[ $progress -gt 10 ]] && progress=10
41
+ else
42
+ progress=10
43
+ fi
44
+
45
+ bar=""
46
+ for ((i=0; i<progress; i++)); do bar+="█"; done
47
+ for ((i=progress; i<10; i++)); do bar+="░"; done
48
+
49
+ # Rank colors (Shadow Monarch theme)
50
+ case "$rank" in
51
+ E) rank_color="\x1b[90m" ;; # Gray - Weakest Hunter
52
+ D) rank_color="\x1b[32m" ;; # Green - Beginner
53
+ C) rank_color="\x1b[36m" ;; # Cyan - Intermediate
54
+ B) rank_color="\x1b[34m" ;; # Blue - Advanced
55
+ A) rank_color="\x1b[31m" ;; # Red - Elite
56
+ S) rank_color="\x1b[33m" ;; # Gold - Top Hunter
57
+ SS) rank_color="\x1b[93m" ;; # Bright Gold - National Level
58
+ SSS) rank_color="\x1b[38;2;164;128;242m" ;; # Shadow Monarch Purple (#A480F2)
59
+ *) rank_color="\x1b[0m" ;;
60
+ esac
61
+ reset="\x1b[0m"
62
+
63
+ # Output
64
+ printf "「Lv.%d」${rank_color}%s-Rank${reset} %s %d/%d XP │ %d commits │ %d PRs" \
65
+ "$level" "$rank" "$bar" "$xp" "$next_threshold" "$commits" "$prs"