claude-minipet 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/README.md +113 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +351 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/install.d.ts +4 -0
- package/dist/cli/install.js +89 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/cli/setup.d.ts +11 -0
- package/dist/cli/setup.js +203 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/core/dna.d.ts +14 -0
- package/dist/core/dna.js +95 -0
- package/dist/core/dna.js.map +1 -0
- package/dist/core/evolution.d.ts +16 -0
- package/dist/core/evolution.js +252 -0
- package/dist/core/evolution.js.map +1 -0
- package/dist/core/pet.d.ts +25 -0
- package/dist/core/pet.js +224 -0
- package/dist/core/pet.js.map +1 -0
- package/dist/core/rarity.d.ts +17 -0
- package/dist/core/rarity.js +55 -0
- package/dist/core/rarity.js.map +1 -0
- package/dist/core/sync.d.ts +37 -0
- package/dist/core/sync.js +94 -0
- package/dist/core/sync.js.map +1 -0
- package/dist/core/types.d.ts +92 -0
- package/dist/core/types.js +22 -0
- package/dist/core/types.js.map +1 -0
- package/dist/daemon/server.d.ts +8 -0
- package/dist/daemon/server.js +137 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/hooks/handler.d.ts +2 -0
- package/dist/hooks/handler.js +99 -0
- package/dist/hooks/handler.js.map +1 -0
- package/dist/render/anim-state.d.ts +5 -0
- package/dist/render/anim-state.js +24 -0
- package/dist/render/anim-state.js.map +1 -0
- package/dist/render/animation.d.ts +15 -0
- package/dist/render/animation.js +94 -0
- package/dist/render/animation.js.map +1 -0
- package/dist/render/frames.d.ts +51 -0
- package/dist/render/frames.js +151 -0
- package/dist/render/frames.js.map +1 -0
- package/dist/render/pixel.d.ts +44 -0
- package/dist/render/pixel.js +169 -0
- package/dist/render/pixel.js.map +1 -0
- package/dist/render/sprites.d.ts +8 -0
- package/dist/render/sprites.js +300 -0
- package/dist/render/sprites.js.map +1 -0
- package/dist/render/statusline.d.ts +3 -0
- package/dist/render/statusline.js +117 -0
- package/dist/render/statusline.js.map +1 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# 🐾 Claude MiniPet
|
|
2
|
+
|
|
3
|
+
一只住在 Claude Code 终端里的虚拟宠物。写代码时它会陪着你,获得经验、升级、进化。
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="https://img.shields.io/badge/Node.js-18+-339933?logo=nodedotjs&logoColor=white" />
|
|
7
|
+
<img src="https://img.shields.io/badge/Claude_Code-TUI-6c5ce7" />
|
|
8
|
+
<img src="https://img.shields.io/badge/License-MIT-blue" />
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
## 安装
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g github:crazyma99/claude-minipet
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
安装时会自动引导你完成配置:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
🐾 欢迎使用 Claude MiniPet!
|
|
21
|
+
|
|
22
|
+
📧 请输入你的邮箱: you@example.com
|
|
23
|
+
📤 发送验证码中...
|
|
24
|
+
✅ 验证码已发送到你的邮箱
|
|
25
|
+
|
|
26
|
+
🔑 请输入验证码: 483721
|
|
27
|
+
✅ 登录成功!
|
|
28
|
+
|
|
29
|
+
✨ 一只新的宠物诞生了! ✨
|
|
30
|
+
种族: 壳龙 (Shelldragon)
|
|
31
|
+
稀有度: ★★★ [传说]
|
|
32
|
+
🧬 DNA: A3-F7-2B-E1-8C-D4-09-5F
|
|
33
|
+
|
|
34
|
+
✅ Claude Code hooks 已配置
|
|
35
|
+
✅ 守护进程已启动
|
|
36
|
+
☁️ 宠物数据已上传到云端
|
|
37
|
+
|
|
38
|
+
重启 Claude Code 就能看到你的宠物了! 🎉
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
重启 Claude Code 后宠物就会出现在终端底部的 status line 里。
|
|
42
|
+
|
|
43
|
+
## 使用
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
claude-minipet status # 查看宠物详细状态
|
|
47
|
+
claude-minipet feed # 喂食(饱食度 +30)
|
|
48
|
+
claude-minipet pat # 摸摸(心情 +10,亲密 +2)
|
|
49
|
+
claude-minipet rename <名字> # 给宠物改名
|
|
50
|
+
claude-minipet redeem <兑换码> # 兑换码兑换宠物(宠物重新培养)
|
|
51
|
+
claude-minipet sync # 手动同步云端数据
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
日常使用不需要手动操作 — 宠物会在你用 Claude Code 编程时自动获得经验、升级、进化,数据自动同步到云端。
|
|
55
|
+
|
|
56
|
+
## 兑换码
|
|
57
|
+
|
|
58
|
+
通过兑换码可以获得指定种族和稀有度的宠物:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
claude-minipet redeem XXXX-XXXX-XXXX
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
兑换后当前宠物会被替换为新宠物(Lv.1 重新培养)。兑换码由管理员生成分发。
|
|
65
|
+
|
|
66
|
+
## 特性
|
|
67
|
+
|
|
68
|
+
- **🎲 程序化生成** — 每只宠物独一无二,基于 DNA 系统随机生成外观
|
|
69
|
+
- **🐱 6 个种族** — 位猫、壳龙、码史莱姆、吉狐、虫枭、像素精灵,各有专属被动技能
|
|
70
|
+
- **✨ 5 级稀有度** — 普通(60%) / 优秀(25%) / 稀有(10%) / 传说(4%) / 异色(1%)
|
|
71
|
+
- **📈 养成系统** — 等级、经验、心情、饱食度、亲密度
|
|
72
|
+
- **🧬 进化分支** — 3 阶段进化,编程习惯决定进化方向
|
|
73
|
+
- **🎨 像素画渲染** — Unicode 半块字符 + ANSI 24-bit 真彩色
|
|
74
|
+
- **💫 多帧动画** — 眨眼、进食、升级、进化等动态效果
|
|
75
|
+
- **☁️ 云端同步** — 邮箱登录,数据自动同步,跨设备使用
|
|
76
|
+
|
|
77
|
+
## 经验获取
|
|
78
|
+
|
|
79
|
+
使用 Claude Code 的过程中,宠物会自动获得经验:
|
|
80
|
+
|
|
81
|
+
| 事件 | 经验值 |
|
|
82
|
+
|------|--------|
|
|
83
|
+
| 发送消息 | +2 |
|
|
84
|
+
| Bash 命令 | +3 |
|
|
85
|
+
| 编辑/写入文件 | +5 |
|
|
86
|
+
| 读取文件 | +1 |
|
|
87
|
+
| 测试通过 | +10 |
|
|
88
|
+
| Git commit | +15 |
|
|
89
|
+
| 创建 PR | +20 |
|
|
90
|
+
|
|
91
|
+
## 种族
|
|
92
|
+
|
|
93
|
+
| 种族 | 被动技能 |
|
|
94
|
+
|------|---------|
|
|
95
|
+
| 🐱 位猫 Bitcat | 读文件时特别开心 |
|
|
96
|
+
| 🐉 壳龙 Shelldragon | Bash 命令双倍经验 |
|
|
97
|
+
| 🟢 码史莱姆 Codeslime | 升级经验需求 -20% |
|
|
98
|
+
| 🦊 吉狐 Gitfox | Git 操作额外经验 |
|
|
99
|
+
| 🦉 虫枭 Bugowl | 测试/调试双倍经验 |
|
|
100
|
+
| 🤖 像素精灵 Pixiebot | 心情衰减减半 |
|
|
101
|
+
|
|
102
|
+
## 进化
|
|
103
|
+
|
|
104
|
+
每个种族有 3 个进化阶段(幼年体 → 成长体 → 完全体),每阶段 2-3 个分支。进化方向取决于你的编程习惯:
|
|
105
|
+
|
|
106
|
+
- 写代码多 → 代码系进化
|
|
107
|
+
- 跑命令多 → 命令系进化
|
|
108
|
+
- 亲密度高 → 特殊进化
|
|
109
|
+
- 保持好心情 → 光系进化
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
|
|
113
|
+
MIT
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { loadState, saveState, saveConfig, createPet, feedPet, patPet, ensureDataDir } from '../core/pet.js';
|
|
3
|
+
import { generateDNA } from '../core/dna.js';
|
|
4
|
+
import { getRarityDisplay, RARITY_INFO } from '../core/rarity.js';
|
|
5
|
+
import { renderStatusLine } from '../render/statusline.js';
|
|
6
|
+
import { SPECIES_NAMES } from '../render/sprites.js';
|
|
7
|
+
import { handleHook } from '../hooks/handler.js';
|
|
8
|
+
import { startDaemon, stopDaemon, isDaemonRunning } from '../daemon/server.js';
|
|
9
|
+
import { installHooks } from './install.js';
|
|
10
|
+
import { fg, RESET, BOLD } from '../render/pixel.js';
|
|
11
|
+
import { triggerAnim } from '../render/anim-state.js';
|
|
12
|
+
import { loadAuth, saveAuth, sendCode, verifyCode, syncPetToServer, fetchPetFromServer, redeemCode } from '../core/sync.js';
|
|
13
|
+
import { createInterface } from 'node:readline';
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
const command = args[0];
|
|
16
|
+
async function main() {
|
|
17
|
+
switch (command) {
|
|
18
|
+
case 'init':
|
|
19
|
+
await initPet();
|
|
20
|
+
break;
|
|
21
|
+
case 'status':
|
|
22
|
+
showStatus();
|
|
23
|
+
break;
|
|
24
|
+
case 'feed':
|
|
25
|
+
doFeed();
|
|
26
|
+
break;
|
|
27
|
+
case 'pat':
|
|
28
|
+
doPat();
|
|
29
|
+
break;
|
|
30
|
+
case 'rename': {
|
|
31
|
+
const newName = args[1];
|
|
32
|
+
if (!newName) {
|
|
33
|
+
console.log('Usage: claude-minipet rename <name>');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
doRename(newName);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case 'hook':
|
|
40
|
+
await handleHook();
|
|
41
|
+
break;
|
|
42
|
+
case 'statusline':
|
|
43
|
+
showStatusLine();
|
|
44
|
+
break;
|
|
45
|
+
case 'login':
|
|
46
|
+
await doLogin(args[1]);
|
|
47
|
+
break;
|
|
48
|
+
case 'sync':
|
|
49
|
+
await doSync();
|
|
50
|
+
break;
|
|
51
|
+
case 'redeem':
|
|
52
|
+
await doRedeem(args[1]);
|
|
53
|
+
break;
|
|
54
|
+
case 'daemon':
|
|
55
|
+
handleDaemon(args[1]);
|
|
56
|
+
break;
|
|
57
|
+
case 'help':
|
|
58
|
+
default:
|
|
59
|
+
showHelp();
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function initPet() {
|
|
64
|
+
const existing = loadState();
|
|
65
|
+
if (existing) {
|
|
66
|
+
console.log(`你已经有一只宠物了: ${existing.name} (${SPECIES_NAMES[existing.species].zh})`);
|
|
67
|
+
console.log('如果想重新开始,请先删除 ~/.claude-minipet/state.json');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
ensureDataDir();
|
|
71
|
+
// Generate DNA
|
|
72
|
+
const dna = generateDNA();
|
|
73
|
+
const speciesInfo = SPECIES_NAMES[dna.species];
|
|
74
|
+
const rarityInfo = RARITY_INFO[dna.rarity];
|
|
75
|
+
const rc = fg(rarityInfo.color);
|
|
76
|
+
// Create pet with default name
|
|
77
|
+
const defaultName = speciesInfo.zh;
|
|
78
|
+
const state = createPet(defaultName, dna.species, dna.raw, dna.rarity);
|
|
79
|
+
saveState(state);
|
|
80
|
+
// Save default config
|
|
81
|
+
const config = { language: 'zh', animationsEnabled: true, statusLineRows: 3 };
|
|
82
|
+
saveConfig(config);
|
|
83
|
+
// Show birth announcement
|
|
84
|
+
console.log('');
|
|
85
|
+
console.log(` ✨ ${BOLD}一只新的宠物诞生了!${RESET} ✨`);
|
|
86
|
+
console.log('');
|
|
87
|
+
console.log(` 种族: ${fg(dna.primaryColor)}${BOLD}${speciesInfo.zh}${RESET} (${speciesInfo.en})`);
|
|
88
|
+
console.log(` 稀有度: ${rc}${getRarityDisplay(dna.rarity, 'zh')}${RESET}`);
|
|
89
|
+
console.log(` DNA: ${dna.raw}`);
|
|
90
|
+
console.log('');
|
|
91
|
+
// Show the pet
|
|
92
|
+
console.log(renderStatusLine(state));
|
|
93
|
+
console.log('');
|
|
94
|
+
console.log(` 用 ${BOLD}claude-minipet rename <名字>${RESET} 给它起个名字吧!`);
|
|
95
|
+
console.log('');
|
|
96
|
+
// Install hooks
|
|
97
|
+
try {
|
|
98
|
+
installHooks();
|
|
99
|
+
console.log(' ✅ Claude Code hooks 已配置');
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
console.log(` ⚠️ Hook 配置失败: ${err}`);
|
|
103
|
+
console.log(' 请手动配置 ~/.claude/settings.json');
|
|
104
|
+
}
|
|
105
|
+
// Start daemon
|
|
106
|
+
if (!isDaemonRunning()) {
|
|
107
|
+
console.log(' 🔄 启动后台守护进程...');
|
|
108
|
+
// Fork daemon as detached process
|
|
109
|
+
const { spawn } = await import('node:child_process');
|
|
110
|
+
const daemonPath = new URL('../daemon/server.js', import.meta.url).pathname;
|
|
111
|
+
// We'll use the CLI entry point with daemon start
|
|
112
|
+
const child = spawn(process.execPath, [process.argv[1], 'daemon', 'start'], {
|
|
113
|
+
detached: true,
|
|
114
|
+
stdio: 'ignore',
|
|
115
|
+
});
|
|
116
|
+
child.unref();
|
|
117
|
+
console.log(' ✅ 守护进程已启动');
|
|
118
|
+
}
|
|
119
|
+
console.log('');
|
|
120
|
+
console.log(` ${BOLD}开始使用 Claude Code 吧,你的宠物会陪伴你! 🎉${RESET}`);
|
|
121
|
+
console.log('');
|
|
122
|
+
}
|
|
123
|
+
function showStatus() {
|
|
124
|
+
const state = loadState();
|
|
125
|
+
if (!state) {
|
|
126
|
+
console.log('还没有宠物。运行 claude-minipet init 创建一只!');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
console.log('');
|
|
130
|
+
console.log(renderStatusLine(state));
|
|
131
|
+
console.log('');
|
|
132
|
+
const speciesInfo = SPECIES_NAMES[state.species];
|
|
133
|
+
console.log(` 名字: ${state.name}`);
|
|
134
|
+
console.log(` 种族: ${speciesInfo.zh} (${speciesInfo.en})`);
|
|
135
|
+
console.log(` 🧬 DNA: ${state.dna}`);
|
|
136
|
+
console.log(` 等级: Lv.${state.level} (${state.exp}/${state.expToNext} EXP)`);
|
|
137
|
+
console.log(` 阶段: ${state.stage === 'baby' ? '幼年体' : state.stage === 'growth' ? '成长体' : '完全体'}`);
|
|
138
|
+
if (state.evolution) {
|
|
139
|
+
console.log(` 进化: ${state.evolution}`);
|
|
140
|
+
}
|
|
141
|
+
console.log(` 心情: ${state.mood}/100`);
|
|
142
|
+
console.log(` 饱食: ${state.hunger}/100`);
|
|
143
|
+
console.log(` 亲密: ${Math.floor(state.bond)}/100`);
|
|
144
|
+
console.log('');
|
|
145
|
+
console.log(` -- 统计 --`);
|
|
146
|
+
console.log(` 编辑文件: ${state.stats.totalEdits}`);
|
|
147
|
+
console.log(` 命令执行: ${state.stats.totalBash}`);
|
|
148
|
+
console.log(` 文件阅读: ${state.stats.totalReads}`);
|
|
149
|
+
console.log(` Git提交: ${state.stats.totalCommits}`);
|
|
150
|
+
console.log(` 会话数: ${state.stats.totalSessions}`);
|
|
151
|
+
console.log(` 连续登录: ${state.stats.loginStreak} 天`);
|
|
152
|
+
console.log('');
|
|
153
|
+
}
|
|
154
|
+
function showStatusLine() {
|
|
155
|
+
const state = loadState();
|
|
156
|
+
if (!state) {
|
|
157
|
+
process.exit(0);
|
|
158
|
+
}
|
|
159
|
+
// Status line reads stdin (session data from Claude Code) but we don't need it
|
|
160
|
+
// Just output the rendered status
|
|
161
|
+
process.stdout.write(renderStatusLine(state));
|
|
162
|
+
}
|
|
163
|
+
function doFeed() {
|
|
164
|
+
const state = loadState();
|
|
165
|
+
if (!state) {
|
|
166
|
+
console.log('还没有宠物。运行 claude-minipet init 创建一只!');
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const before = state.hunger;
|
|
170
|
+
feedPet(state);
|
|
171
|
+
triggerAnim('feed');
|
|
172
|
+
console.log(`◆ 喂食成功! 饱食度: ${before} → ${state.hunger}`);
|
|
173
|
+
}
|
|
174
|
+
function doPat() {
|
|
175
|
+
const state = loadState();
|
|
176
|
+
if (!state) {
|
|
177
|
+
console.log('还没有宠物。运行 claude-minipet init 创建一只!');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const beforeMood = state.mood;
|
|
181
|
+
const beforeBond = Math.floor(state.bond);
|
|
182
|
+
patPet(state);
|
|
183
|
+
triggerAnim('pat');
|
|
184
|
+
console.log(`♥ 摸摸 ${state.name}! 心情: ${beforeMood} → ${state.mood}, 亲密: ${beforeBond} → ${Math.floor(state.bond)}`);
|
|
185
|
+
}
|
|
186
|
+
function doRename(newName) {
|
|
187
|
+
const state = loadState();
|
|
188
|
+
if (!state) {
|
|
189
|
+
console.log('还没有宠物。运行 claude-minipet init 创建一只!');
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const oldName = state.name;
|
|
193
|
+
state.name = newName;
|
|
194
|
+
saveState(state);
|
|
195
|
+
console.log(`✏️ ${oldName} 现在叫 ${BOLD}${newName}${RESET} 了!`);
|
|
196
|
+
}
|
|
197
|
+
function handleDaemon(subcommand) {
|
|
198
|
+
switch (subcommand) {
|
|
199
|
+
case 'start':
|
|
200
|
+
startDaemon();
|
|
201
|
+
break;
|
|
202
|
+
case 'stop':
|
|
203
|
+
stopDaemon();
|
|
204
|
+
break;
|
|
205
|
+
case 'status':
|
|
206
|
+
if (isDaemonRunning()) {
|
|
207
|
+
console.log('Daemon is running.');
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
console.log('Daemon is not running.');
|
|
211
|
+
}
|
|
212
|
+
break;
|
|
213
|
+
default:
|
|
214
|
+
console.log('Usage: claude-minipet daemon <start|stop|status>');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** Prompt user for input in terminal */
|
|
218
|
+
function prompt(question) {
|
|
219
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
220
|
+
return new Promise(resolve => {
|
|
221
|
+
rl.question(question, answer => {
|
|
222
|
+
rl.close();
|
|
223
|
+
resolve(answer.trim());
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
/** Login with email verification code */
|
|
228
|
+
async function doLogin(serverUrl) {
|
|
229
|
+
const url = serverUrl ?? 'http://localhost:3456';
|
|
230
|
+
console.log(` 服务器: ${url}`);
|
|
231
|
+
const email = await prompt(' 请输入邮箱: ');
|
|
232
|
+
if (!email || !email.includes('@')) {
|
|
233
|
+
console.log(' 邮箱格式不正确');
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
console.log(' 发送验证码中...');
|
|
237
|
+
const sendResult = await sendCode(url, email);
|
|
238
|
+
if (!sendResult.ok) {
|
|
239
|
+
console.log(` ❌ ${sendResult.error ?? '发送失败'}`);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
console.log(' ✅ 验证码已发送到邮箱');
|
|
243
|
+
const code = await prompt(' 请输入验证码: ');
|
|
244
|
+
if (!code) {
|
|
245
|
+
console.log(' 已取消');
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const verifyResult = await verifyCode(url, email, code);
|
|
249
|
+
if (!verifyResult.ok || !verifyResult.token) {
|
|
250
|
+
console.log(` ❌ ${verifyResult.error ?? '验证失败'}`);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
saveAuth({
|
|
254
|
+
token: verifyResult.token,
|
|
255
|
+
email,
|
|
256
|
+
userId: verifyResult.userId,
|
|
257
|
+
serverUrl: url,
|
|
258
|
+
});
|
|
259
|
+
console.log(` ✅ 登录成功! (${email})`);
|
|
260
|
+
// Sync pet to server if exists
|
|
261
|
+
const state = loadState();
|
|
262
|
+
if (state) {
|
|
263
|
+
await syncPetToServer(state);
|
|
264
|
+
console.log(' ✅ 宠物数据已同步到服务器');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/** Sync pet data with server */
|
|
268
|
+
async function doSync() {
|
|
269
|
+
const auth = loadAuth();
|
|
270
|
+
if (!auth) {
|
|
271
|
+
console.log(' 未登录。请先运行: claude-minipet login <服务器地址>');
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const localState = loadState();
|
|
275
|
+
const remoteState = await fetchPetFromServer();
|
|
276
|
+
if (localState && remoteState) {
|
|
277
|
+
// Both exist — use the one with more recent interaction
|
|
278
|
+
const localTime = new Date(localState.lastInteraction).getTime();
|
|
279
|
+
const remoteTime = new Date(remoteState.lastInteraction).getTime();
|
|
280
|
+
if (localTime >= remoteTime) {
|
|
281
|
+
await syncPetToServer(localState);
|
|
282
|
+
console.log(' ✅ 本地数据已同步到服务器 (本地较新)');
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
saveState(remoteState);
|
|
286
|
+
console.log(' ✅ 服务器数据已同步到本地 (服务器较新)');
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
else if (localState && !remoteState) {
|
|
290
|
+
await syncPetToServer(localState);
|
|
291
|
+
console.log(' ✅ 本地数据已上传到服务器');
|
|
292
|
+
}
|
|
293
|
+
else if (!localState && remoteState) {
|
|
294
|
+
saveState(remoteState);
|
|
295
|
+
console.log(' ✅ 服务器数据已下载到本地');
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
console.log(' 本地和服务器都没有宠物数据');
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/** Redeem a code to get a new pet */
|
|
302
|
+
async function doRedeem(code) {
|
|
303
|
+
const auth = loadAuth();
|
|
304
|
+
if (!auth) {
|
|
305
|
+
console.log(' 未登录。请先运行: claude-minipet login');
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (!code) {
|
|
309
|
+
code = await prompt(' 🎫 请输入兑换码: ');
|
|
310
|
+
}
|
|
311
|
+
if (!code) {
|
|
312
|
+
console.log(' 已取消');
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
console.log(' 兑换中...');
|
|
316
|
+
const result = await redeemCode(code);
|
|
317
|
+
if (!result.ok) {
|
|
318
|
+
console.log(` ❌ ${result.error ?? '兑换失败'}`);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
// Save new pet locally
|
|
322
|
+
if (result.pet) {
|
|
323
|
+
saveState(result.pet);
|
|
324
|
+
console.log(` ✅ ${result.message}`);
|
|
325
|
+
console.log('');
|
|
326
|
+
console.log(renderStatusLine(result.pet));
|
|
327
|
+
console.log('');
|
|
328
|
+
console.log(` 用 ${BOLD}claude-minipet rename <名字>${RESET} 给新宠物起个名字吧!`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function showHelp() {
|
|
332
|
+
console.log(`
|
|
333
|
+
${BOLD}claude-minipet${RESET} - Claude Code 终端宠物
|
|
334
|
+
|
|
335
|
+
${BOLD}命令:${RESET}
|
|
336
|
+
init 创建新宠物并配置 hooks
|
|
337
|
+
login <url> 登录服务器 (如: login https://minipet.crazyma99.xyz)
|
|
338
|
+
sync 同步宠物数据到服务器
|
|
339
|
+
redeem <code> 兑换码兑换宠物 (宠物重新培养)
|
|
340
|
+
status 查看宠物详细状态
|
|
341
|
+
feed 喂食宠物 (饱食度 +30)
|
|
342
|
+
pat 摸摸宠物 (心情 +10, 亲密 +2)
|
|
343
|
+
rename <name> 给宠物改名
|
|
344
|
+
daemon start 启动后台守护进程
|
|
345
|
+
daemon stop 停止守护进程
|
|
346
|
+
daemon status 查看守护进程状态
|
|
347
|
+
help 显示帮助
|
|
348
|
+
`);
|
|
349
|
+
}
|
|
350
|
+
main().catch(console.error);
|
|
351
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
const CLAUDE_DIR = join(homedir(), '.claude');
|
|
5
|
+
const SETTINGS_FILE = join(CLAUDE_DIR, 'settings.json');
|
|
6
|
+
/** Install hooks and status line config into Claude Code settings */
|
|
7
|
+
export function installHooks() {
|
|
8
|
+
if (!existsSync(CLAUDE_DIR)) {
|
|
9
|
+
mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
// Read existing settings
|
|
12
|
+
let settings = {};
|
|
13
|
+
if (existsSync(SETTINGS_FILE)) {
|
|
14
|
+
try {
|
|
15
|
+
settings = JSON.parse(readFileSync(SETTINGS_FILE, 'utf-8'));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// If settings file is corrupt, start fresh but warn
|
|
19
|
+
console.warn('Warning: Could not parse existing settings.json, will create new one');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Ensure hooks object exists
|
|
23
|
+
if (!settings.hooks) {
|
|
24
|
+
settings.hooks = {};
|
|
25
|
+
}
|
|
26
|
+
const hooks = settings.hooks;
|
|
27
|
+
// Helper to add a hook without duplicating
|
|
28
|
+
const addHook = (event, matcher, command, options = {}) => {
|
|
29
|
+
if (!hooks[event]) {
|
|
30
|
+
hooks[event] = [];
|
|
31
|
+
}
|
|
32
|
+
const eventHooks = hooks[event];
|
|
33
|
+
// Check if our hook already exists
|
|
34
|
+
const existing = eventHooks.find(h => h.hooks?.some(hh => hh.command?.includes('claude-minipet')));
|
|
35
|
+
if (existing)
|
|
36
|
+
return; // Already installed
|
|
37
|
+
eventHooks.push({
|
|
38
|
+
matcher,
|
|
39
|
+
hooks: [{
|
|
40
|
+
type: 'command',
|
|
41
|
+
command,
|
|
42
|
+
...options,
|
|
43
|
+
}],
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
addHook('SessionStart', 'startup', 'claude-minipet hook');
|
|
47
|
+
addHook('UserPromptSubmit', '', 'claude-minipet hook');
|
|
48
|
+
addHook('PostToolUse', 'Bash|Write|Edit|Read', 'claude-minipet hook', { async: true });
|
|
49
|
+
addHook('Stop', '', 'claude-minipet hook');
|
|
50
|
+
// Install status line
|
|
51
|
+
settings.statusLine = {
|
|
52
|
+
type: 'command',
|
|
53
|
+
command: 'claude-minipet statusline',
|
|
54
|
+
refreshInterval: 2,
|
|
55
|
+
};
|
|
56
|
+
// Write settings
|
|
57
|
+
writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2), 'utf-8');
|
|
58
|
+
}
|
|
59
|
+
/** Remove hooks from Claude Code settings */
|
|
60
|
+
export function uninstallHooks() {
|
|
61
|
+
if (!existsSync(SETTINGS_FILE))
|
|
62
|
+
return;
|
|
63
|
+
let settings;
|
|
64
|
+
try {
|
|
65
|
+
settings = JSON.parse(readFileSync(SETTINGS_FILE, 'utf-8'));
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Remove our hooks
|
|
71
|
+
if (settings.hooks) {
|
|
72
|
+
const hooks = settings.hooks;
|
|
73
|
+
for (const [event, eventHooks] of Object.entries(hooks)) {
|
|
74
|
+
hooks[event] = eventHooks.filter(h => !h.hooks?.some(hh => hh.command?.includes('claude-minipet')));
|
|
75
|
+
if (hooks[event].length === 0) {
|
|
76
|
+
delete hooks[event];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Remove status line if it's ours
|
|
81
|
+
if (settings.statusLine) {
|
|
82
|
+
const sl = settings.statusLine;
|
|
83
|
+
if (sl.command?.includes('claude-minipet')) {
|
|
84
|
+
delete settings.statusLine;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2), 'utf-8');
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/cli/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Postinstall script — runs automatically after `npm install -g claude-minipet`.
|
|
4
|
+
*
|
|
5
|
+
* Full guided flow:
|
|
6
|
+
* 1. Login with email verification code → server creates user
|
|
7
|
+
* 2. Generate pet (DNA, species, rarity) → save locally + upload to server
|
|
8
|
+
* 3. Configure Claude Code hooks + status line
|
|
9
|
+
* 4. Start daemon
|
|
10
|
+
*/
|
|
11
|
+
export {};
|