mcpField
W
work-hours

work-hours

github.com/marks97生产力0150 次安装3 周前更新
代码仓库

关于 work-hours

根据个人已有的活动时间戳估算工作时长的技能。它比较消息活动与设备在场模型,并说明如何依据证据校准空闲时长、解读数据。

主要功能

  1. 01合并多个来源的活动记录
  2. 02比较消息与设备在场模型
  3. 03依据证据校准空闲阈值
  4. 04按客户归属工作时长
  5. 05扣除休息与休闲活动

适用场景

  1. 01依据活动记录估算工作时长
  2. 02比较不同方法的工时结果
  3. 03区分工作、休息与休闲
  4. 04生成按工作日和客户划分的报告

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/marks97/work-hours --skill work-hours

安装后在 Claude Code 中输入/work-hours确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
config.example.json
mac-upload-prompt.md
methodology.md
sources.md
scripts/
calibrate.py
common.py
extract_chess.py
extract_claude.py
extract_mac.py
extract_meetings.py
extract_whatsapp.py
model.py
slack_parse.py

详细介绍

工作时长

根据人员已经产生的时间戳,事后重建工作时间。结果的准确性只取决于两件事:区分人员自己的操作与自动化行为,以及判断沉默意味着什么。以下内容都围绕如何做好这两点。

在采信任何数字前,请先阅读 references/methodology.md——其中列出了那些会让结果偏差数小时的陷阱。各数据源的具体操作方法见 references/sources.md。

基本原则

  • 个人数据默认临时存储。 所有内容都放在配置中的运行目录(run_dir,默认值为 ~/.cache/work-hours/run)。绝不要将提取的事件写入代码仓库。人员表示工作完成后,删除运行目录及所有上传的数据(浏览器历史记录、聊天导出文件、屏幕使用时间数据库);并确认这些路径已不存在。
  • 全程只读。 对 Slack、GitHub、跟踪工具、邮件,只搜索和读取,不发布内容或进行互动。
  • 限制资源占用。 转录文件夹可能有数 GB:使用 nice -n 19 ionice -c3,逐行读取,只启用一到两个读取进程,并使用 python3 -I。
  • 索取数据,不要猜测。 人员可以提供你无法访问的数据(聊天导出文件、笔记本电脑上的文件、国际象棋用户名、会议安排)。尽早询问;参见“需要索取的内容”。

工作流

S=<this skill>/scripts
# 0. config: copy references/config.example.json to ~/.config/work-hours/config.json and fill it in
#    (timezone, window, customer rules, Slack user id, chess usernames, meeting schedule, categories).
#    The person's real config never lives inside the skill.

python3 -I $S/extract_claude.py                 # human prompts + answers/interrupts from transcripts
# Slack: run the MCP search loop (references/sources.md), then:
python3 -I $S/slack_parse.py <saved result files...>
python3 -I $S/extract_whatsapp.py _chat.txt --me "<name>" --customer <c> --tag <who>
python3 -I $S/extract_chess.py                  # chess.com / lichess → leisure intervals
python3 -I $S/extract_meetings.py               # recordings + recurring calls (run after the point extractors)
python3 -I $S/extract_mac.py <upload-dir>       # laptop presence, foreground apps, browsing
# any other human-only source (PR approvals, tracker moves made in the UI): write events.<name>.ndjson
python3 -I $S/calibrate.py                      # silence survival, bout criterion, ground-truth check
python3 -I $S/model.py --idle 25 --tail 5       # → report.md

单点事件存储在 events.<source>.ndjson(ts、src、customer、kind)中;时间段存储在 intervals.<source>.ndjson(start、end、category)中。model.py 会读取所有匹配这些名称的文件,因此新增数据源只需添加一个新文件。

模型

有两种独立的方法。报告两者;两者结果一致,才说明准确。

  • B. 消息: 将所有来源中的每个人工操作合并成一条时间线。沉默不超过 idle 分钟时视为工作;超过此时长则视为休息,但仍会从最后一次操作之后计入 tail 分钟。休闲时间段(国际象棋对局、休闲浏览)会被扣除。
  • A. 在场情况: 笔记本电脑处于有人使用状态的时长(已解锁,并扣除显示器睡眠后的尾随时长),减去休闲时间,再加上仅在有证据时确认的离开电脑工作时长:电脑不在身边时发送的手机消息(间隔少于 idle 分钟时合并计算)以及通话。笔记本电脑显示人员已离开时,不要让消息模型继续填补空档——这会导致每天重复计入约 1.5 小时。

先合并所有客户的数据进行衡量;按客户拆分时,将每个工作分钟归属到最近操作对应的客户。按固定的本地时间划分工作日(默认 05:00),因此 02:00 的工作时段归入前一天。

选择空闲阈值(最重要的数字)

在一个真实数据集中,阈值设为 5 分钟和 60 分钟时,结果分别从每天 6.0 小时变为 13.9 小时,而间隔直方图没有明显的自然分界。应进行校准,不要凭空选择。

  1. calibrate.py 会给出工作时段的判定标准:一个下限,通常约为 10 分钟。
  2. 以人员本人的表述作为真实依据。 在他们使用的所有语言中,查找消息里的“午餐”“稍等一下”“回来了”“去睡觉了”“在火车上,用手机工作”等表达。每条匹配结果都要亲自阅读:不能让词语列表替你判断含义。编写包含 away 和 phone_work 时段的 labels.ndjson。合适的阈值应能区分这两种情况。在校准案例中,明确说明的休息间隔从未少于 27 分钟,手机工作间隔从未超过约 26 分钟,因此阈值定为 25 分钟。
  3. 注意力检查。 在由 Agent 驱动的工作中,查看人员是在 Agent 完成后几秒内回复(说明他们一直在关注),还是过了很久才回复(说明他们当时不在)。如果人员通常在 Agent 完成约 16 分钟后才回复,而且几乎从不在 2 分钟内回复,那么沉默就不代表他们在专注等待,因此不要为了涵盖这些情况而调高阈值。

可以索取的内容

按价值排序:

  1. 笔记本电脑活动。 将 references/mac-upload-prompt.md 发给他们 Mac 上的 Agent。该文件会上传浏览器历史记录、knowledgeC.db(屏幕开启时的前台应用)以及锁定/电源日志。这是最强的信号。
  2. 聊天记录导出,包括与他们共事的人之间的聊天(WhatsApp「导出聊天」)。
  3. 用于有 API 的休闲活动的用户名(chess.com、lichess)。
  4. 定期会议: 日期、时间、时长以及变更时间。
  5. 如果他们想要更精确的数据,可提供耗时较长的导出文件: Google Takeout(YouTube 和 Maps)、Apple Health(睡眠)。只有开启「跨设备共享」后,iPhone 的屏幕使用时间才会同步到 Mac;即便如此,数据仍保存在需要完全磁盘访问权限的系统存储中。
  6. 要排除的假期和其他时段,作为配置项 exclude。

报告

先列出工作日和周末每天的总时数,再说明不同方法和阈值下的范围。然后介绍各客户的时间分布、按时钟时间划分的日常规律(开始、用餐时段的低谷、第二个工作时段、结束),以及在「工作」时间内发现了多少休闲活动。明确指出仍无法看到的内容:手机屏幕使用时间、未记录的通话,以及离开键盘时的思考。

评论

支持 Markdown