Files
chktime/CLAUDE.md
T
yoshikazuandClaude Opus 5 d23bcabd76 ガントで範囲外にはみ出すタスクの全体時間と往復数も範囲内に揃える
表示範囲を絞ったとき、作業時間だけが範囲内に切り詰められ、全体時間・往復数・
ツール呼び出し数はセッション全体の値のままだったので、1日表示に「全体 793時間」
のような数字が並んで読み違えやすかった。

範囲の左端で切れている行は全体時間を「表示範囲の開始→セッション終了」にし、
往復数とツール数も範囲内のターンだけを数える。切り詰めた行には clipped を立て、
ツールチップのラベルを「全体」→「表示範囲内」に変える。開始→終了の日時は
実際の値のままなので、範囲外へ続いていることはそこで分かる。

ガントの CSV にも clipped 列を追加した。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 11:17:06 +09:00

4.2 KiB
Raw Blame History

chktime

Claude Code の会話ログ(~/.claude/projects/<プロジェクト>/<セッションID>.jsonl)を解析して、 タスクごとのやりとりの時刻を表示するローカル Web アプリ。使い方は README.md に書いてある。

構成

chktime.py      サーバ + jsonl 解析(これ1本で完結)
web/index.html  画面の骨組み
web/app.js      表示ロジック(フレームワークなし・素の DOM 操作)
web/style.css   スタイル(ダークテーマ固定)
run.bat         コンソール表示で起動
stop.cmd        起動中の chktime を終了

chktime.py の中身は上から「解析ロジック → Store(キャッシュ)/ Watcher(更新検出)→ HTTP」の順。

守ること

  • 標準ライブラリのみ。外部パッケージも CDN も使わない。ブラウザ側もフレームワークなし。
  • 外部通信しない。読むのはローカルの jsonl だけ。
  • 会話ログは読み取り専用。検証で書き換えるときはスクラッチパッドにコピーしてから行う。
  • .bat / .cmd は cmd の既定コードページで読まれるので中身は ASCII のみ(日本語を書かない)。
  • コメント・コミットメッセージ・UI の文言は日本語。
  • 機能を足したら README.md も更新する。

動かす

python chktime.py --port 8799 --no-browser

ユーザーは 8787 でデスクトップショートカットから常用しているので、検証は 8799 など別ポートで立てる。 停止は stop.cmd(ただし chktime.py を実行中の python/pythonw をすべて終了するので、 検証用だけを止めたいときはコマンドラインでポートを見て個別に kill する)。

API

ルート 内容
/api/projects プロジェクト一覧
/api/sessions?project= そのプロジェクトのタスク一覧
/api/all 全プロジェクトのタスク一覧(横断モード)
/api/session?project=&id= 1タスクのターン一覧
/api/daily?project=&days=&from=&to=&exclude= 日別集計
/api/timeline?project=&days= ガント(タスク単位)。ターン単位は /api/session から描く
/api/watch SSE。ログが変わったら change を流す
/api/rev /api/reload 現在の版 / キャッシュ破棄

いずれも &format=csv を付けると CSV を返す(Excel 用に BOM 付き)。

解析の前提

  • ターンの起点は人間の発言だけ。ツール実行結果・システム挿入・サブエージェント(isSidechain)は起点にしない。
  • 再開時に書かれるメタ行(attachment / system / mode / queue-operation)はターンの所要時間に数えない。 セッション全体の開始・終了時刻には反映する。
  • tool_result を含む行は巨大なので JSON パースせず、正規表現で timestamp だけ拾う。
  • 解析結果は (mtime, size) でキャッシュし、追記されただけのファイルは増えたぶんだけ読み足す (SessionParser.read())。書きかけの行は消費せず次回に回す。先頭と解析済み末尾のバイト列が 変わっていたら書き換えとみなして頭から読み直す。
  • 追記解析は状態を持つので、同じファイルを複数スレッドで同時に解析しない(Entry.lock)。

画面

  • 3ペイン(プロジェクト / タスク一覧 / 詳細)。右ペインは やりとり・日別集計・ガントのタブ。
  • 状態はすべて app.js 冒頭の state オブジェクト。再描画は render*() が #detail-body を作り直す方式。
  • 自動追従(SSE)で作り直すときも、選択・スクロール位置・絞り込み・タブは保つ(refreshFollow())。
  • ガントの軸・背景・枠組みは timeScale / axisSvg / gridSvg / ganttFrame をタスク単位と ターン単位で共有している。
  • /api/timeline は表示範囲より前から続くセッションの全体時間・往復数・ツール数も範囲内に切り詰め、 clipped を立てて返す(作業時間だけ切り詰めると数字が食い違うため)。