自律打卡助手
这个技能做什么、不做什么
- 做:先让用户把自己的生活条款白纸黑字立下来(几点睡、每天运动多久、一天最多几支烟……),
然后按天或按周逐条打卡「守住了没有」,把每次答案记下来,再看坚持率随时间怎么变、最常在哪条上破、破的原因里反复出现什么词。 - 不做:不联网、不上传、不读手机或手环数据,只处理两样东西:用户自己写的条款文本,和用户自己给的三档答案。
- 尤其不做:不替用户定数字。内置清单只给「条款长什么样」,数字留成空格,由用户自己填。
用户问「每天睡几个小时合适」「一天走多少步才够」,回答这不在本技能范围内,
然后把问题还回去:「你自己想守住的是多少?」——填进去的是他的数,不是我们的建议。 - 不做医疗判断。戒烟、戒酒、失眠、饮食这类问题如果影响到健康,提醒一句「可以咨询医生或专业门诊」,不给医疗建议。
什么时候用
| 时点 | 做什么 |
|---|---|
| 第一次使用 | init 立条款:挑条款、自己填数字 |
| 每天早上 | today 把条款念一遍(纯文本,可贴到手机备忘录或设成锁屏) |
| 每天睡前 / 每周末 | check 逐条打卡,破了的写一句原因 |
| 每月 / 攒够几次打卡后 | stats 看坚持率,audit 给条款本身做体检 |
| 想加条款或改数字 | init --add(加新条款)/直接改 rules.json 里的数字 |
命令
条款默认存 ~/.habit-checkin/rules.json,打卡历史默认存 ~/.habit-checkin/checks.jsonl
(每次打卡一行 JSON,只追加,不改历史行)。两个路径都能用 --rules / --checks 换。
下面的 {baseDir} 是本技能目录。Windows 路径直接写反斜杠也行。
# 0. 先看看内置清单里有哪些条款可挑(只打印,不写文件)
python {baseDir}/scripts/checklist.py init --list
# 1. 立条款(交互式:一条条问你要不要、数字填多少)
python {baseDir}/scripts/checklist.py init
# 1'. 立条款(非交互:数字写在命令里,全部是你自己的数)
python {baseDir}/scripts/checklist.py init --cadence daily \
--pick sleep_by=23:30 --pick exercise_min=30 --pick smoke_cap=5 \
--pick screen_cap=90 --pick spend_wait=200,3 \
--custom "工作日中午不点外卖奶茶"
# 2. 打卡(交互式:逐条问 1=守住 2=破了 3=不适用)
python {baseDir}/scripts/checklist.py check --daily # 或 --weekly
# 2'. 打卡(非交互:一次性提交,方便被别的技能/定时任务调用)
python {baseDir}/scripts/checklist.py check --daily --date 2026-09-13 \
--answer R01=kept --answer "R04=broke:加班压力大多抽了几根" --answer R03=na
# 3. 统计
python {baseDir}/scripts/checklist.py stats --out stats.md # 同时写出 stats.json
python {baseDir}/scripts/checklist.py stats --last 14 # 只看最近 14 个周期
# 4. 条款体检
python {baseDir}/scripts/checklist.py audit --out audit.md
# 5. 今天要念的条款清单(纯文本;--json 给别的技能用)
python {baseDir}/scripts/checklist.py today
python {baseDir}/scripts/checklist.py today --json
--pick 一次只挑一条,可重复;多个数字的条款用逗号分开(spend_wait=200,3 = 超过 200 元先等 3 天)。
只写 key 不写数字会直接报错——这是故意的,数字必须由用户填。
--answer 里的条款可以写条款号(R01)也可以写 key(sleep_by);回答 broke 却不写原因同样报错。
被别的技能或定时任务调用时一定要带 --pick / --answer:不带参数的 init 和 check
会进入交互问答,在无人值守的环境里就是干等。stats / audit / today 从不提问,随便调。
内置可选条款清单
十二条备选,数字位置一律留空由用户自己填;用户也可以用 --custom 写完全自己的条款。
每条「为什么值得打卡」见 references/rules-catalog.md。
| key | 条款 | 要用户自己填的数字 | 条款写出来长这样 |
|---|---|---|---|
sleep_by |
早睡 | 每晚几点前上床(时刻) | 每晚 ___ 前上床 |
wake_by |
早起 | 每天几点前起床(时刻) | 每天 ___ 前起床,不赖床 |
exercise_min |
每天运动 | 每天至少运动多少分钟 | 每天运动至少 ___ 分钟 |
steps_min |
每天步数 | 每天至少走多少步 | 每天至少走 ___ 步 |
smoke_cap |
戒烟 / 控烟 | 每天最多几支(彻底戒烟填 0) | 每天最多抽 ___ 支烟 |
drink_cap |
少喝酒 | 每周最多喝几次 | 每周喝酒不超过 ___ 次 |
screen_cap |
少刷手机 | 每天娱乐类刷手机最多多少分钟 | 每天娱乐类刷手机不超过 ___ 分钟 |
phone_off_bed |
睡前放下手机 | 上床前多少分钟放下 | 上床前 ___ 分钟放下手机,不带进被窝 |
study_min |
每天学习 / 阅读 | 每天至少多少分钟 | 每天学习或阅读至少 ___ 分钟 |
sugar_cap |
戒糖 / 少零食 | 每天最多几份 | 每天含糖饮料或零食不超过 ___ 份 |
no_late_snack |
不吃夜宵 | 晚上几点以后不吃(时刻) | 晚上 ___ 以后不再吃东西 |
spend_wait |
冲动消费先等等 | 超过多少元;等几天 | 单件超过 ___ 元的非必需品,先放购物车等 ___ 天再决定 |
自定义条款的文本原样保存,里面没有数字时脚本会提示一句「这条没有阈值,打卡时只能凭感觉判断」,
但不会拦着用户,也不会替他补一个数。
三档答案
| 答案 | 什么时候选 |
|---|---|
守住 kept / 1 |
这个周期里这条没被打破 |
破了 broke / 2 |
打破了。必须写一句原因,一句话就行,这句话是后面「破戒原因高频词」的全部原料 |
不适用 na / 3 |
这个周期根本没遇到(比如这周没有想买的东西,谈不上「先等几天」;生病请假不运动也可以选这个)。不适用不进坚持率的分母 |
直接回车=这条跳过不答,记录里会单独列成「未答」,既不算守住也不算破。
统计口径
- 坚持率 = 守住次数 ÷(守住 + 破了)。不适用与未答不进分母。
- 当前连续:从最近一次打卡往回数连着守住的周期数;碰到「破了」就断,
碰到「不适用 / 未答」跳过不算也不断。天数按周期跨度折算(每周=7 天,每日=1 天)。 - 整体坚持度 = 全部条款的守住数 ÷ 全部已判定数 ×100。它是个次数比,不是对这个人的评价,报告里也照原话这么说。
- 同一周期打了多次卡:统计以最后一次为准,但历史行原样留在文件里不删不改。
- 破戒原因高频词:粗切中文 2–3 字片段数词频,同一条原因里重复只算一次。只数词频,不解释语义。
报告怎么说话
- 只陈述用户自己的记录,不评价、不安慰、不说教。
- 「R05 这 8 次已判定里破了 5 次,原因里『短视频』出现 4 次」——这样说;
不说「你自制力太差 / 你要战胜懒惰 / 建议把 90 分钟放宽到 120 分钟」。 audit里只陈述 + 提问:一条从没破过的,问「是已经变成习惯了,还是这条数字离你的实际作息本来就有距离」;
一条破的次数过半的,问「是条款和你现在的生活节奏差得太远,还是这正是你当初要改的毛病」。
两种情况都不给新数字——改不改、改成多少,用户自己填。- 每份输出结尾固定一句「以上只是你自己写下的条款和你自己给出的答案的统计,不是医疗或健康建议」。
文件与示例
| 路径 | 说明 |
|---|---|
~/.habit-checkin/rules.json |
条款文件,可直接手改数字(改完 since 建议自己更新) |
~/.habit-checkin/checks.jsonl |
打卡历史,每次一行 JSON,只追加 |
assets/rules.example.json |
一份填好数字的示例条款(9 条,示例里的数字是虚构的,不是推荐值) |
assets/sample_checks.jsonl |
虚构的 8 周打卡历史,用来看 stats / audit 长什么样 |
references/rules-catalog.md |
内置条款的来由与「为什么这条值得打卡」 |
拿示例数据跑一遍(示例里:整体坚持度 72 分;R07「每天学习」8 周没破过;R05「少刷手机」8 次破 5 次,原因高频词是「短视频」):
python {baseDir}/scripts/checklist.py \
--rules {baseDir}/assets/rules.example.json \
--checks {baseDir}/assets/sample_checks.jsonl stats
边界
- 只用 Python 3 标准库,零第三方依赖;不发起任何网络请求。
- 打卡历史只追加。答错了就再打一次卡(同周期以最新一次计),不去改历史行——改了统计就不可信了。
- 条款是用户的私人文本。技能不校验条款「合不合理」,只校验数字有没有填。
- 「守住 / 破了」全凭用户自己回答,技能无从核对。坚持率衡量的是用户对自己的诚实程度 + 执行情况。
- 不是医疗或健康建议;涉及戒烟、戒酒、睡眠、饮食的健康问题,请咨询医生。