cc2190-buddy 1.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # cc2190-buddy
2
+
3
+ 快速搜索 legendary + shiny 宠物,支持自定义物种、眼睛、帽子选项。
4
+
5
+ ## 致谢
6
+
7
+ 本项目使用了 [cc-buddy](https://www.npmjs.com/package/cc-buddy) 的部分代码,在其基础上进行了修改和简化。
8
+
9
+ ## 安装使用
10
+
11
+ ```bash
12
+ npx cc2190-buddy
13
+ ```
14
+
15
+ ## 功能
16
+
17
+ - 🎯 自动搜索 **LEGENDARY + SHINY** 宠物
18
+ - 🦆 可选物种(18种)
19
+ - 👀 可选眼睛样式(6种)
20
+ - 🎩 可选帽子(7种)
21
+ - ✏️ 自定义名字和性格
22
+
23
+ ## 运行流程
24
+
25
+ 1. 选择物种(可选)
26
+ 2. 选择眼睛(可选)
27
+ 3. 选择帽子(可选)
28
+ 4. 输入名字(可选)
29
+ 5. 输入性格(可选)
30
+ 6. 开始搜索
31
+ 7. 自动写入配置
32
+
33
+ 搜索完成后,重启 Claude Code 并运行 `/buddy` 查看结果。
34
+
35
+ ## 要求
36
+
37
+ - Node.js >= 16.0.0
38
+ - Claude Code >= 2.1.89
39
+
40
+ ## License
41
+
42
+ MIT
package/fast_buddy.mjs ADDED
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+ // 快速搜索 legendary + shiny 宠物,支持自定义选项
3
+ import { randomBytes } from 'node:crypto'
4
+ import { readFileSync, writeFileSync, existsSync, copyFileSync } from 'node:fs'
5
+ import { join } from 'node:path'
6
+ import { homedir } from 'node:os'
7
+ import { createInterface } from 'node:readline'
8
+
9
+ const CONFIG_PATH = join(homedir(), '.claude.json')
10
+ const SALT = 'friend-2026-401'
11
+
12
+ const SPECIES = ['duck','goose','blob','cat','dragon','octopus','owl','penguin','turtle','snail','ghost','axolotl','capybara','cactus','robot','rabbit','mushroom','chonk']
13
+ const SP_E = { duck:'🦆',goose:'🪿',blob:'🫧',cat:'🐱',dragon:'🐉',octopus:'🐙',owl:'🦉',penguin:'🐧',turtle:'🐢',snail:'🐌',ghost:'👻',axolotl:'🦎',capybara:'🦫',cactus:'🌵',robot:'🤖',rabbit:'🐰',mushroom:'🍄',chonk:'🐈' }
14
+ const RARITIES = ['common','uncommon','rare','epic','legendary']
15
+ const RARITY_W = { common:60, uncommon:25, rare:10, epic:4, legendary:1 }
16
+ const EYES = ['·','✦','×','◉','@','°']
17
+ const HATS = ['none','crown','tophat','propeller','halo','wizard','beanie','tinyduck']
18
+ const HAT_E = { none:'—',crown:'👑',tophat:'🎩',propeller:'🧢',halo:'😇',wizard:'🧙',beanie:'⛑',tinyduck:'🐤' }
19
+ const STATS = ['DEBUGGING','PATIENCE','CHAOS','WISDOM','SNACK']
20
+ const RARITY_FLOOR = { common:5, uncommon:15, rare:25, epic:35, legendary:50 }
21
+
22
+ // ANSI colors
23
+ const E = { rs:'\x1b[0m',b:'\x1b[1m',c:'\x1b[36m',g:'\x1b[32m',y:'\x1b[33m',m:'\x1b[35m',d:'\x1b[2m' }
24
+ const c = (code, text) => `${code}${text}${E.rs}`
25
+
26
+ // wyhash
27
+ const M64=(1n<<64n)-1n,WYP=[0xa0761d6478bd642fn,0xe7037ed1a0b428dbn,0x8ebc6af09c88c6e3n,0x589965cc75374cc3n]
28
+ function _mx(A,B){const r=(A&M64)*(B&M64);return((r>>64n)^r)&M64}
29
+ function _r8(p,i){return BigInt(p[i])|(BigInt(p[i+1])<<8n)|(BigInt(p[i+2])<<16n)|(BigInt(p[i+3])<<24n)|(BigInt(p[i+4])<<32n)|(BigInt(p[i+5])<<40n)|(BigInt(p[i+6])<<48n)|(BigInt(p[i+7])<<56n)}
30
+ function _r4(p,i){return BigInt(p[i])|(BigInt(p[i+1])<<8n)|(BigInt(p[i+2])<<16n)|(BigInt(p[i+3])<<24n)}
31
+ function _r3(p,i,k){return(BigInt(p[i])<<16n)|(BigInt(p[i+(k>>1)])<<8n)|BigInt(p[i+k-1])}
32
+ function wyhash(key,seed=0n){const len=key.length;seed=(seed^_mx(seed^WYP[0],WYP[1]))&M64;let a,b;if(len<=16){if(len>=4){a=((_r4(key,0)<<32n)|_r4(key,((len>>3)<<2)))&M64;b=((_r4(key,len-4)<<32n)|_r4(key,len-4-((len>>3)<<2)))&M64}else if(len>0){a=_r3(key,0,len);b=0n}else{a=0n;b=0n}}else{let i=len,p=0;if(i>48){let s1=seed,s2=seed;do{seed=_mx(_r8(key,p)^WYP[1],_r8(key,p+8)^seed);s1=_mx(_r8(key,p+16)^WYP[2],_r8(key,p+24)^s1);s2=_mx(_r8(key,p+32)^WYP[3],_r8(key,p+40)^s2);p+=48;i-=48}while(i>48);seed=(seed^s1^s2)&M64}while(i>16){seed=_mx(_r8(key,p)^WYP[1],_r8(key,p+8)^seed);i-=16;p+=16}a=_r8(key,p+i-16);b=_r8(key,p+i-8)}a=(a^WYP[1])&M64;b=(b^seed)&M64;const r=(a&M64)*(b&M64);a=r&M64;b=(r>>64n)&M64;return _mx((a^WYP[0]^BigInt(len))&M64,(b^WYP[1])&M64)}
33
+ function hWy(s){return Number(wyhash(Buffer.from(s,'utf8'))&0xffffffffn)}
34
+
35
+ function prng(seed){let a=seed>>>0;return()=>{a|=0;a=(a+0x6d2b79f5)|0;let t=Math.imul(a^(a>>>15),1|a);t=(t+Math.imul(t^(t>>>7),61|t))^t;return((t^(t>>>14))>>>0)/4294967296}}
36
+ function pick(rng,arr){return arr[Math.floor(rng()*arr.length)]}
37
+ function rollRar(rng){let r=rng()*100;for(const x of RARITIES){r-=RARITY_W[x];if(r<0)return x}return'common'}
38
+ function rollStats(rng,rar){const fl=RARITY_FLOOR[rar],pk=pick(rng,STATS);let dp=pick(rng,STATS);while(dp===pk)dp=pick(rng,STATS);const s={};for(const n of STATS){if(n===pk)s[n]=Math.min(100,fl+50+Math.floor(rng()*30));else if(n===dp)s[n]=Math.max(1,fl-10+Math.floor(rng()*15));else s[n]=Math.min(100,fl+Math.floor(rng()*40))}return s}
39
+ function roll(uid,salt=SALT){const rng=prng(hWy(uid+salt)),rar=rollRar(rng);return{rarity:rar,species:pick(rng,SPECIES),eye:pick(rng,EYES),hat:rar==='common'?'none':pick(rng,HATS),shiny:rng()<0.01,stats:rollStats(rng,rar)}}
40
+
41
+ function readCfg(){if(!existsSync(CONFIG_PATH))return null;try{return JSON.parse(readFileSync(CONFIG_PATH,'utf8'))}catch{return null}}
42
+
43
+ function writeConfig(uid, buddy, name, personality){
44
+ const cfg=readCfg()||{}
45
+ if(existsSync(CONFIG_PATH))copyFileSync(CONFIG_PATH,CONFIG_PATH+`.bak.${Date.now()}`)
46
+ cfg.userID=uid
47
+ cfg.companion={hatchedAt:cfg.companion?.hatchedAt||Date.now()}
48
+ const bones={species:buddy.species,rarity:buddy.rarity,eye:buddy.eye,hat:buddy.hat,shiny:buddy.shiny,stats:buddy.stats}
49
+ cfg.companionOverride=bones
50
+ cfg.companion.bones=bones
51
+ Object.assign(cfg.companion,bones)
52
+ if(name)cfg.companion.name=name
53
+ if(personality)cfg.companion.personality=personality
54
+ writeFileSync(CONFIG_PATH,JSON.stringify(cfg,null,2),'utf8')
55
+ }
56
+
57
+ // 交互式选择
58
+ const ask = q => new Promise(r => { const rl = createInterface({input:process.stdin,output:process.stdout}); rl.question(q, a => { rl.close(); r(a.trim()) }) })
59
+
60
+ async function select(title, items, allowSkip=false){
61
+ console.log(`\n ${c(E.b,title)}\n`)
62
+ items.forEach((it,i) => console.log(` ${c(E.c,`[${i+1}]`)} ${it}`))
63
+ if(allowSkip) console.log(` ${c(E.d,`[0] 不限制`)}`)
64
+ const a = await ask(`\n ${c(E.c,'>')} `)
65
+ const idx = parseInt(a)-1
66
+ if(allowSkip && a==='0') return null
67
+ return idx>=0&&idx<items.length ? items[idx] : (allowSkip?null:items[0])
68
+ }
69
+
70
+ async function main(){
71
+ console.log(`\n ${c(E.b+E.c,'🎰 快速 Buddy 搜索器')}`)
72
+ console.log(` ${c(E.d,'目标: LEGENDARY + SHINY ✨')}\n`)
73
+
74
+ // 选择物种
75
+ const speciesList = SPECIES.map(s => `${SP_E[s]} ${s}`)
76
+ const species = await select('选择物种 (可选)', speciesList, true)
77
+ console.log(species ? ` ✓ 物种: ${SP_E[species]} ${species}` : ` ✓ 物种: 不限制`)
78
+
79
+ // 选择眼睛
80
+ const eyeList = EYES.map(e => ` ${e}`)
81
+ const eye = await select('选择眼睛 (可选)', eyeList, true)
82
+ console.log(eye ? ` ✓ 眼睛: ${eye}` : ` ✓ 眼睛: 不限制`)
83
+
84
+ // 选择帽子
85
+ const hatList = HATS.map(h => `${HAT_E[h]} ${h}`)
86
+ const hat = await select('选择帽子 (可选)', hatList, true)
87
+ console.log(hat ? ` ✓ 帽子: ${HAT_E[hat]} ${hat}` : ` ✓ 帽子: 不限制`)
88
+
89
+ // 输入名字
90
+ const name = await ask(`\n ${c(E.m,'✏️')} 输入名字 (回车跳过): `)
91
+ console.log(name ? ` ✓ 名字: ${name}` : ` ✓ 名字: 自动生成`)
92
+
93
+ // 输入性格
94
+ const personality = await ask(` ${c(E.m,'✏️')} 输入性格 (回车跳过): `)
95
+ console.log(personality ? ` ✓ 性格: ${personality}` : ` ✓ 性格: 自动生成`)
96
+
97
+ // 开始搜索
98
+ console.log(`\n ${c(E.b,'🎯 开始搜索...')}\n`)
99
+ const start=Date.now()
100
+ let found=null
101
+ let attempts=0
102
+ const maxAttempts=1_000_000_000
103
+
104
+ for(let i=0;i<maxAttempts;i++){
105
+ const uid=randomBytes(32).toString('hex')
106
+ const buddy=roll(uid)
107
+ attempts++
108
+
109
+ // 检查条件: legendary + shiny + 可选的物种、眼睛和帽子
110
+ const matchRarity = buddy.rarity==='legendary'
111
+ const matchShiny = buddy.shiny
112
+ const matchSpecies = !species || buddy.species===species
113
+ const matchEye = !eye || buddy.eye===eye
114
+ const matchHat = !hat || buddy.hat===hat
115
+
116
+ if(matchRarity && matchShiny && matchSpecies && matchEye && matchHat){
117
+ found={uid,buddy}
118
+ console.log(`\n${c(E.g+E.b,' ✓ 找到了!')}`)
119
+ console.log(` 尝试次数: ${attempts.toLocaleString()}`)
120
+ console.log(` 耗时: ${(Date.now()-start)/1000}s`)
121
+ break
122
+ }
123
+
124
+ if(i>0 && i%100_000===0){
125
+ process.stdout.write(`\r ${c(E.d,`已搜索 ${i.toLocaleString()} 次...`)}`)
126
+ }
127
+ }
128
+
129
+ if(found){
130
+ console.log(`\n${c(E.b,' ════════════════════════════════════')}`)
131
+ console.log(`${c(E.b,' 🎉 宠物信息:')}`)
132
+ console.log(`${c(E.b,' ════════════════════════════════════')}`)
133
+ console.log(` ${SP_E[found.buddy.species]} ${c(E.y+E.b,found.buddy.species.toUpperCase())}`)
134
+ console.log(` ${c(E.y,'★★★★★')} legendary ${c(E.y,'✨ SHINY!')}`)
135
+ console.log(` 眼睛: ${found.buddy.eye}`)
136
+ console.log(` 帽子: ${HAT_E[found.buddy.hat]} ${found.buddy.hat}`)
137
+ console.log(`\n 属性:`)
138
+ for(const [n,v] of Object.entries(found.buddy.stats)){
139
+ const bar='█'.repeat(Math.round(v/5))+'░'.repeat(20-Math.round(v/5))
140
+ console.log(` ${n.padEnd(10)} ${c(v>=80?E.g:v>=50?E.y:E.d,bar)} ${v}`)
141
+ }
142
+
143
+ console.log(`\n 写入配置...`)
144
+ writeConfig(found.uid, found.buddy, name, personality)
145
+ console.log(`${c(E.g+E.b,' ✓ 完成!')}`)
146
+ console.log(`\n ${c(E.c,'重启 Claude Code 运行 /buddy 查看结果')}`)
147
+ }else{
148
+ console.log(`\n${c(E.y,' ⚠ 未找到,请再运行一次或放宽条件')}`)
149
+ }
150
+ }
151
+
152
+ main()
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "cc2190-buddy",
3
+ "version": "1.0.1",
4
+ "description": "快速搜索 legendary + shiny 宠物,支持自定义物种、眼睛、帽子选项",
5
+ "type": "module",
6
+ "bin": {
7
+ "cc2190-buddy": "./fast_buddy.mjs"
8
+ },
9
+ "scripts": {
10
+ "start": "node fast_buddy.mjs"
11
+ },
12
+ "keywords": [
13
+ "claude",
14
+ "claude-code",
15
+ "buddy",
16
+ "pet",
17
+ "reroll",
18
+ "companion",
19
+ "anthropic",
20
+ "legendary",
21
+ "shiny"
22
+ ],
23
+ "author": "ssooddaa",
24
+ "license": "MIT",
25
+ "engines": {
26
+ "node": ">=16.0.0"
27
+ },
28
+ "files": [
29
+ "fast_buddy.mjs",
30
+ "LICENSE",
31
+ "README.md"
32
+ ]
33
+ }