claude-minipet 0.4.1 → 0.6.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 +36 -9
- package/dist/core/comments.d.ts +12 -0
- package/dist/core/comments.js +175 -0
- package/dist/core/comments.js.map +1 -0
- package/dist/core/evolution.d.ts +12 -4
- package/dist/core/evolution.js +157 -214
- package/dist/core/evolution.js.map +1 -1
- package/dist/core/pet.d.ts +3 -1
- package/dist/core/pet.js +58 -5
- package/dist/core/pet.js.map +1 -1
- package/dist/core/types.d.ts +9 -0
- package/dist/core/types.js.map +1 -1
- package/dist/hooks/handler.js +40 -0
- package/dist/hooks/handler.js.map +1 -1
- package/dist/render/bubble.d.ts +11 -0
- package/dist/render/bubble.js +165 -0
- package/dist/render/bubble.js.map +1 -0
- package/dist/render/statusline.js +5 -0
- package/dist/render/statusline.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# 🐾 Claude MiniPet
|
|
2
2
|
|
|
3
|
+
> [!IMPORTANT]
|
|
4
|
+
> **隐私声明:** 本项目所有 Hooks 仅用于宠物状态(经验、心情、饱食度等)的娱乐性监测,**不会读取、存储或传输你的任何代码内容、文件内容或对话内容。** 所有数据处理均在本地端侧完成,云同步仅上传宠物状态数值(等级、经验、统计计数等),不包含任何源码或隐私信息。项目完全开源,欢迎审查代码。
|
|
5
|
+
|
|
3
6
|
一只住在 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) 终端里的虚拟宠物。在你编程时它会陪伴在终端底部,随着你的 coding 活动获得经验、升级、进化。
|
|
4
7
|
|
|
5
8
|
> **前提条件:** 本工具是 Claude Code 的扩展插件,需要先安装 Node.js 和 Claude Code。
|
|
@@ -103,18 +106,42 @@ claude-minipet redeem XXXX-XXXX-XXXX
|
|
|
103
106
|
- **🎨 像素画渲染** — Unicode 半块字符 + ANSI 24-bit 真彩色
|
|
104
107
|
- **💫 多帧动画** — 眨眼、进食、升级、进化等动态效果
|
|
105
108
|
- **☁️ 云端同步** — 邮箱登录,数据自动同步,跨设备使用
|
|
109
|
+
- **💬 宠物气泡** — 实时语音气泡,显示工作状态、评语、彩蛋
|
|
110
|
+
- **🧠 AI 感知** — 新会话自动识别宠物命令,说"喂宠物"即可执行
|
|
111
|
+
|
|
112
|
+
## 宠物气泡
|
|
113
|
+
|
|
114
|
+
状态栏底部始终显示一个实时气泡,宠物会根据当前状态"说话":
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
╭────────────────────────────────────────────────╮
|
|
118
|
+
│ >> 疯狂Coding中... [3m25s] │ ← Claude 工作中
|
|
119
|
+
╰────────────────────────────────────────────────╯
|
|
120
|
+
|
|
121
|
+
╭────────────────────────────────────────────────╮
|
|
122
|
+
│ [ok] 任务完成了! (用时 5分12秒) │ ← Claude 停止时
|
|
123
|
+
╰────────────────────────────────────────────────╯
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
宠物还会根据你的编码行为吐槽或鼓励:
|
|
127
|
+
- 只 commit 不写测试 → "主人又在裸奔了..."
|
|
128
|
+
- 连续报错 → "又炸了...宠物捂脸"
|
|
129
|
+
- 深夜编码 → "都这么晚了,主人该休息了"
|
|
130
|
+
- 长时间离开后回来 → "主人回来啦!宠物想你了~"
|
|
106
131
|
|
|
107
132
|
## 经验获取
|
|
108
133
|
|
|
109
|
-
| 事件 |
|
|
110
|
-
|
|
111
|
-
| 发送消息 | +
|
|
112
|
-
| Bash 命令 | +
|
|
113
|
-
| 编辑/写入文件 | +
|
|
114
|
-
| 读取文件 | +1 |
|
|
115
|
-
| 测试通过 | +
|
|
116
|
-
| Git commit | +
|
|
117
|
-
| 创建 PR | +
|
|
134
|
+
| 事件 | 基础经验 | 内容加成 |
|
|
135
|
+
|------|---------|---------|
|
|
136
|
+
| 发送消息 | +3 | +1/100字符 |
|
|
137
|
+
| Bash 命令 | +5 | +1/100字符 |
|
|
138
|
+
| 编辑/写入文件 | +8 | +1/100字符 |
|
|
139
|
+
| 读取文件 | +2 | +1/100字符 |
|
|
140
|
+
| 测试通过 | +15 | +1/100字符 |
|
|
141
|
+
| Git commit | +20 | +1/100字符 |
|
|
142
|
+
| 创建 PR | +30 | +1/100字符 |
|
|
143
|
+
|
|
144
|
+
内容加成上限 +50,大文件操作获得更多经验。
|
|
118
145
|
|
|
119
146
|
## 种族
|
|
120
147
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PetState, HookInput } from './types.js';
|
|
2
|
+
/** Generate a code comment based on stats */
|
|
3
|
+
export declare function generateCodeComment(state: PetState, input: HookInput): string | null;
|
|
4
|
+
export interface MoodReaction {
|
|
5
|
+
moodDelta: number;
|
|
6
|
+
message: string | null;
|
|
7
|
+
anim: 'idle' | 'exp' | 'feed' | 'pat' | 'levelup' | 'evolve' | 'hungry' | 'sad' | null;
|
|
8
|
+
}
|
|
9
|
+
/** Analyze tool response for success/failure signals */
|
|
10
|
+
export declare function reactToCodeQuality(state: PetState, input: HookInput): MoodReaction;
|
|
11
|
+
/** Check for easter egg triggers */
|
|
12
|
+
export declare function checkEasterEgg(state: PetState, input: HookInput): string | null;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/** Minimum interval between comments (5 minutes) */
|
|
2
|
+
const COMMENT_COOLDOWN_MS = 5 * 60 * 1000;
|
|
3
|
+
/** Check if comment cooldown has passed */
|
|
4
|
+
function canComment(state) {
|
|
5
|
+
if (!state.lastComment)
|
|
6
|
+
return true;
|
|
7
|
+
return Date.now() - new Date(state.lastComment).getTime() >= COMMENT_COOLDOWN_MS;
|
|
8
|
+
}
|
|
9
|
+
/** Mark comment as sent */
|
|
10
|
+
function markCommented(state) {
|
|
11
|
+
state.lastComment = new Date().toISOString();
|
|
12
|
+
}
|
|
13
|
+
const CODE_COMMENTS = [
|
|
14
|
+
// No tests
|
|
15
|
+
{
|
|
16
|
+
condition: (s) => s.stats.totalCommits > 5 && s.stats.totalTests === 0,
|
|
17
|
+
messages: [
|
|
18
|
+
'主人又在裸奔了...一个测试都没写 ~',
|
|
19
|
+
'提交了这么多代码,测试呢?宠物有点慌...',
|
|
20
|
+
'commit 了但没 test,主人胆子真大!',
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
// Write a lot but rarely read
|
|
24
|
+
{
|
|
25
|
+
condition: (s) => s.stats.totalEdits > 20 && s.stats.totalReads < s.stats.totalEdits * 0.3,
|
|
26
|
+
messages: [
|
|
27
|
+
'主人写代码不看文档的吗?',
|
|
28
|
+
'写得比看得多好多...主人是凭感觉编程吗?',
|
|
29
|
+
'建议主人偶尔也 Read 一下代码哦~',
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
// Consecutive failures
|
|
33
|
+
{
|
|
34
|
+
condition: (s) => (s.recentFailures ?? 0) >= 3,
|
|
35
|
+
messages: [
|
|
36
|
+
'又炸了...宠物捂脸 🫣',
|
|
37
|
+
'连续报错了!主人要不要歇一会?',
|
|
38
|
+
'错误连连...宠物默默递上咖啡 ~',
|
|
39
|
+
'主人别急,bug 总会修好的!',
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
// Git commit spree
|
|
43
|
+
{
|
|
44
|
+
condition: (s) => s.stats.totalCommits > 0 && s.stats.totalCommits % 10 === 0,
|
|
45
|
+
messages: [
|
|
46
|
+
`哇,已经提交 ${0} 次了!主人好高产!`, // placeholder, replaced at runtime
|
|
47
|
+
'又一个 commit!主人今天状态不错~',
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
// High activity
|
|
51
|
+
{
|
|
52
|
+
condition: (s) => s.stats.totalEdits + s.stats.totalBash > 100,
|
|
53
|
+
messages: [
|
|
54
|
+
'主人今天好肝啊...注意身体哦!',
|
|
55
|
+
'产出爆表!宠物为你骄傲 💪',
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
// Healthy balance
|
|
59
|
+
{
|
|
60
|
+
condition: (s) => s.stats.totalTests > 10 && s.stats.totalCommits > 5,
|
|
61
|
+
messages: [
|
|
62
|
+
'有提交有测试,主人是靠谱的工程师!',
|
|
63
|
+
'测试覆盖不错!宠物心情很好~',
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
/** Pick a random element */
|
|
68
|
+
function pick(arr) {
|
|
69
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
70
|
+
}
|
|
71
|
+
/** Generate a code comment based on stats */
|
|
72
|
+
export function generateCodeComment(state, input) {
|
|
73
|
+
if (!canComment(state))
|
|
74
|
+
return null;
|
|
75
|
+
// Shuffle and try rules
|
|
76
|
+
const shuffled = [...CODE_COMMENTS].sort(() => Math.random() - 0.5);
|
|
77
|
+
for (const rule of shuffled) {
|
|
78
|
+
if (rule.condition(state, input)) {
|
|
79
|
+
markCommented(state);
|
|
80
|
+
let msg = pick(rule.messages);
|
|
81
|
+
// Replace placeholder for commit count
|
|
82
|
+
msg = msg.replace('${0}', String(state.stats.totalCommits));
|
|
83
|
+
return `🐾 ${state.name}: ${msg}`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
/** Analyze tool response for success/failure signals */
|
|
89
|
+
export function reactToCodeQuality(state, input) {
|
|
90
|
+
if (input.hook_event_name !== 'PostToolUse' || !input.tool_response) {
|
|
91
|
+
return { moodDelta: 0, message: null, anim: null };
|
|
92
|
+
}
|
|
93
|
+
const resp = input.tool_response.toLowerCase();
|
|
94
|
+
const toolName = (input.tool_name ?? '').toLowerCase();
|
|
95
|
+
// Test passed
|
|
96
|
+
if (toolName === 'bash' && (resp.includes('passed') || resp.includes('pass') || resp.includes('✓'))) {
|
|
97
|
+
if (resp.includes('test') || resp.includes('vitest') || resp.includes('jest') || resp.includes('pytest')) {
|
|
98
|
+
state.recentFailures = 0;
|
|
99
|
+
return { moodDelta: 5, message: null, anim: 'pat' };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Build/command failure
|
|
103
|
+
if (toolName === 'bash') {
|
|
104
|
+
const isError = resp.includes('error') || resp.includes('failed') || resp.includes('fail') ||
|
|
105
|
+
resp.includes('exception') || resp.includes('exit code 1') || resp.includes('command not found');
|
|
106
|
+
const isWarning = resp.includes('warning') || resp.includes('warn');
|
|
107
|
+
if (isError) {
|
|
108
|
+
state.recentFailures = (state.recentFailures ?? 0) + 1;
|
|
109
|
+
const delta = state.recentFailures >= 3 ? -5 : -2;
|
|
110
|
+
return { moodDelta: delta, message: null, anim: state.recentFailures >= 3 ? 'sad' : null };
|
|
111
|
+
}
|
|
112
|
+
if (isWarning) {
|
|
113
|
+
return { moodDelta: -1, message: null, anim: null };
|
|
114
|
+
}
|
|
115
|
+
// Success — reset failure counter
|
|
116
|
+
state.recentFailures = 0;
|
|
117
|
+
}
|
|
118
|
+
return { moodDelta: 0, message: null, anim: null };
|
|
119
|
+
}
|
|
120
|
+
// ─── 4. Easter eggs (time/behavior based) ───
|
|
121
|
+
/** Check for easter egg triggers */
|
|
122
|
+
export function checkEasterEgg(state, input) {
|
|
123
|
+
if (!canComment(state))
|
|
124
|
+
return null;
|
|
125
|
+
const hour = new Date().getHours();
|
|
126
|
+
const rand = Math.random();
|
|
127
|
+
// Late night coding (23:00 - 4:00)
|
|
128
|
+
if (hour >= 23 || hour < 4) {
|
|
129
|
+
if (rand < 0.3) {
|
|
130
|
+
markCommented(state);
|
|
131
|
+
return pick([
|
|
132
|
+
`🐾 ${state.name}: 都这么晚了,主人该休息了 💤`,
|
|
133
|
+
`🐾 ${state.name}: 宠物好困...主人还不睡吗?`,
|
|
134
|
+
`🐾 ${state.name}: 深夜写代码,bug 会变多的哦...`,
|
|
135
|
+
`🐾 ${state.name}: *打哈欠* 主人晚安~`,
|
|
136
|
+
]);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Early morning (5:00 - 7:00)
|
|
140
|
+
if (hour >= 5 && hour < 7) {
|
|
141
|
+
if (rand < 0.3) {
|
|
142
|
+
markCommented(state);
|
|
143
|
+
return pick([
|
|
144
|
+
`🐾 ${state.name}: 主人起得好早!今天也要加油~`,
|
|
145
|
+
`🐾 ${state.name}: 早起的程序员有 bug 修...不对`,
|
|
146
|
+
]);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Back after long idle (> 2 hours)
|
|
150
|
+
if (state.lastActivityTime) {
|
|
151
|
+
const idleMs = Date.now() - new Date(state.lastActivityTime).getTime();
|
|
152
|
+
if (idleMs > 2 * 60 * 60 * 1000) {
|
|
153
|
+
markCommented(state);
|
|
154
|
+
return pick([
|
|
155
|
+
`🐾 ${state.name}: 主人回来啦!宠物想你了~`,
|
|
156
|
+
`🐾 ${state.name}: 好久不见!宠物等了你好久~`,
|
|
157
|
+
`🐾 ${state.name}: 欢迎回来!准备继续写代码了吗?`,
|
|
158
|
+
]);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Random daily chat (2% chance per hook)
|
|
162
|
+
if (rand < 0.02) {
|
|
163
|
+
markCommented(state);
|
|
164
|
+
return pick([
|
|
165
|
+
`🐾 ${state.name}: 主人写的代码真好看~`,
|
|
166
|
+
`🐾 ${state.name}: 宠物觉得这个函数很优雅!`,
|
|
167
|
+
`🐾 ${state.name}: *蹭蹭* 继续加油!`,
|
|
168
|
+
`🐾 ${state.name}: 宠物在认真学习主人的代码呢~`,
|
|
169
|
+
`🐾 ${state.name}: 据说好的变量命名能延年益寿哦`,
|
|
170
|
+
`🐾 ${state.name}: 主人知道吗?第一个 bug 是一只真的虫子 bug`,
|
|
171
|
+
]);
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=comments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/core/comments.ts"],"names":[],"mappings":"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"}
|
package/dist/core/evolution.d.ts
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
import type { PetState, Species } from './types.js';
|
|
1
|
+
import type { PetState, Species, LangCategory, CodingStyle } from './types.js';
|
|
2
2
|
/** Evolution branch definition */
|
|
3
3
|
export interface EvolutionBranch {
|
|
4
4
|
name: string;
|
|
5
5
|
nameZh: string;
|
|
6
|
-
condition: (state: PetState) => boolean;
|
|
7
6
|
description: string;
|
|
8
7
|
}
|
|
9
|
-
/**
|
|
10
|
-
export
|
|
8
|
+
/** Per-species evolution tree */
|
|
9
|
+
export interface SpeciesEvolutionTree {
|
|
10
|
+
growth: Record<LangCategory, EvolutionBranch>;
|
|
11
|
+
final: Record<CodingStyle, EvolutionBranch>;
|
|
12
|
+
}
|
|
13
|
+
/** Full evolution tree: 6 species × (7 first-evo + 5 second-evo) */
|
|
14
|
+
export declare const EVOLUTION_TREE: Record<Species, SpeciesEvolutionTree>;
|
|
15
|
+
/** Get dominant programming language from file edit stats */
|
|
16
|
+
export declare function getDominantLang(state: PetState): LangCategory;
|
|
17
|
+
/** Get coding style from habits */
|
|
18
|
+
export declare function getCodingStyle(state: PetState): CodingStyle;
|
|
11
19
|
/** Check if pet is ready to evolve, return the branch name or null */
|
|
12
20
|
export declare function checkEvolution(state: PetState): string | null;
|
|
13
21
|
/** Get evolution info by name */
|