Files
chktime/web/style.css
T
yoshikazuandClaude Opus 5 cf17cf3fa0 Claude Code のやりとり時刻ビューア chktime を追加
~/.claude/projects の会話ログ (jsonl) を解析し、タスク(セッション)ごとの
やりとりの時刻を一覧表示するローカル Web アプリ。標準ライブラリのみで動作する。

- プロジェクト / タスク / ターンの3ペイン表示
- ターンごとに 発言時刻・空き時間・初回応答までの待ち・応答時間・完了時刻・
  ツール呼び出し内訳を表示、タイムラインバー付き
- 絶対時刻と経過時間の切替、絞り込み、CSV書き出し
- ファイルの更新時刻+サイズでの解析キャッシュ、tool_result 行はパースを省略
- デスクトップ用の起動 (pythonw) / 停止 (stop.cmd) スクリプト

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 15:10:48 +09:00

165 lines
5.3 KiB
CSS

:root {
--bg: #14161a;
--pane: #1a1d23;
--pane2: #20242c;
--line: #2c313b;
--fg: #e6e9ef;
--dim: #8f98a8;
--accent: #7aa2f7;
--user: #7aa2f7;
--work: #9ece6a;
--idle: #3d4350;
--warn: #e0af68;
--cmd: #bb9af7;
font-synthesis: none;
}
* { box-sizing: border-box; }
body {
margin: 0;
height: 100vh;
display: flex;
flex-direction: column;
background: var(--bg);
color: var(--fg);
font: 13px/1.5 "Segoe UI", "Yu Gothic UI", system-ui, sans-serif;
}
header {
display: flex;
align-items: center;
gap: 12px;
padding: 8px 14px;
background: var(--pane);
border-bottom: 1px solid var(--line);
}
header h1 { margin: 0; font-size: 15px; letter-spacing: .04em; }
header .sub { color: var(--dim); font-size: 11px; }
header .spacer { flex: 1; }
.chk { color: var(--dim); user-select: none; cursor: pointer; }
button, .btn {
background: var(--pane2);
color: var(--fg);
border: 1px solid var(--line);
border-radius: 5px;
padding: 3px 10px;
font: inherit;
font-size: 12px;
cursor: pointer;
text-decoration: none;
}
button:hover, .btn:hover { border-color: var(--accent); color: var(--accent); }
main { flex: 1; display: flex; min-height: 0; }
.pane { display: flex; flex-direction: column; min-width: 0; border-right: 1px solid var(--line); }
#projects { width: 220px; flex: none; resize: horizontal; overflow: hidden; }
#sessions { width: 330px; flex: none; resize: horizontal; overflow: hidden; }
#detail { flex: 1; border-right: none; }
.pane-head {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
font-size: 11px;
letter-spacing: .08em;
color: var(--dim);
text-transform: uppercase;
background: var(--pane);
border-bottom: 1px solid var(--line);
}
.pane-head > span:first-child { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#filter {
flex: 1 1 120px;
min-width: 80px;
background: var(--bg);
border: 1px solid var(--line);
border-radius: 5px;
color: var(--fg);
padding: 3px 8px;
font: inherit;
font-size: 12px;
}
.scroll { flex: 1; overflow: auto; }
/* プロジェクト一覧 */
#project-list { list-style: none; margin: 0; padding: 0; overflow: auto; }
#project-list li { padding: 7px 10px; border-bottom: 1px solid var(--line); cursor: pointer; }
#project-list li:hover { background: var(--pane2); }
#project-list li.sel { background: var(--pane2); box-shadow: inset 3px 0 var(--accent); }
#project-list .p-path { font-size: 12px; word-break: break-all; }
#project-list .p-meta { color: var(--dim); font-size: 11px; }
/* セッション一覧 */
table { width: 100%; border-collapse: collapse; }
#session-table tr { border-bottom: 1px solid var(--line); cursor: pointer; }
#session-table tr:hover { background: var(--pane2); }
#session-table tr.sel { background: var(--pane2); box-shadow: inset 3px 0 var(--accent); }
#session-table td { padding: 6px 10px; vertical-align: top; }
.s-title { font-size: 12.5px; margin-bottom: 2px; }
.s-meta { color: var(--dim); font-size: 11px; display: flex; gap: 10px; flex-wrap: wrap; }
.s-when { white-space: nowrap; }
/* 詳細 */
#detail-body { padding: 0 0 40px; }
.empty, .loading { color: var(--dim); padding: 20px; }
.err { color: #f7768e; padding: 20px; white-space: pre-wrap; }
.sum {
display: flex;
flex-wrap: wrap;
gap: 18px;
padding: 10px 14px;
background: var(--pane);
border-bottom: 1px solid var(--line);
position: sticky;
top: 0;
z-index: 2;
}
.sum div { display: flex; flex-direction: column; }
.sum .k { color: var(--dim); font-size: 10.5px; letter-spacing: .06em; }
.sum .v { font-size: 13px; }
#turns { width: 100%; border-collapse: collapse; }
#turns th {
position: sticky;
top: 0;
background: var(--pane);
border-bottom: 1px solid var(--line);
color: var(--dim);
font-weight: 500;
font-size: 11px;
text-align: left;
padding: 6px 8px;
white-space: nowrap;
z-index: 1;
}
#turns td { padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
#turns tr:hover td { background: var(--pane2); }
#turns .num, #turns .n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
#turns .time { font-variant-numeric: tabular-nums; white-space: nowrap; }
#turns .done { color: var(--dim); }
#turns .d { color: var(--dim); font-size: 11px; margin-right: 1px; }
#turns .msg { width: 40%; min-width: 160px; cursor: pointer; }
#turns .small { color: var(--dim); font-size: 11px; }
#turns .small .u { font-size: 9px; opacity: .65; margin: 0 3px 0 1px; }
#turns .msg .txt { white-space: pre-wrap; word-break: break-word; max-height: 3em; overflow: hidden; }
#turns tr.open .msg .txt { max-height: none; }
#turns .tools { color: var(--dim); font-size: 11px; margin-top: 3px; word-break: break-all; }
.kind { font-size: 10px; padding: 0 5px; border-radius: 3px; border: 1px solid var(--line); color: var(--dim); }
.kind.command { color: var(--cmd); border-color: var(--cmd); }
.kind.resume { color: var(--warn); border-color: var(--warn); }
.int { color: var(--warn); font-size: 11px; }
.ovl { color: var(--cmd); font-size: 11px; cursor: help; }
.bar { display: flex; align-items: center; gap: 2px; height: 12px; min-width: 95px; }
.bar i { display: block; height: 8px; border-radius: 2px; }
.bar .b-idle { background: var(--idle); }
.bar .b-wait { background: var(--user); }
.bar .b-work { background: var(--work); }