$npx -y skills add Soul-Brews-Studio/arra-oracle-skills-cli --skill digMine Claude Code sessions — timeline, gaps, repo attribution, session history. Use when user says "dig", "sessions", "past sessions", "timeline", "what did I work on", or wants to see session history. Do NOT trigger for finding code/projects (use /trace), exploring repos (use /le
| 1 | # /dig - Session Goldminer v2 |
| 2 | |
| 3 | Mine Claude Code session data for timelines, gaps, and repo attribution. No query needed. |
| 4 | |
| 5 | ## Usage |
| 6 | |
| 7 | ``` |
| 8 | /dig # Current repo, 10 most recent |
| 9 | /dig [N] # Current repo, N most recent |
| 10 | /dig --all # All repos, ALL sessions (auto-detect count) |
| 11 | /dig --all [N] # All repos, N most recent |
| 12 | /dig --deep # Deep scan — ALL .jsonl files (not just most-recent per project) |
| 13 | /dig --deep [N] # Deep scan, N most recent |
| 14 | /dig --all --deep # All repos, deep scan — full coverage |
| 15 | /dig --timeline # Day-by-day grouped (current repo) |
| 16 | /dig --all --timeline # Day-by-day grouped (all repos, ALL sessions) |
| 17 | ``` |
| 18 | |
| 19 | ### Deep Mode (#216) |
| 20 | |
| 21 | Standard `/dig` deduplicates by session basename — only showing the most recent file per session. This misses historical sessions, subagent sessions, and worktree sessions. |
| 22 | |
| 23 | `--deep` scans ALL `.jsonl` files across all project directories. Output includes extra fields: |
| 24 | - `toolCalls` — number of tool invocations in the session |
| 25 | - `fileSizeKB` — session file size in KB |
| 26 | - Coverage metadata: `"X of Y sessions"` showing how many were returned vs found |
| 27 | |
| 28 | ### Timezone (#214) |
| 29 | |
| 30 | dig.py v2 auto-detects timezone instead of hardcoding GMT+7: |
| 31 | 1. `MAW_DISPLAY_TZ` env var (e.g., `Asia/Bangkok`, `7`, `America/New_York`) |
| 32 | 2. `TZ` env var |
| 33 | 3. System timezone |
| 34 | 4. Fallback: UTC |
| 35 | |
| 36 | Output metadata includes detected timezone name and offset. |
| 37 | |
| 38 | ## Step 0: Timestamp |
| 39 | |
| 40 | ```bash |
| 41 | date "+🕐 %H:%M %Z (%A %d %B %Y)" |
| 42 | ENCODED_PWD=$(pwd | sed 's|^/|-|; s|[/.]|-|g') |
| 43 | PROJECT_BASE=$(ls -d "$HOME/.claude/projects/${ENCODED_PWD}" 2>/dev/null | head -1) |
| 44 | export PROJECT_DIRS="$PROJECT_BASE" |
| 45 | |
| 46 | # Strip -wt* suffix to find parent project dir |
| 47 | PARENT_ENCODED=$(echo "$ENCODED_PWD" | sed 's/-wt-[^/]*$//') |
| 48 | if [ "$PARENT_ENCODED" != "$ENCODED_PWD" ]; then |
| 49 | PARENT_BASE=$(ls -d "$HOME/.claude/projects/${PARENT_ENCODED}" 2>/dev/null | head -1) |
| 50 | [ -n "$PARENT_BASE" ] && export PROJECT_DIRS="$PROJECT_DIRS:$PARENT_BASE" |
| 51 | fi |
| 52 | |
| 53 | # nullglob-safe worktree scan (both parent and self) |
| 54 | for base in "$PROJECT_BASE" "$PARENT_BASE"; do |
| 55 | [ -z "$base" ] && continue |
| 56 | for wt in "$base"-wt-*(N); do # (N) = zsh nullglob qualifier |
| 57 | [ -d "$wt" ] && export PROJECT_DIRS="$PROJECT_DIRS:$wt" |
| 58 | done |
| 59 | done |
| 60 | ``` |
| 61 | |
| 62 | Encodes `pwd` the same way Claude does (replace `/` and `.` with `-`, prepend `-`) to match the `.claude/projects/` directory naming (e.g. `github.com` → `github-com`). Detects parent project from worktree dirs (strips `-wt-*` suffix) and includes both parent and self worktrees. The `(N)` qualifier prevents zsh crashes when no worktrees exist. |
| 63 | |
| 64 | **With `--all`** (all repos): |
| 65 | ```bash |
| 66 | export PROJECT_DIRS=$(ls -d "$HOME/.claude/projects/"*/ | tr '\n' ':') |
| 67 | ``` |
| 68 | |
| 69 | ## Step 2: Extract Session Data |
| 70 | |
| 71 | Run the dig script. Pass `0` for `--all` (no limit), or N if user specified a count, default 10: |
| 72 | |
| 73 | ```bash |
| 74 | python3 ~/.claude/skills/dig/scripts/dig.py [N] [--deep] |
| 75 | # N=10 (default), N=0 (scan all sessions), N=50 (50 most recent) |
| 76 | # --deep: scan ALL .jsonl files (not just most-recent per basename) |
| 77 | ``` |
| 78 | |
| 79 | ### Deep Mode Display |
| 80 | |
| 81 | When `--deep` is used, add extra columns to the table: |
| 82 | |
| 83 | ```markdown |
| 84 | | # | Date | Session | Min | Repo | Msgs | Tools | Size | Focus | |
| 85 | ``` |
| 86 | |
| 87 | And show coverage in the footer: |
| 88 | |
| 89 | ```markdown |
| 90 | **Coverage**: [returned]/[found] sessions | **Timezone**: [tz_name] (GMT+[offset]) |
| 91 | ``` |
| 92 | |
| 93 | ## Step 3: Display Timeline |
| 94 | |
| 95 | Read the JSON output and display as a table. Sessions are chronological (oldest first). Gap rows (`type: "gap"`) span the session column with `· · ·` prefix: |
| 96 | |
| 97 | ```markdown |
| 98 | ## Session Timeline |
| 99 | |
| 100 | | # | Date | Session | Min | Repo | Msgs | Focus | |
| 101 | |---|------|---------|-----|------|------|-------| |
| 102 | | | | · · · sleeping / offline | | | | | |
| 103 | | 1 | 02-21 | 08:40–09:08 | 28m | oracle-skills-cli | 5 | Wire /rrr to read pulse data | |
| 104 | | | | · · · 45m gap | | | | | |
| 105 | | 2 | 02-21 | 09:55–10:23 | 28m | homelab | 3 | oracle-pulse birth + CLI flag | |
| 106 | | | | · · · no session yet | | | | | |
| 107 | |
| 108 | **Dirs scanned**: [list PROJECT_DIRS] |
| 109 | **Total sessions found**: [count] |
| 110 | ``` |
| 111 | |
| 112 | Column rendering rules: |
| 113 | - **Gap rows**: `| | | · · · [label] | | | | |` — number + date empty, label in Session col |
| 114 | - **Date**: `MM-DD` short format (strip year) |
| 115 | - **Session**: `HH:MM–HH:MM` using `startGMT7` and `endGMT7` (strip date, keep time only) |
| 116 | - **Min**: `[durationMin]m` |
| 117 | - **Repo**: use `repoName` field from dig.py output (resolved via ghq) |
| 118 | - **Msgs**: `realHumanMessages` count |
| 119 | |
| 120 | "Msgs" = real typed human messages (not tool approvals). |
| 121 | |
| 122 | --- |
| 123 | |
| 124 | ## With --timeline: Group by Date |
| 125 | |
| 126 | When `--timeline` flag is pr |