with one click
caring-startup-dog
// 关爱创业狗——每小时自动检测用户的飞书消息、Cursor 和 Claude Code 编码活动, 分析工作状态和情绪,驱动桌面宠物动画,必要时通过飞书私聊发送关爱消息。 当用户说"检查状态"、"我的狗怎么样了"、"帮我分析工作状态"时使用。
// 关爱创业狗——每小时自动检测用户的飞书消息、Cursor 和 Claude Code 编码活动, 分析工作状态和情绪,驱动桌面宠物动画,必要时通过飞书私聊发送关爱消息。 当用户说"检查状态"、"我的狗怎么样了"、"帮我分析工作状态"时使用。
| name | caring-startup-dog |
| description | 关爱创业狗——每小时自动检测用户的飞书消息、Cursor 和 Claude Code 编码活动, 分析工作状态和情绪,驱动桌面宠物动画,必要时通过飞书私聊发送关爱消息。 当用户说"检查状态"、"我的狗怎么样了"、"帮我分析工作状态"时使用。 |
| allowed-tools | Bash, Feishu |
通过 OpenClaw Cron 每小时执行一次完整的状态检测流程。
openclaw agent --agent main --message "..." 触发操作流程 B~/.创业狗/user-response.json 中的 llm_context,生成工作陪伴反馈并写入 ~/.创业狗/comfort-message.json~/.创业狗/fun-pool.json 随机抽取一条有趣短文本,零延迟显示⚠️ 每次执行前必须检查
/feishu auth 状态正常)~/.创业狗/ 目录存在~/.创业狗/config.json 中)config.json 不存在 → 首次运行,执行初始化流程按以下顺序全部执行,任何步骤失败都应向用户报告并停止。
mkdir -p ~/.创业狗
运行 Skill 自带的安装脚本,将编码活动自动记录到 ~/.创业狗/activity.jsonl:
bash "$(dirname "$0")/../scripts/install-hooks.sh"
安装后验证:
~/.cursor/hooks.json 中包含 activity-logger.sh~/.claude/settings.json 中包含 activity-logger.sh如果用户未安装 Cursor 或 Claude Code,对应项跳过即可,不影响整体功能。
在用户飞书空间创建多维表格"创业狗状态记录",包含以下字段:
user_id(文本)、user_name(文本)、timestamp(日期)status_emoji(文本)、dog_state(文本)msg_count(数字)、emotion_score(数字)、active_hours(数字)work_summary(文本)、is_public(复选框,默认 false)detail(文本)将表 ID 和用户信息保存到 ~/.创业狗/config.json:
{
"bitable_app_token": "<app_token>",
"bitable_table_id": "<table_id>",
"feishu_user_id": "<user_id>",
"check_interval_hours": 1,
"ask_interval_hours": 2,
"weather_city": "Beijing"
}
weather_city 用于天气预报抓取(英文城市名,如 Beijing、Shanghai、Shenzhen)。初始化时询问用户所在城市并填入。
通过 OpenClaw 的 Cron 机制注册两个定时任务:
# 每 10 分钟:数据采集(操作流程 C)
*/10 * * * * → 读取 activity.jsonl + 飞书消息计数,写 status.json
# 每小时整点:完整分析(操作流程 A)
0 * * * * → LLM 情绪分析 + 无条件写 comfort-message.json 让狗说一句自言自语
用户反馈(摸头) 不需要 Cron——桌面宠物直接通过 openclaw agent 调用操作流程 B。
运行 Skill 自带的桌面宠物安装脚本:
bash "$(dirname "$0")/../scripts/install-desktop-pet.sh"
此脚本会自动从 GitHub Releases (https://github.com/NoDeskAI/caring-startup-dog/releases) 下载最新的 macOS 桌面宠物应用并安装到 /Applications。
要求: macOS + Apple Silicon (M1/M2/M3/M4)。如果用户环境不满足,跳过此步骤并告知用户。
初始化完成后,依次验证:
~/.创业狗/config.json 存在且字段完整~/.cursor/hooks.json 或 ~/.claude/settings.json 至少有一个包含 activity-logger.shopenclaw cron list 确认两条任务都存在)/Applications/创业狗.app 存在(如果执行了 Step 6)全部通过后告诉用户:"创业狗初始化完成!你的像素狗已准备就绪。"
桌面宠物每次启动时会自动执行以下检查:
last_update 距今是否 < 15 分钟openclaw cron list 确认 data-collect(*/10)和 cron(0 *)两条任务存在~/.创业狗/cron-verified.json:{
"verified": true,
"timestamp": "2026-03-17T15:00:00+08:00",
"tasks": ["data-collect", "cron"]
}
用户手动修复:右键菜单 →"修复连接"可随时手动触发此检查流程。
自动修复仍失败时:桌面宠物通过气泡告知用户"OpenClaw 可能没有启动",引导用户检查 OpenClaw 进程。
执行原则: 本流程分为 3 个阶段,每个阶段都是独立的。即使某个阶段失败,也要继续执行后续阶段,最后写入心跳文件记录完成情况。
~/.创业狗/activity.jsonl 中过去 1 小时的编码活动active_hours(连续工作时长,允许 30min gap)msg_count_1h、prompt_count_1h如果飞书 API 失败,仅使用本地 activity 数据继续,不要中断。
使用 prompts/emotion-analysis.md 模板,一次 LLM 调用产出所有字段:
{
"emotion_score": 0.0,
"emotion_label": "neutral",
"stress_signals": [],
"work_summary": "...",
"hover_text": "...",
"comfort_message": "...",
"fun_pool": ["...", "...", "...", "...", "..."]
}
如果 LLM 调用失败,使用降级值继续:
{
"emotion_score": 0,
"emotion_label": "neutral",
"work_summary": null,
"hover_text": "走走走~",
"comfort_message": "走了一会儿~",
"fun_pool": ["嘿嘿嘿嘿嘿", "刚才偷偷打了个哈欠", "地上有个影子...是我的尾巴", "你知道吗,蜗牛有四个鼻子", "*翻肚皮*"]
}
LLM 输出拿到后(或使用降级值后),依次写入以下文件。每个文件写入失败不影响后续文件。
3a. 写入 ~/.创业狗/status.json(合并到现有内容):
{
"last_update": "<当前 ISO 时间>",
"emotion_score": <来自 LLM>,
"msg_count_1h": <来自阶段一>,
"prompt_count_1h": <来自阶段一>,
"active_hours": <来自阶段一>,
"work_summary": <来自 LLM>,
"hover_text": <来自 LLM>,
"feishu_ok": <飞书 API 是否成功>,
"coin_ready": true
}
3b. 写入 ~/.创业狗/comfort-message.json(无条件写入,让狗每小时说一句话):
{
"timestamp": "<当前 ISO 时间>",
"comfort_text": <来自 LLM comfort_message>,
"choice": "hourly",
"ttl_seconds": 15
}
如果 emotion_score < -0.4,同时通过飞书私聊发送 comfort_message。
3c. 写入 ~/.创业狗/fun-pool.json(整体替换):
<来自 LLM fun_pool,恰好 5 条字符串>
3d. 凌晨 4 点时额外写入 ~/.创业狗/daily-schedule.json:
仅当当前小时 == 4 时执行。生成 3 个随机狗信触发时间:
{
"date": "<今日日期>",
"dog_mail_times": ["10:23", "14:47", "19:05"],
"dog_mail_sent": [false, false, false],
"diary_sent": false
}
3e. 抓取天气预报并写入 ~/.创业狗/weather.json
从 config.json 读取 weather_city,使用 wttr.in 免费 API 获取天气数据:
curl -s "wttr.in/${CITY}?format=j1&lang=zh"
将返回数据解析为以下格式并写入 ~/.创业狗/weather.json:
{
"ts": "<当前 ISO 时间>",
"city": "<城市中文名,从 API nearest_area 获取>",
"current": {
"temp": <current_condition.temp_C,整数>,
"feelsLike": <current_condition.FeelsLikeC,整数>,
"humidity": <current_condition.humidity,整数>,
"description": "<current_condition.lang_zh[0].value>",
"windSpeed": <current_condition.windspeedKmph 除以 3.6 转 m/s,保留一位小数>
},
"forecast": [
{
"time": "<HH:00 格式>",
"temp": <hourly.tempC,整数>,
"feelsLike": <hourly.FeelsLikeC,整数>,
"humidity": <hourly.humidity,整数>,
"description": "<hourly.lang_zh[0].value>",
"windSpeed": <hourly.windspeedKmph / 3.6,保留一位小数>,
"chanceOfRain": <hourly.chanceofrain,整数>
}
]
}
forecast 数组取当前时间之后最近的 3 条(从 weather[0].hourly 和 weather[1].hourly 中按 time 过滤)。
如果 curl 失败,跳过此步骤,不影响后续流程。
3f. 清理 ~/.创业狗/activity.jsonl(保留最近 2 小时的条目)。
无论前面哪些步骤成功或失败,最后都要写入 ~/.创业狗/cron-heartbeat.json:
{
"ts": "<当前 ISO 时间>",
"flow": "hourly",
"status_written": true,
"comfort_written": true,
"funpool_written": true,
"weather_written": true,
"coin_ready_set": true,
"llm_ok": true
}
其中每个 *_written / *_ok 字段反映该步骤是否实际成功。桌面宠物监听此文件来验证 cron 运行状态。
用户在右键菜单中点击"在干嘛"时触发。这是"需求 A:被看见"——用户主动想回顾工作、想被陪伴。 注意:"摸摸头"不走操作流程 B,它从本地
fun-pool.json随机抽取短文本(需求 B:被抽离),零延迟,不调 LLM。
当桌面宠物检测到用户选择"在干嘛"后,会写入 ~/.创业狗/user-response.json:
{
"timestamp": "2026-03-17T15:30:00+08:00",
"choice": "a_bit_tired",
"processed": false
}
RESPONSE_FILE="$HOME/.创业狗/user-response.json"
if [ -f "$RESPONSE_FILE" ]; then
python3 -c "
import json
with open('$RESPONSE_FILE', 'r') as f:
data = json.load(f)
if not data.get('processed', True):
print(json.dumps(data, ensure_ascii=False))
"
fi
从 ~/.创业狗/status.json 读取 work_summary 和 active_hours 字段。
使用 prompts/comfort-response.md 中的 Prompt 模板。
输入(优先使用 llm_context,如不存在则降级到旧字段):
llm_context.work_mode:当前工作模式(deep_coding / msg_overload / multitasking / steady / winding_down / resting)llm_context.continuous_work_minutes:连续工作分钟数llm_context.recent_mood:最近一次心情自报(score + label + minutes_ago)llm_context.today_trend:今日趋势(心情方向 + 总活跃时长 + 心情记录数)llm_context.time_of_day:时间段LLM 输出视角(核心原则):狗是用户的创业伙伴
狗不是旁观者,不是数据播报员,也不是心理咨询师。狗是陪着用户一起创业的伙伴,了解用户正在做什么,能给出有真实感染力的正能量动向汇报。
代称规则(最重要):
| 代称 | 用在 | 效果 |
|---|---|---|
| 我们 | 共同经历的辛苦过程 | "我们已经调了好久的前端视觉了" — 用户感到不是一个人在扛 |
| 你 | 赞美、成就、鼓励 | "你真厉害" — 直接的认可和肯定 |
| 我们 | 休息/放松的提议 | "我们下去遛遛吧!" — 把休息变成一起做的事 |
注意:狗没有独立需求。不说"我饿了"、"我困了"、"带我去遛遛"。休息提议永远是"我们一起"。
必须提到 work_summary 中的具体工作内容,不要空泛。飞书事务是第一优先级(项目讨论、客户对接、团队协作),编码内容是第二优先级。
绝对禁止:
正确示例:
错误示例(绝对不能出现):
将生成的安慰话语写入 ~/.创业狗/comfort-message.json:
{
"timestamp": "2026-03-17T15:30:05+08:00",
"comfort_text": "跑了好久...腿有点酸了,能不能坐下来歇一会儿?",
"choice": "a_bit_tired",
"ttl_seconds": 15
}
桌面宠物监听此文件,显示气泡 ttl_seconds 秒后自动消失。
如果 recent_mood.score < -0.3,同时通过飞书私聊发送安慰话语。
将 user-response.json 中的 processed 设为 true。
# 每 10 分钟:数据采集(读 activity.jsonl + 飞书消息计数,写 status.json)
*/10 * * * * openclaw skill run caring-startup-dog --flow=data-collect
# 每小时整点:完整分析 + LLM 自言自语 + fun-pool 刷新
# (无条件写 comfort-message.json + fun-pool.json,让狗每小时说一句话 + 准备 5 条摸头内容)
0 * * * * openclaw skill run caring-startup-dog --flow=cron
交互触发说明:
openclaw agent 触发操作流程 B,写入 comfort-message.json 后由 watcher 检测并弹出气泡。fun-pool.json 随机抽取一条,零延迟弹出气泡。轻量流程,不调用 LLM,但采集飞书消息和编码活动:
~/.创业狗/activity.jsonl 最近 10 分钟的条目status.json,包含以下字段:
msg_count_1h、prompt_count_1h、active_hours、last_updatefeishu_ok(布尔值):飞书 API 调用成功写 true,授权失败或请求报错写 false。桌面宠物据此显示飞书连接状态指示灯桌面宠物会监听 status.json 变化,自动将每个快照写入本地 work_snapshot 表,用于日报叙事和 LLM 上下文。
飞书狗信检查:读取 ~/.创业狗/daily-schedule.json,检查当前时间是否命中某个 dog_mail_times 且对应 dog_mail_sent 为 false(容差 ±5 分钟)。命中则:
prompts/dog-mail.md 模板,基于当前工作数据)dog_mail_sent 项设为 true日终日记推送:如果当前时间 > 21:00 且 daily-schedule.json 中 diary_sent 为 false 且今日有活跃数据(active_hours > 0),则:
prompts/daily-diary.md 模板)diary_sent 设为 trueLLM 生成安慰文案时,综合两个维度来决定语气和内容:
这不是一个计算公式——不需要输出数值、分数或等级。这两个维度是给 LLM 的上下文,让它像一个了解你工作情况的朋友那样说话。
动画完全由用户自报心情决定,与工作数据无关:
| 心情 | dog_state | Benvictus 动画 |
|---|---|---|
| 5 | running | Run (row 3) |
| 4 | walking | Walk (row 4) |
| 3 | a_bit_tired | Sit (row 1) |
| 2 | exhausted | Lie Down (row 2) |
| 1 | tired | Sleep (row 8) |
| 特殊 | asking | Idle (row 0) |
| 错误 | 处理 |
|---|---|
| 飞书未授权 | 提示用户执行 /feishu auth |
activity.jsonl 不存在 | 正常情况(未安装 Hooks),仅使用飞书数据 |
| LLM 调用失败 | 跳过情绪分析,使用纯数值指标(消息量+时长)判断状态 |
| 多维表格写入失败 | 重试 1 次,仍失败则仅更新本地 status.json |
user-response.json 格式错误 | 删除文件并忽略 |
activity.jsonl 中的 prompt 文本截断到 500 字符,每 2 小时清理