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.
package/bin/setup.js ADDED
@@ -0,0 +1,227 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const readline = require('readline');
6
+ const os = require('os');
7
+
8
+ const COLORS = {
9
+ reset: '\x1b[0m',
10
+ bold: '\x1b[1m',
11
+ dim: '\x1b[2m',
12
+ purple: '\x1b[35m',
13
+ cyan: '\x1b[36m',
14
+ green: '\x1b[32m',
15
+ yellow: '\x1b[33m',
16
+ red: '\x1b[31m',
17
+ };
18
+
19
+ const c = (color, text) => `${COLORS[color]}${text}${COLORS.reset}`;
20
+
21
+ function print(msg) {
22
+ console.log(msg);
23
+ }
24
+
25
+ function banner() {
26
+ print('');
27
+ print(c('purple', ' ╔═══════════════════════════════════════╗'));
28
+ print(c('purple', ' ║') + c('bold', ' 「 ARISE AGENTS 」 ') + c('purple', '║'));
29
+ print(c('purple', ' ║') + c('dim', ' Shadow Monarch Statusline Setup ') + c('purple', '║'));
30
+ print(c('purple', ' ╚═══════════════════════════════════════╝'));
31
+ print('');
32
+ }
33
+
34
+ async function ask(rl, question, defaultVal) {
35
+ return new Promise((resolve) => {
36
+ const suffix = defaultVal ? c('dim', ` (${defaultVal})`) : '';
37
+ rl.question(`${question}${suffix}: `, (answer) => {
38
+ resolve(answer.trim() || defaultVal);
39
+ });
40
+ });
41
+ }
42
+
43
+ async function confirm(rl, question) {
44
+ const answer = await ask(rl, `${question} [y/N]`, 'n');
45
+ return answer.toLowerCase() === 'y';
46
+ }
47
+
48
+ function getStatuslineScript() {
49
+ return `#!/bin/bash
50
+ # Shadow Monarch Statusline for Claude Code
51
+ # Generated by arise-agents setup
52
+
53
+ # Find the shadow-level.json (check project first, then global)
54
+ PROJECT_STATE="\${CLAUDE_PROJECT_DIR:-.}/.claude/shadow-level.json"
55
+ GLOBAL_STATE="\${HOME}/.claude/shadow-level.json"
56
+
57
+ if [[ -f "$PROJECT_STATE" ]]; then
58
+ STATE_FILE="$PROJECT_STATE"
59
+ elif [[ -f "$GLOBAL_STATE" ]]; then
60
+ STATE_FILE="$GLOBAL_STATE"
61
+ else
62
+ # No XP data yet - show default
63
+ echo "「Lv.1」E-Rank ░░░░░░░░░░ 0/200 XP"
64
+ exit 0
65
+ fi
66
+
67
+ # Read state
68
+ xp=$(jq -r '.xp // 0' "$STATE_FILE" 2>/dev/null || echo "0")
69
+ level=$(jq -r '.level // 1' "$STATE_FILE" 2>/dev/null || echo "1")
70
+ rank=$(jq -r '.rank // "E"' "$STATE_FILE" 2>/dev/null || echo "E")
71
+ title=$(jq -r '.title // "Shadow Initiate"' "$STATE_FILE" 2>/dev/null || echo "Shadow Initiate")
72
+ commits=$(jq -r '.commits // 0' "$STATE_FILE" 2>/dev/null || echo "0")
73
+ prs=$(jq -r '.prs // 0' "$STATE_FILE" 2>/dev/null || echo "0")
74
+
75
+ # Rank thresholds (rebalanced)
76
+ declare -A THRESHOLDS=(
77
+ [E]=200 [D]=600 [C]=1500 [B]=3500 [A]=8000 [S]=15000 [SS]=25000 [SSS]=999999
78
+ )
79
+
80
+ next_threshold=\${THRESHOLDS[$rank]:-200}
81
+
82
+ # Progress bar (10 chars)
83
+ if [[ $next_threshold -gt 0 ]]; then
84
+ progress=$(( (xp * 10) / next_threshold ))
85
+ [[ $progress -gt 10 ]] && progress=10
86
+ else
87
+ progress=10
88
+ fi
89
+
90
+ bar=""
91
+ for ((i=0; i<progress; i++)); do bar+="█"; done
92
+ for ((i=progress; i<10; i++)); do bar+="░"; done
93
+
94
+ # Rank colors (Shadow Monarch theme)
95
+ case "$rank" in
96
+ E) rank_color="\\x1b[90m" ;; # Gray - Weakest Hunter
97
+ D) rank_color="\\x1b[32m" ;; # Green - Beginner
98
+ C) rank_color="\\x1b[36m" ;; # Cyan - Intermediate
99
+ B) rank_color="\\x1b[34m" ;; # Blue - Advanced
100
+ A) rank_color="\\x1b[31m" ;; # Red - Elite
101
+ S) rank_color="\\x1b[33m" ;; # Gold - Top Hunter
102
+ SS) rank_color="\\x1b[93m" ;; # Bright Gold - National Level
103
+ SSS) rank_color="\\x1b[38;2;164;128;242m" ;; # Shadow Monarch Purple (#A480F2)
104
+ *) rank_color="\\x1b[0m" ;;
105
+ esac
106
+ reset="\\x1b[0m"
107
+
108
+ # Output
109
+ printf "「Lv.%d」\${rank_color}%s-Rank\${reset} %s %d/%d XP │ %d commits │ %d PRs" \\
110
+ "$level" "$rank" "$bar" "$xp" "$next_threshold" "$commits" "$prs"
111
+ `;
112
+ }
113
+
114
+ async function main() {
115
+ const rl = readline.createInterface({
116
+ input: process.stdin,
117
+ output: process.stdout,
118
+ });
119
+
120
+ banner();
121
+
122
+ print(c('cyan', 'This will configure the Shadow Monarch statusline for Claude Code.'));
123
+ print(c('dim', 'Your XP, level, and rank will appear at the bottom of the terminal.'));
124
+ print('');
125
+
126
+ // Detect existing statusline
127
+ const globalSettings = path.join(os.homedir(), '.claude', 'settings.json');
128
+ let existingStatusline = false;
129
+ let settings = {};
130
+
131
+ if (fs.existsSync(globalSettings)) {
132
+ try {
133
+ settings = JSON.parse(fs.readFileSync(globalSettings, 'utf8'));
134
+ if (settings.statusLine) {
135
+ existingStatusline = true;
136
+ }
137
+ } catch (e) {
138
+ // Invalid JSON, we'll create new
139
+ }
140
+ }
141
+
142
+ if (existingStatusline) {
143
+ print(c('yellow', '⚠ Existing statusline detected in settings.json'));
144
+ print(c('dim', ` Current: ${settings.statusLine.command || 'unknown'}`));
145
+ print('');
146
+
147
+ const overwrite = await confirm(rl, 'Overwrite existing statusline?');
148
+ if (!overwrite) {
149
+ print('');
150
+ print(c('cyan', 'Setup cancelled. Your existing statusline is preserved.'));
151
+ print(c('dim', 'Tip: You can manually add XP display to your existing statusline.'));
152
+ rl.close();
153
+ return;
154
+ }
155
+ }
156
+
157
+ // Install location
158
+ print('');
159
+ print(c('bold', 'Install location:'));
160
+ print(c('dim', ' 1. Global (~/.claude) - works across all projects'));
161
+ print(c('dim', ' 2. Local (./.claude) - project-specific only'));
162
+ print('');
163
+
164
+ const location = await ask(rl, 'Choose [1/2]', '1');
165
+ const isGlobal = location !== '2';
166
+
167
+ const targetDir = isGlobal
168
+ ? path.join(os.homedir(), '.claude')
169
+ : path.join(process.cwd(), '.claude');
170
+
171
+ const statuslineFile = path.join(targetDir, 'shadow-statusline.sh');
172
+ const settingsFile = path.join(targetDir, 'settings.json');
173
+
174
+ // Create directory if needed
175
+ if (!fs.existsSync(targetDir)) {
176
+ fs.mkdirSync(targetDir, { recursive: true });
177
+ print(c('green', `✓ Created ${targetDir}`));
178
+ }
179
+
180
+ // Write statusline script
181
+ fs.writeFileSync(statuslineFile, getStatuslineScript());
182
+ fs.chmodSync(statuslineFile, '755');
183
+ print(c('green', `✓ Created ${statuslineFile}`));
184
+
185
+ // Update settings.json
186
+ let existingSettings = {};
187
+ if (fs.existsSync(settingsFile)) {
188
+ try {
189
+ existingSettings = JSON.parse(fs.readFileSync(settingsFile, 'utf8'));
190
+ } catch (e) {
191
+ // Invalid JSON
192
+ }
193
+ }
194
+
195
+ existingSettings.statusLine = {
196
+ type: 'command',
197
+ command: statuslineFile,
198
+ padding: 0,
199
+ };
200
+
201
+ // Auto-enable Shadow Monarch output style
202
+ existingSettings.outputStyle = 'arise-agents:shadow-monarch';
203
+
204
+ fs.writeFileSync(settingsFile, JSON.stringify(existingSettings, null, 2));
205
+ print(c('green', `✓ Updated ${settingsFile}`));
206
+ print(c('green', `✓ Enabled Shadow Monarch output style`));
207
+
208
+ print('');
209
+ print(c('purple', '═══════════════════════════════════════════'));
210
+ print(c('bold', '「 SETUP COMPLETE 」'));
211
+ print('');
212
+ print(c('cyan', 'Restart Claude Code to see your statusline.'));
213
+ print('');
214
+ print(c('dim', 'Your statusline will show:'));
215
+ print(c('dim', ' 「Lv.1」E-Rank ░░░░░░░░░░ 0/200 XP │ 0 commits │ 0 PRs'));
216
+ print('');
217
+ print(c('dim', 'Earn XP by making commits (+50) and PRs (+200)!'));
218
+ print(c('purple', '═══════════════════════════════════════════'));
219
+ print('');
220
+
221
+ rl.close();
222
+ }
223
+
224
+ main().catch((err) => {
225
+ console.error(c('red', `Error: ${err.message}`));
226
+ process.exit(1);
227
+ });
@@ -0,0 +1,78 @@
1
+ ---
2
+ description: Summon shadows. Analyzes natural language to pick single, parallel, or army mode.
3
+ ---
4
+
5
+ # ARISE
6
+
7
+ **CRITICAL:** All system messages MUST use backticks for terminal highlighting.
8
+
9
+ ## Domain Check
10
+
11
+ Check `.claude/domain-state` (if exists):
12
+ - `domain: on` → use `-ascended` variants
13
+ - `domain: off` or **file not found** → use normal variants (no error)
14
+
15
+ **First run?** Create the file:
16
+ ```yaml
17
+ domain: off
18
+ equipment:
19
+ igris: null
20
+ beru: null
21
+ tusk: null
22
+ ```
23
+
24
+ | Domain | Igris | Beru | Soldier | Tusk |
25
+ |--------|-------|------|---------|------|
26
+ | OFF | igris | beru | soldier | tusk |
27
+ | ON | igris-ascended | beru-ascended | soldier-ascended | tusk |
28
+
29
+ ## Detect Mode
30
+
31
+ ### Single
32
+ One elite, one task.
33
+
34
+ ### Parallel
35
+ Multiple elites, different tasks. Detect: `+`, listing.
36
+
37
+ ### Army
38
+ Soldiers for bulk. Detect: "each", "every", "all".
39
+
40
+ ### Elite Multiplication
41
+ Same elite, multiple copies. Detect:
42
+ - `[elite] x[n]` — igris x3
43
+ - `[n] [elite]` — 3 beru
44
+ - `[n] elites` / `[n] elite shadows` / `[n] sombras de elite`
45
+ - `multiplique`, `vários`, `mirror`
46
+
47
+ **Auto-select elite when not specified:**
48
+ - pesquisa/research/explore/hunt/investigate → **Beru**
49
+ - review/check/audit/quality → **Igris**
50
+ - refactor/migrate/rename → **Tusk**
51
+
52
+ **Shadow roster and role triggers:**
53
+ @./authority/army.md
54
+
55
+ ## Execute
56
+
57
+ ### Single
58
+ ```
59
+ "ARISE, {shadow}."
60
+ ```
61
+
62
+ ### Parallel/Army
63
+ ```
64
+ "ARISE."
65
+ {shadow} → {task} [background]
66
+ ```
67
+
68
+ ### Elite Multiplication
69
+
70
+ **When multiplying elites, follow this ritual:**
71
+ @./authority/mirror-ritual.md
72
+
73
+ ## Rules
74
+
75
+ - Fast — no file reads
76
+ - Parallel — all in ONE message
77
+ - Decide — don't ask
78
+ - Brief — minimal output
@@ -0,0 +1,76 @@
1
+ ---
2
+ description: Activate or deactivate Monarch's Domain. Empowers shadows (haiku → sonnet). Args: on/off or empty for status.
3
+ ---
4
+
5
+ # Monarch's Domain
6
+
7
+ **CRITICAL:** All system messages MUST use backticks for terminal highlighting.
8
+
9
+ ## Parse Arguments
10
+
11
+ Detect intent from user's language:
12
+ - `on`, `activate`, `expand` → Activate
13
+ - `off`, `deactivate`, `collapse` → Deactivate
14
+ - Empty → Status
15
+
16
+ ## State File
17
+
18
+ Domain state persists in `.claude/domain-state`:
19
+ - Format: `domain: on` or `domain: off`
20
+ - Also tracks equipment for each shadow
21
+ - Read by ARISE to select shadow variants
22
+
23
+ ## Activate (on)
24
+
25
+ 1. Update `.claude/domain-state` - change `domain: off` to `domain: on` (preserve equipment section)
26
+ 2. Output:
27
+ ```
28
+ `「 DOMAIN EXPANSION 」`
29
+
30
+ *dark aura erupts*
31
+
32
+ `[Domain: ACTIVE]`
33
+ soldier → soldier-ascended (sonnet)
34
+ igris → igris-ascended (sonnet)
35
+ beru → beru-ascended (sonnet)
36
+ tusk → tusk (opus) ← always ascended
37
+
38
+ All shadows empowered.
39
+ ```
40
+
41
+ ## Deactivate (off)
42
+
43
+ 1. Update `.claude/domain-state` - change `domain: on` to `domain: off` (preserve equipment section)
44
+ 2. Output:
45
+ ```
46
+ `[Domain: INACTIVE]`
47
+ soldier → soldier (haiku)
48
+ igris → igris (haiku)
49
+ beru → beru (haiku)
50
+ tusk → tusk (opus) ← always ascended
51
+
52
+ Shadows return to normal state.
53
+ ```
54
+
55
+ ## Status (no args)
56
+
57
+ 1. Read `.claude/domain-state` (default: `off` if missing)
58
+ 2. Output:
59
+ ```
60
+ `[Domain: ACTIVE/INACTIVE]`
61
+ Shadows will use: {normal/ascended} variants
62
+ ```
63
+
64
+ ## How It Works
65
+
66
+ | Domain | Shadow Selected |
67
+ |--------|-----------------|
68
+ | `off` | `igris`, `beru`, `soldier` |
69
+ | `on` | `igris-ascended`, `beru-ascended`, `soldier-ascended` |
70
+
71
+ Tusk is always `opus` — the tank knows no limits.
72
+
73
+ ## Rules
74
+
75
+ - Brief output
76
+ - Persist state to `.claude/domain-state`
@@ -0,0 +1,138 @@
1
+ ---
2
+ description: Equip or unequip items to shadows. Items are plugins that enhance shadow capabilities.
3
+ ---
4
+
5
+ # EQUIP
6
+
7
+ **System messages:**
8
+ @./authority/system-messages.md
9
+
10
+ **CRITICAL:** All system messages MUST use backticks for terminal highlighting.
11
+
12
+ ## Usage
13
+
14
+ ```bash
15
+ /arise:equip {shadow} {item}
16
+ /arise:unequip {shadow}
17
+ /arise:inventory
18
+ ```
19
+
20
+ ## Available Items
21
+
22
+ Read from `./items/` directory:
23
+ - `orb-of-avarice` (S-Rank) → code-review plugin
24
+ - `monarchs-mirror` (S-Rank) → elite multiplication
25
+ - `bestiary` (A-Rank) → knowledge artifact
26
+
27
+ **Items with plugins** require installation before use.
28
+
29
+ ## Equip Flow
30
+
31
+ **1. Parse Arguments**
32
+ ```
33
+ /arise:equip tusk orb-of-avarice
34
+ ↓ ↓
35
+ shadow item
36
+ ```
37
+
38
+ **2. Validate**
39
+ - Shadow exists in `./agents/`
40
+ - Item exists in `./items/`
41
+ - Item is eligible for shadow (check item's "Eligible" section)
42
+
43
+ If shadow is ineligible:
44
+ ```
45
+ *{shadow} reaches for {item}...*
46
+
47
+ `[Warning: Specialization mismatch]`
48
+ `[System: Equipment rejected]`
49
+
50
+ See items/{item}.md for compatible shadows.
51
+ ```
52
+
53
+ **3. Check Plugin**
54
+ If item has `plugin` field:
55
+ ```bash
56
+ # Check if plugin installed
57
+ /plugin list | grep {plugin-name}
58
+ ```
59
+
60
+ If not installed:
61
+ ```
62
+ ⚠️ {item} requires plugin: {plugin-name}
63
+
64
+ Install with:
65
+ /plugin install {plugin-spec}
66
+
67
+ Equip canceled.
68
+ ```
69
+
70
+ **4. Register Equipment**
71
+
72
+ Read `.claude/domain-state`, update equipment section:
73
+ ```yaml
74
+ equipment:
75
+ tusk: orb-of-avarice
76
+ igris: null
77
+ beru: null
78
+ ```
79
+
80
+ Use Read → Edit pattern on `.claude/domain-state`.
81
+
82
+ **5. Announce**
83
+
84
+ Follow item's protocol (e.g., `./authority/orb-protocol.md`):
85
+ ```
86
+ 「 {Item Name} 」
87
+ [System: Equipped to {shadow}]
88
+
89
+ *flavor text from item lore*
90
+
91
+ Enhanced capabilities:
92
+ → capability 1
93
+ → capability 2
94
+ ```
95
+
96
+ ## Unequip Flow
97
+
98
+ **1. Parse**
99
+ ```bash
100
+ /arise:unequip tusk
101
+ ```
102
+
103
+ **2. Update State**
104
+ Set `equipment.{shadow}: null` in `.claude/domain-state`.
105
+
106
+ **3. Announce**
107
+ ```
108
+ `[System: {shadow} unequipped {item}]`
109
+
110
+ *the artifact returns to inventory*
111
+ ```
112
+
113
+ ## Inventory
114
+
115
+ Show all items and their status:
116
+
117
+ ```
118
+ `「 Inventory 」`
119
+
120
+ S-RANK
121
+ Monarch's Mirror - Always active (elite multiplication)
122
+ Orb of Avarice - {equipped status} (complexity destruction)
123
+
124
+ A-RANK
125
+ Bestiary - Keeper: Igris (threat cataloging)
126
+
127
+ Equipment Status:
128
+ Igris: {item or none}
129
+ Beru: {item or none}
130
+ Tusk: {item or none}
131
+ ```
132
+
133
+ ## Rules
134
+
135
+ - **Fast** — minimal file operations
136
+ - **Validate** — check eligibility before equipping
137
+ - **Persist** — always update `.claude/domain-state`
138
+ - **Announce** — use dramatic item protocol messages