work-hours について
本人が残した活動時刻から勤務時間を推定するスキルです。メッセージとデバイスの在席モデルを比較し、証拠に基づくアイドル時間の調整とデータの解釈を案内します。
主な機能
- 01複数ソースの活動記録を統合
- 02メッセージと在席モデルを比較
- 03証拠に基づくアイドル閾値の調整
- 04顧客別の勤務時間の割り当て
- 05休憩と余暇活動の差し引き
活用シーン
- 01活動ログから勤務時間を推定
- 02手法ごとの勤務時間推定を比較
- 03仕事・休憩・余暇を区別
- 04曜日別・顧客別のレポート作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ marks97/ work-hours --skill work-hoursインストール後、Claude Code で/work-hoursを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/config.example.jsonmac-upload-prompt.mdmethodology.mdsources.mdscripts/calibrate.pycommon.pyextract_chess.pyextract_claude.pyextract_mac.pyextract_meetings.pyextract_whatsapp.pymodel.pyslack_parse.py詳細
勤務時間
本人が残したタイムスタンプから、事後的に勤務時間を再構成します。結果の精度は、本人の行動と自動処理を区別することと、無反応の時間をどう解釈するかという2点にかかっています。以下では、この2点を正しく見極める方法を説明します。
数値を信頼する前に、references/methodology.mdを読んでください。そこには、結果をそれぞれ数時間変えた落とし穴が記載されています。ソースごとの手順については、references/sources.mdを参照してください。
基本原則
- 個人データは、デフォルトで一時的なものとして扱います。 設定の実行ディレクトリ(
run_dir、デフォルトは~/.cache/work-hours/run)にすべて保存します。抽出したイベントをリポジトリに書き込んではいけません。本人が作業完了を告げたら、実行ディレクトリとすべてのアップロードデータ(ブラウザー履歴、チャットのエクスポート、スクリーンタイムのデータベースなど)を削除し、パスが存在しないことを確認します。 - すべて読み取り専用で操作します。 Slack、GitHub、トラッカー、メールでは、検索と閲覧のみを行い、投稿やリアクションはしません。
- 負荷を抑えます。 トランスクリプトのフォルダーは数ギガバイトに及ぶことがあります。
nice -n 19 ionice -c3を使い、1行ずつ読み込み、読み取りプロセスは1つか2つにし、python3 -Iを使います。 - 推測せず、データを尋ねます。 本人は、こちらからアクセスできない情報(チャットのエクスポート、ノートPCのファイル、チェスのユーザー名、会議の予定など)を提供できます。早めに尋ねてください。「尋ねるべきこと」を参照してください。
ワークフロー
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はこれらの名前に一致するファイルをすべて読み込むため、新しいソースを追加するには新しいファイルを用意するだけです。
モデル
独立した2つの手法を使います。両方を報告してください。両者の一致が、精度の根拠になります。
- B. メッセージ: すべてのソースにおける人間の行動を統合したタイムラインを作成します。無反応の時間が
idle分以内なら勤務時間とみなし、それを超えると休憩として扱います。ただし、最後の行動からtail分間は勤務時間に加算します。余暇の区間(チェスの対局、娯楽目的のブラウジングなど)は差し引きます。 - A. 在席: ノートPCの使用中の時間(ロック解除中から、ディスプレイのスリープ後の猶予時間を除いたもの)から余暇を差し引き、証拠がある場合に限り、ノートPCを離れて行った作業を加算します。具体的には、ノートPCから離れている間のスマートフォンでのメッセージ送信(間隔が
idle分未満の場合は連結)と通話です。ノートPCのログで本人が離席中と示されている時間に、メッセージモデルで空白時間を勤務として埋めてはいけません。これを行うと、1日あたり約1.5時間の二重計上になります。
まず、すべての顧客を合算して測定します。顧客別の内訳は、勤務時間の各分を最も近い行動の顧客に割り当てて算出します。勤務日は固定の現地時刻(デフォルトは05:00)で区切り、02:00の作業セッションは前日の分として扱います。
無反応時間のしきい値を決める(最も重要な数値)
実際のあるデータセットでは、しきい値を5分から60分に変えると、結果は1日あたり6.0時間から13.9時間まで変動し、時間差のヒストグラムには自然な区切りがありませんでした。しきい値は適当に選ばず、調整してください。
calibrate.pyで、作業セッションを判定する基準となる下限を求めます。通常は10分前後です。- 本人の言葉から正解データを得ます。 使われているすべての言語で、「昼食」「ちょっと離席」「戻りました」「寝ます」「電車の中で、スマートフォンから作業中」などの表現を含むメッセージを読みます。該当箇所は必ず自分で読み、単語リストだけで意味を判定してはいけません。休憩中の
away区間と、スマートフォンで作業中のphone_work区間を記録したlabels.ndjsonを作成します。適切なしきい値なら、この2つを区別できます。調整時には、本人が申告した休憩中の無反応時間は常に27分以上で、スマートフォンでの作業は約26分を超えなかったため、しきい値は25分でした。 - 注意の向け方を確認します。 エージェント主導の作業では、エージェントの処理終了後、本人が数秒で返信するか(作業を見守っていた)、それともかなり時間が経ってから返信するか(その場を離れていた)を確認します。返信がエージェントの処理終了から約16分後で、2分以内の返信がほとんどない場合、無反応の時間は注意を向けて待機していた時間ではありません。そこまで含めるようにしきい値を広げてはいけません。
何を依頼するか
価値の高い順です。
- ノートパソコンの利用状況。
references/mac-upload-prompt.mdを相手の Mac 上のエージェントに送ります。ブラウザーの履歴、knowledgeC.db(画面がオンのときの前面アプリ)、ロック/電源ログがアップロードされます。これが最も有力なシグナルです。 - 一緒に仕事をする相手とのチャットのエクスポート(WhatsApp の「チャットをエクスポート」)。
- API を利用できる余暇活動のユーザー名(chess.com、lichess)。
- 定例ミーティング: 曜日、時刻、長さ、変更時期。
- より精密な分析を希望する場合は、時間のかかるエクスポート:Google Takeout(YouTube と Maps)、Apple Health(睡眠)。 iPhone のスクリーンタイムが Mac に反映されるのは「デバイス間で共有」がオンの場合のみです。その場合も、フルディスクアクセスが必要なシステムストアに保存されています。
- 除外する休暇などの期間を設定の
excludeに指定します。
レポート
まず、平日と週末それぞれの合計時間を示し、次に手法としきい値ごとの範囲を示します。 続いて、顧客ごとの内訳、時間帯ごとの習慣(開始時刻、食事による中断、午後の作業、終了時刻)、そして「仕事」の時間内に見つかった余暇の量を説明します。まだ把握できないものとして、スマートフォンのスクリーンタイム、記録されていない通話、キーボードから離れて考えている時間を明記します。