æå120äžã®èªåŸç°å¢ãåããŠããŠããã©ã®Skillãæ¯é±éãã«ããŒã¯ã³ãé£ãç¶ããŠãããã¯ã誰ãæããŠãããŸããã§ããã
Claude Codeã® /usage ãå©ããšãåºãŠããã®ã¯ claude-sonnet-4-6: Â¥3,240 ãšããã¢ãã«å¥ã®åèšé¡ã ãã§ãããå
é±ãã2å²é«ããã¯ãããããã©ã®Skillãåå ããã¯ããããªãããã®ã®ã£ãããåããã®ã usage-breakdown.sh ã§ããtranscript.jsonlãPythonã§ããŒã¹ããSkillã»Agentã»MCPãµãŒããŒããšã®åŒã³åºãåæ°ã Counter ã§éèšããã106è¡ã®ã·ã§ã«ã¹ã¯ãªããã§ãã
ãã®èšäºã§ã¯ããã®ã¹ã¯ãªããã®ä»çµã¿ãšåããæ¹ãå®ã³ãŒããšå®æ°åã§è§£èª¬ããŸãã
ãªããã®ä»çµã¿ãå¹ãã®ã
Claude Codeãèšé²ããŠãããã®ã®æ£äœ
Claude Codeã¯ã»ãã·ã§ã³äžã®å
šæäœã ~/.claude/projects/ 以äžã® .jsonl ãã¡ã€ã«ãžé次æžãåºããŠããŸãã1è¡1ã€ãã³ãã®JSONL圢åŒã§ã1ã»ãã·ã§ã³ïŒ1ãã¡ã€ã«ã§ãããã¡ã€ã«å㯠<project-id>/ ãã£ã¬ã¯ããªä»¥äžã«äžŠã³ãŸãã
1ã¬ã³ãŒãã®éªšæ Œã¯ãããªã£ãŠããŸãã
{
"message": {
"role": "assistant",
"content": [
{
"type": "tool_use",
"name": "Skill",
"input": {
"skill": "pre-completion-self-audit"
}
}
]
}
}
message.content[] ã®äžã« "type": "tool_use" ãããã¯ã䞊ã¶ãname ãã£ãŒã«ããåŒã³åºãããããŒã«åã§ããBashããŒã«ãEditããŒã«ãSkillããŒã«ãAgentããŒã«ãMCPåŒã³åºãââãã¹ãŠãã®åœ¢åŒã§èšé²ãããŠããŸãã
ããã«æ°ã¥ãããšããããããCounterã§éèšããã°äžžèŠãã ããšæããŸãããSkillããŒã«ã®å Žå㯠input.skill ã«ã¹ãã«åãå
¥ã£ãŠãããAgentããŒã«ãªã input.subagent_typeãMCPãµãŒããŒãªã mcp__<server>__<tool> ãšããããŒã«åã®åœåèŠåãã __ åå²ã§ãµãŒããŒåãæœåºã§ããŸããæ§é ãäžè²«ããŠããã®ã§ãããŒãµãŒã¯é©ãã»ã©ã·ã³ãã«ã«æžããŸãã
/usage ãæããŠãããªãããš
Claude Codeã® /usage ã³ãã³ããåºåããã®ã¯ãæéå
ã®ã¢ãã«å¥ã³ã¹ãéèšã§ãã
Model Cost
claude-sonnet-4-6 ¥3,240
claude-opus-4-8 ¥ 892
ããã¯ããã§æçšã§ãããã³ã¹ãã®å èš³ãèŠããªããã©ã®ã»ãã·ã§ã³ã§ãäœã®SkillããäœååŒã°ããŠããŒã¯ã³ã䜿ã£ãã®ããããããŸããã
usage-breakdown.sh ã¯ããŒã¯ã³éã§ã¯ãªãåŒã³åºãåæ°ãéèšããŸããããŒã¯ã³æ°ã®æ£ç¢ºãªéèšã«ã¯APIã¬ã¹ãã³ã¹ã® usage ãªããžã§ã¯ããæŸãå¿
èŠããããŸããïŒã¹ã¯ãªããå
ã³ã¡ã³ã: token æ°ã¯ usage ãªããžã§ã¯ãéèšãå¿
èŠã ãããŸã㯠call count ã§ä»£æ¿ïŒãåŒã³åºãåæ°ã ãã§ããäœãå€ãããã®èŒªéã¯ååã«èŠããŸãã100ååŒã°ããŠããSkillãš1åããåŒã°ããŠããªãSkillã§ã¯ãããŒã¯ã³æ¶è²»ã®ãªãŒããŒãéããŸãã
mtimeãŠã£ã³ããŠã§ãçŽè¿Næ¥ãã«çµã
å
šã»ãã·ã§ã³åãéèšãããšå€ããã°ãæ··å
¥ããŠæ¯èŒãã¶ããŸããã¹ã¯ãªããã¯ãã¡ã€ã«ã® mtime ã§æéçªãåããŸãã
cutoff_ts = (now - datetime.timedelta(days=days)).timestamp()
for path in glob.glob(f"{tr_dir}/*.jsonl"):
mtime = os.path.getmtime(path)
if mtime < cutoff_ts: continue
ããã©ã«ã㯠7dãåŒæ°ã§ 30d ã 14d ã«å€ããããŸãã--short ãã©ã°ãæž¡ããš statusline åãã®1è¡ãµããªã ãåºãŸãã
5015 tool_use across 39 sessions (7d)
ãããmacOSã®ã¹ããŒã¿ã¹ããŒãŠã£ãžã§ããã«æµãã°ãé±ããŸããã§ç©ã¿äžãã£ãŠããç·ã³ãŒã«æ°ãåžžæèŠããŸãã
Counterã§éèšãã4æ¬ã®è»ž
ã¹ã¯ãªãããéèšããã®ã¯4æ¬ã®ã«ãŠã³ã¿ãŒã§ãã
skill_calls = collections.Counter() # SkillããŒã« â input.skill
agent_calls = collections.Counter() # AgentããŒã« â input.subagent_type
mcp_calls = collections.Counter() # mcp__<server>__* â ãµãŒããŒå
plugin_skill_calls = collections.Counter() # plugin:skill 圢åŒã®namespace
tool_calls ãå
šããŒã«ã®ã«ãŠã³ã¿ãŒã§ãäžèš4æ¬ã¯ãã®å
èš³ã§ããSkillã®äžã§ã plugin:skill-name 圢åŒã®ãã®ã¯namespaceããšã«æããââãã®ç²åºŠãå®éã«åœ¹ç«ã¡ãŸããsuperpowers:brainstorming ãš superpowers:research ãå¥ã
ã«æ°ããŠããsuperpowers pluginãéããšããäºå®ããç¥ããããªãå±é¢ãããããã§ãã
å€å®ããžãã¯ã¯åçŽãªåå²ã§ãã
if name == "Skill":
skill_name = inp.get("skill", "?")
if ":" in skill_name:
plugin_skill_calls[skill_name.split(":", 1)[0]] += 1
skill_calls[skill_name] += 1
elif name == "Agent":
st = inp.get("subagent_type", "?")
agent_calls[st] += 1
elif name.startswith("mcp__"):
parts = name.split("__")
if len(parts) >= 2:
mcp_calls[parts[1]] += 1
ã«ãŒãã¯1ãã¡ã€ã«ã1è¡ãã€èªãã§ json.loads ããã ããíì±ãšã©ãŒã¯ try/except ã§ç¡èŠãå
šéšã§30è¡è¶³ããã®éèšã³ã¢ã§ãã
å šäœã®æµã
ã¹ã¯ãªããã®åŠçãããŒãã¢ã¹ããŒå³ã§ç€ºããŸãã
~/.claude/projects/
ââ -Users-<username>/
ââ abc123.jsonl ââ
ââ def456.jsonl ââ⺠mtime >= cutoff? âNOâ⺠ã¹ããã
ââ ghi789.jsonl ââ â
YES
â
jsonl 1è¡ãã€èªã
â
message.content[]
â
type=="tool_use" ã®ãããã¯æœåº
â
ââââââââââââââââŒâââââââââââââââ
â â â
name== name== name starts
"Skill" "Agent" "mcp__"
â â â
input.skill subagent_type __split[1]
â â â
skill_calls agent_calls mcp_calls
â â â
ââââââââââââââââŽâââââââââââââââ
â
Counter.most_common(10)
â
stdout ãžåºå
ã¹ã¯ãªããã®æ§æïŒå š106è¡ïŒ
usage-breakdown.sh ã¯3ã€ã®ããŒãã«åãããŠããŸãã
Part 1: ã·ã§ã«å±€ïŒ1ã16è¡ïŒ
åŒæ°ããŒã¹ã»ãã©ã³ã¹ã¯ãªãããã£ã¬ã¯ããªã®ååšç¢ºèªã»Pythonã¹ã¯ãªãããžã®åãæž¡ããæ ããŸãã
#!/usr/bin/env bash
set -uo pipefail
ARG="${1:-7d}"
TR_DIR="$HOME/.claude/projects/-Users-<username>"
[ -d "$TR_DIR" ] || { echo "(no transcript dir)"; exit 0; }
python3 - "$TR_DIR" "$ARG" <<'PY'
<<'PY' ... PY ã®ãã¢ããã¥ã¡ã³ãã§Pythonã³ãŒããã€ã³ã©ã€ã³ã«åã蟌ãã§ããŸããå€éšã® .py ãã¡ã€ã«ã眮ããã«1ãã¡ã€ã«ã§å®çµãããããã®æ§é ã§ããã€ã³ã¹ããŒã«äžèŠã»ãã¹è§£æ±ºãªãã»ã©ãããåŒãã§ãåãããšããéçšäžã®å©ç¹ããããŸãã
Part 2: åŒæ°è§£æãšæéçªã®èšç®ïŒ18ã28è¡ïŒ
SHORT = arg == "--short"
days = int((arg if arg.endswith("d") else "7d").rstrip("d"))
cutoff_ts = (now - datetime.timedelta(days=days)).timestamp()
--short ãã©ã°ãåå²ãããåŸã7d â 7 ã®æ°å€å€æãendswith("d") ãã§ãã¯ã§ 30d 圢åŒãšçŽç²ãªæŽæ°ã®äž¡æ¹ãåãä»ããŸãã
Part 3: ãã¡ã€ã«èµ°æ»ãšéèšã³ã¢ïŒ37ã73è¡ïŒ
glob.glob ã§JSONLãã¡ã€ã«äžèЧãååŸããmtimeãã£ã«ã¿ãééãããã®ã ããéããŸãã1è¡ã〠json.loads â message.content ã®ãªã¹ãèµ°æ» â tool_use ãããã¯æœåº â 4æ¬ã®Counterãžå ç®ããšãããã€ãã©ã€ã³ã§ãã
for path in glob.glob(f"{tr_dir}/*.jsonl"):
mtime = os.path.getmtime(path)
if mtime < cutoff_ts: continue
total_files += 1
with open(path, "r", encoding="utf-8", errors="replace") as f:
for line in f:
rec = json.loads(line)
msg = rec.get("message", {})
content = msg.get("content")
if not isinstance(content, list): continue
for block in content:
if block.get("type") != "tool_use": continue
name = block.get("name", "")
inp = block.get("input") or {}
tool_calls[name] += 1
# ... 4æ¬ã®åå²
errors="replace" ãæž¡ããŠããã®ã¯ãçšã«å«ãŸããäžæ£ãã€ãã§ãã¡ã€ã«å
šäœã®èªã¿èŸŒã¿ãæ¢ãŸãã®ãé²ãããã§ãã
Part 4: åºåïŒ75ã106è¡ïŒ
--short ãªã1è¡ãµããªãéåžžã¢ãŒããªã most_common(10) ã§äžäœ10ä»¶ãã»ã¯ã·ã§ã³å¥ã«åºåããŸãã
print(f"=== usage breakdown (last {days}d, {total_files} transcripts) ===")
print(f"\ntotal tool_use: {sum(tool_calls.values())}")
if skill_calls:
print(f"\n--- top skills ({len(skill_calls)} unique) ---")
for sk, n in skill_calls.most_common(10):
print(f" {n:>5} {sk}")
{n:>5} ã®å³å¯ããã©ãŒãããã§ãæ¡æ°ãéã£ãŠã瞊æ£ãæããŸããã¿ãŒããã«ã§èŠããšãã®èŠèªæ§ã®ããã®çް工ã§ãã
å®éã«7æ¥åãæµããåºå
=== usage breakdown (last 7d, 39 transcripts) ===
total tool_use: 5015
--- top tools ---
3656 Bash
508 Edit
304 Read
240 Write
37 Monitor
35 ToolSearch
23 AskUserQuestion
20 TaskUpdate
19 mcp__plugin_playwright_playwright__browser_take_screenshot
16 mcp__claude-in-chrome__navigate
--- top skills (3 unique) ---
3 artifact-design
1 dataviz
1 claude-api
--- top agents (1 unique) ---
1 code-reviewer
--- top MCP servers (4 unique) ---
79 plugin_playwright_playwright
45 claude-in-chrome
15 claude_ai_Google_Calendar
2 claude_ai_Gmail
7æ¥éã§39ã»ãã·ã§ã³ãããŒã«åŒã³åºãç·æ°5,015åãBashã3,656åïŒ72.9%ïŒã§ãã³ããéŠäœãEditã508åã§ç¶ããŸããSkillãšAgentã¯æã£ãããå°ãªãââãã®æ°åãäœãæå³ãããã¯æ¬¡ã®ç« ã§æããŸãã30æ¥åã«åºãããšçµµãå€ãããŸãã
=== usage breakdown (last 30d, 203 transcripts) ===
total tool_use: 21215
--- top agents (7 unique) ---
94 general-purpose
22 Explore
6 reviewer
...
--- top MCP servers (5 unique) ---
1571 claude-in-chrome
81 plugin_playwright_playwright
54 computer-use
30æ¥ã¹ãã³ã§èŠããš claude-in-chrome ã1,571åââ鱿ç®ã§çŽ366åã§ããAgentã§ã¯ general-purpose ã94åïŒé±æç®23åïŒã7æ¥çªã§ã¯èŠãã«ããã£ãå®åžžçãªéããã30æ¥çªã§æµ®ãã³äžãããŸãã
ãã®ã®ã£ããââççªã§ã¯èŠãããé·çªã§åããŠèŠããéãââãã宿å®è¡ãããèªååããã¿ã®ãã¥ãŒãã³ã°ãã€ã³ãã«ãªããŸãã
å®è£ ã®è©³çްââããªãããæžããããæã
äºé try/except ã®èšèšæå³
ã¹ã¯ãªããã®éèšã³ã¢ïŒ37ã73è¡ïŒãèªããšãtry/except ã2å±€ã«ãªã£ãŠããããšã«æ°ã¥ããŸãã
for path in glob.glob(f"{tr_dir}/*.jsonl"):
try:
mtime = os.path.getmtime(path)
if mtime < cutoff_ts: continue
total_files += 1
with open(path, "r", encoding="utf-8", errors="replace") as f:
for line in f:
try:
rec = json.loads(line)
except: continue # â å
åŽ
...
except Exception:
continue # â å€åŽ
å
åŽã® try/except 㯠json.loads ã ããå
ã¿ãŸããJSONLã¯1è¡1ã¬ã³ãŒãã®åœ¢åŒãªã®ã§ã1è¡ãããŒã¹å€±æããŠãæ®ãã®è¡ã¯èªã¿ç¶ããããŸããcontinue ã§æ¬¡ã®è¡ãžé£ã¶ã ãã§ãã
å€åŽã® try/except Exception ã¯ãã¡ã€ã«åäœã®äŸå€ãåããŸããããŒããã·ã§ã³ãšã©ãŒããã¡ã€ã«ãåé€ããããmtimeååŸãã³ã±ãââã©ããèµ·ããŠã continue ã§ãã®ãã¡ã€ã«ãã¹ãããããæ¬¡ã®ãã¡ã€ã«ãžé²ã¿ãŸããtotal_files ã®ã«ãŠã³ããå€åŽã® try ã®äžã«ããã®ã¯ãã®ããã§ãããã¡ã€ã«ãæ£åžžã«éããæã ãã«ãŠã³ããããã
2å±€ã«ããçç±ã¯ãç²åºŠã®éãã§ããããã®ãã¡ã€ã«ãèªããªãããšããã®è¡ãJSONã§ãªããã¯å¥ã®é害ã§ãåŠçã®ç¶ç¶ç¯å²ãéããŸãã1å±€ã«ãŸãšããŠãã¡ã€ã«ããš continue ããŠããããå
é è¡ãå£ãã1ãã¡ã€ã«ã§æ®ãã®äœåè¡ããäžžããšæšãŠãããšã«ãªããŸãã
isinstance ã¬ãŒãã®åŸ¹åº
47è¡ç®ã«ã¯ãäžèŠãã©ãèŠããã¬ãŒããå ¥ã£ãŠããŸãã
msg = rec.get("message", {}) if isinstance(rec.get("message"), dict) else {}
rec.get("message", {}) ã ãã§ããããã«èŠããŸãããããã¯è¶³ããŸãããtranscript.jsonlã«ã¯ "message": null ãšããã¬ã³ãŒããååšããŸããnull ã¯JSONãšããŠã¯æ£åœãªã®ã§ json.loads ãééããŸãããPythonã§ã¯ None ã«ãªããŸãã{}.get("content") ã¯åé¡ãªãã§ãããNone.get("content") 㯠AttributeError ã§èœã¡ãŸããisinstance ã§ dict ã§ããããšã確èªããŠãã .get() ãåŒã¶ããšãããã¿ãŒã³ãå
¥ããªããšãnull ã¬ã³ãŒããèžããã³ã«å
åŽã® except ãæŸãç¶ããŸãã
åãçç±ã§54è¡ç®ã«ãé²åŸ¡ããããŸãã
inp = block.get("input") or {}
block.get("input") 㯠None ãè¿ãããšããããŸããNone or {} 㯠{} ã«ãªãã®ã§ã以éã® inp.get("skill", "?") ãå®å
šã«åããŸããif inp is None: inp = {} ãšæžãããçãããNoneãšç©ºdictã®äž¡æ¹ã«å¯ŸããŠç©ºdictã䜿ãããããšããæå³ã1è¡ã§äŒãããŸãã
ããã«50è¡ç®ã
for block in content:
if not isinstance(block, dict): continue
content 㯠list ã ãšç¢ºèªæžã¿ã§ããããã®èŠçŽ ãå
šãŠ dict ãšã¯éããŸãããClaude Codeã®transcriptãçºãããšãcontent ãæååã®ãªã¹ãã«ãªã£ãŠããã¬ã³ãŒããçšã«åºãŠããŸãïŒããã¹ããããã¯ãšããŒã«ãããã¯ãæ··åšããŠããå Žåã®äžéšïŒãèŠçŽ ããšã« isinstance(block, dict) ã確èªããŠãdictã§ãªããã°ã¹ãããããã®ãå
ç¢ã§ãã
ãã¢ããã¥ã¡ã³ãã®ã¯ã©ãŒããåœç¶±
16è¡ç®ãæ³šææ·±ãèŠãŠãã ããã
python3 - "$TR_DIR" "$ARG" <<'PY'
<<'PY' ã®ã·ã³ã°ã«ã¯ã©ãŒãã絶察ã«å¿
èŠã§ãã<<PYïŒã¯ã©ãŒããªãïŒã«ããŠããŸããšããã¢ããã¥ã¡ã³ãã®å
åŽã§ã·ã§ã«ã®å€æ°å±éãèµ°ããŸããPythonã³ãŒãäžã« $tr_dir ãšããæžãæ¹ãäžç®æã§ãããã°ãã·ã§ã«ãå±éããããšããŠæå³ããªãæååã«åããŸããf"{tr_dir}/*.jsonl" ã¯Pythonã®f-stringãªã®ã§$ã¯ãããŸãããã$1ã${HOME}ã«èŠããæååããããšå£ããŸãã<<'PY'ã®ããã«ããªãã¿ãã¯ã©ãŒãã§å²ããšããã¢ããã¥ã¡ã³ãå
ã®å±éãå®å
šã«ç¡å¹åãããPythonã³ãŒãããã®ãŸãŸã®æååãšããŠpython3ã®æšæºå
¥åã«æž¡ãããŸãã
ãã¢ããã¥ã¡ã³ãã§Pythonãã€ã³ã©ã€ã³ã«åããå©ç¹ã¯ã1ãã¡ã€ã«ã§å®çµããããšã§ããã¹ã¯ãªãããã©ããã®ãã£ã¬ã¯ããªã«çœ®ããŠPATHãéããŠããã°ããã ãã§åãã~/.claude/scripts/usage-breakdown.sh ãlaunchdããåŒã¶å ŽåãPythonãã¡ã€ã«ã®ãã¹ãå¥é管çããå¿
èŠããããŸãããå€éšãã¡ã€ã«äŸåã¯ããã®ãã¡ã€ã«ãæ¶ãããç§»åããç¬éã«é»ã£ãŠå£ããŸãã
plugin namespace ã®åé¢ããžãã¯
59ã61è¡ç®ã®ãããã¯ã¯å°ããã§ãããå®éã«äœ¿ã£ãŠã¿ããšäŸ¡å€ãããããŸãã
if ":" in skill_name:
plugin_skill_calls[skill_name.split(":", 1)[0]] += 1
skill_calls[skill_name] += 1
split(":", 1) ã® 1 ãéèŠã§ããæå€§å岿°ã1ã«éå®ããããšã§ãexpo:eas-hosting ãªã ["expo", "eas-hosting"] ã«ãªããŸããã仮㫠expo:eas:hosting ãšãã圢ã®ã¹ãã«åããã£ãŠã ["expo", "eas:hosting"] ã«ãªããnamespaceéšåã ããæ£ç¢ºã«åãåºããŸãã
plugin_skill_calls ãš skill_calls ã®äž¡æ¹ã«ã«ãŠã³ããå
¥ããŠããã®ã¯éèšã®è»žãåããããã§ããskill_calls ã¯åå¥ã¹ãã«åããplugin_skill_calls ã¯namespaceãéèšããŸãã鱿¬¡ã¬ããŒãã§ãexpoãã©ã°ã€ã³ãåèš12å䜿ã£ãããšããæããæ°åãšããexpo:eas-hostingã5åãexpo:expo-upgradeã4åããšããå
èš³ããã©ã¡ããæå
ã§åŒããŸãã
--short ãã©ã°ãšã¹ããŒã¿ã¹ããŒçµ±å
--short ã¢ãŒããè¿ã1è¡ã¯ãmacOSã®ã¹ããŒã¿ã¹ããŒãŠã£ãžã§ããïŒxbarãÃbersichtçïŒããçŽæ¥åŒãã§è¡šç€ºããããã®ãã®ã§ãã
5015 tool_use across 39 sessions (7d)
launchdã®plistã§5åããã«ã¹ã¯ãªãããèµ°ãããçµæã /tmp/usage-short.txt ã«æžãåºããŠããŠã£ãžã§ããããããèªããšããæ§æã§ãããŠã£ãžã§ããåŽã§ãã¡ã€ã«ãèªãã ããªã®ã§ãClaude Codeã®ã»ãã·ã§ã³äžã«å®æèµ·åããŠãç«¶åããŸããã--short ãã©ã°ããªããã°åºåã10è¡ä»¥äžã«ãªãããŠã£ãžã§ããã«åã蟌ãã«ã¯é·ãããŸããçšéå¥ã«åºå圢åŒãåãæ¿ãããªãã·ã§ã³ãæåããèšèšã«å
¥ããŠãããšãåŸããã¯ãŸããŸããã
ç§ãè©°ãŸã£ã話
è©°ãŸãâ ïŒerrors="replace" ãå
¥ããŠããªãã£ããå
šãã¡ã€ã«ãéããªãã£ã
æåã®ããŒãžã§ã³ã«ã¯ errors="replace" ããããŸããã§ããã
with open(path, "r", encoding="utf-8") as f: # â errorsãªã
ããã§èµ°ããããšãäžéšã®transcriptãã¡ã€ã«ã§ UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position ... ãåºãŠã¹ã¯ãªãããæ¢ãŸããŸãããã¡ã€ã«ãå€åŽã® try/except Exception ã§å²ãã§ããã®ã§æ¢ãŸãã¯ããŸãããããã®ãã¡ã€ã«å
šäœã continue ã§ã¹ããããããŸãã
åå ã¯transcriptã«PNGç»åã®base64ããŒã¿ãå«ãŸããŠããå Žåã§ããClaude Codeã§ã¹ã¯ãªãŒã³ã·ã§ããã䜿ãã»ãã·ã§ã³ã§ã¯ãç»åãtranscript.jsonlã«base64ãšã³ã³ãŒãã§æžã蟌ãŸããŸããbase64æååèªäœã¯ASCIIãªã®ã§UTF-8ã§èªããŸãããçšã«ãã€ããªãæ··å
¥ããäžæ£ãªJSONLãçæãããããšããããŸããerrors="replace" ãæž¡ããšãèªããªããã€ãã U+FFFDïŒREPLACEMENT CHARACTERïŒã«çœ®æããŠèªã¿é²ããŸããJSONå€ã®äžã®å£ãããã€ãã眮ææåã«ãªã£ãŠããjson.loads ã®ããŒã¹å¯Ÿè±¡ã¯ãã®è¡å
šäœãªã®ã§ãæ§é ã厩ããŠããªããã°ããŒã¹ã¯éããŸããæ§é ã厩ããŠããã°å
åŽã® except: continue ãæŸããŸãã
errors="replace" ã¯æ
å ±ã®æ¬ æã蚱容ãã代ããã«ããã¡ã€ã«å
šäœã®èªã¿èŸŒã¿ãå®èµ°ãããéžæã§ããusageéèšã§ã¯1ãã€ãã®ç²ŸåºŠãããå
šãã¡ã€ã«ãèµ°æ»ã§ããããã®æ¹ã倧äºãªã®ã§ããã®å€æã¯æ£ããã£ãã§ãã
è©°ãŸãâ¡ïŒmtimeçªããåœéœæ§ãã倧éã«è¿ãã
ã¹ã¯ãªããããã°ãã䜿ã£ãŠãããšãçŽè¿7æ¥ã®éèšãªã®ã«ãæããã«å€ãã»ãã·ã§ã³ã®ããŒã¿ãæ··å ¥ããŠããããšæ°ã¥ãæ¥ããããŸãããåºåã®ç·ä»¶æ°ãæ®æ®µã®3ã4åã«èšããã§ããŠããããå 容ãèŠããš2é±éåã®ãããšããå«ãŸããŠããŸãã
åå ã¯ããã¯ã¢ãããœããã®ãªã¹ãã¢ã§ãããTime Machineãrsyncã§ããŒã ãã£ã¬ã¯ããªãåæãããšã~/.claude/projects/ 以äžã®ãã¡ã€ã«ãäžæžãã³ããŒãããŸããã³ããŒã¯ãã¡ã€ã«ã®äœææå»ãå€ããŸãããmtimeããã³ããŒããæå»ãã«ãªããŸããäžèº«ã¯å€ãã»ãã·ã§ã³ã®transcriptãªã®ã«ãmtimeã¯ä»æ¥ã®æ¥æã§ãã
cutoff_ts = (now - datetime.timedelta(days=days)).timestamp()
for path in glob.glob(f"{tr_dir}/*.jsonl"):
mtime = os.path.getmtime(path)
if mtime < cutoff_ts: continue
mtimeãã£ã«ã¿ã¯ããã®ãã¡ã€ã«ãæåŸã«æžãæããæå»ããèŠãã®ã§ãã³ããŒã«ãã£ãŠmtimeãæŽæ°ããããã¡ã€ã«ã¯ãã¹ãŠãææ°ãæ±ãã«ãªããŸãã164ãã¡ã€ã«ãäžæ¬ã§åœéœæ§ã«ãªãã5çªé£ç¶ã§ãæ°èŠãŒããªã®ã«æ°åãèšããããšããç¶æ ãç¶ããŸããã
æ ¹æ¬çãªè§£æ±ºã¯ãtranscriptå
ã® æ¥æ: ãã£ãŒã«ããããŒã¹ããŠå®éã®ã»ãã·ã§ã³æå»ã§å€å®ããããšã§ãããã ãããã¯å®è£
ã³ã¹ããäžãããããçŸåšã¯30æ¥çªã§éèšããŠé·æãã¬ã³ããèŠããšããã¯ãŒã¯ã¢ã©ãŠã³ããæ¡çšããŠããŸããäžæ¬ã³ããŒã§åœéœæ§ãæ··å
¥ããŠãã30æ¥åã®ç·éã®äžã§ã¯çµ±èšçãªå€ãå€ã«åãŸããŸãã7æ¥çªã䜿ãå Žåã¯ãããã¯ã¢ããçŽåŸã®æ°æ¥ã¯æ°åãä¿¡çšããªããšããéçšã«ãŒã«ãèªåã§æã€ãããããŸããã
ãã®åé¡ã«æ°ã¥ããªããŸãŸãå é±ã¯Skillã100ååŒã°ããããšããæ°åãä¿¡ããŠplistã®StartIntervalãå€ããŠããããå®éã«ã¯å€æŽãäžèŠãªå Žæãè§Šã£ãŠãããããããŸãããããŒã«ã®åºåãéµåã¿ã«ããåã«ããã®æ°åã®ååŸæ¹æ³ã¯äœã«åœ±é¿ããããããäžåºŠçãããšããã¯ã»ãå¿ èŠã ãšåŠã³ãŸããã
è©°ãŸãâ¢ïŒjson.loads ã®äŸå€ããã©ã³ã±ãããã£ãããããå¯äœçšãèŠããªããªã£ã
å
åŽã® except: continue 㯠except Exception: continue ã§ã¯ãªãã裞㮠except: ã§ãããã㯠BaseException ãå«ãå
šäŸå€ãæãŸããŸããKeyboardInterrupt ã SystemExit ãå
šéšé£²ã¿èŸŒã¿ãŸãã
æåã¯ããã§è¯ããšæã£ãŠããŸãããããããã°äžã« Ctrl+C ã§ã¹ã¯ãªãããæ¢ããããšãããæ¢ãŸããªãããšããããŸãããKeyboardInterrupt ãå
åŽã® except: ã«æãŸã£ãŠ continue ãããŠããã®ã§ããã«ãŒããé²ãã§æ¬¡ã®ãã¡ã€ã«ã«å
¥ãã°å€åŽã® try ã except ãè¶ããããŸããã§ããã
çŽãæ¹ã¯å
åŽã except (json.JSONDecodeError, ValueError): continue ã«çµãããšã§ããjson.loads ã倱æããçç±ã¯å®è³ªçã« JSONDecodeErrorïŒPython 3.5以éïŒããçšã« ValueError ã ãã§ãããã以å€ã®äŸå€ïŒKeyboardInterrupt ãå«ãïŒã¯å
åŽã§æãŸãããå€åŽã® except Exception ã«äŒæããããããŠãŒã¶ãŒã«å±ãããŸããçŸåšã®ã³ãŒãã§ã¯ except: ã®ãŸãŸã«ãªã£ãŠãããããã¯ä»ã§ãæ¹åã®äœå°ããããšæã£ãŠããŸããå®éã®éçšã§ã¯åé¡ãåºãããšã¯ãããŸãããããCtrl+C ãå¹ããªãå¯èœæ§ãããããšããæåã¯ç¥ã£ãŠããã¹ãã§ãã
è©°ãŸãâ£ïŒmost_common ã®è¿ãå€ããœãŒããçŽãããšããŠäºåºŠæéã ã£ã
éèšçµæãåºã段éã§ãskill_calls.most_common(10) ã®è¿ãå€ãããã« sorted() ã§äžŠã¹æ¿ããããšããããšããããŸãããã¢ã«ãã¡ãããé ã§ãåºãããã£ãããã§ãã
# ãã£ãŠããŸã£ããã¿ãŒã³
for sk, n in sorted(skill_calls.most_common(10), key=lambda x: x[0]):
print(f" {n:>5} {sk}")
ãã㯠most_common(10) ãå
ã«åã£ãŠããååé ã«äžŠã¹çŽãã®ã§ããå
šäœã®äžäœ10ä»¶ãã¢ã«ãã¡ãããé ã«ããããšããçµæã«ãªããŸããäžèŠåé¡ãªãããã§ããããé »åºŠ11äœã®Skillãååé ã§äžäœã«æ¥ãã¯ããªã®ã«åºãªãããšããæ··ä¹±ãèµ·ããŸãã
most_common() ã®åœ¹å²ã¯ã«ãŠã³ã¿ãŒãé »åºŠéé ã§è¿ãããšã§ããåŒæ° 10 ã¯é »åºŠäžäœ10ä»¶ã ãã«çµãããã®åŸã§ãœãŒããããªããmost_common() ã«åŒæ°ãæž¡ããã«å
šä»¶åã£ãŠãããœãŒãããããæåããç®çã«åã£ãå¥ã®ããŒã¿æ§é ã䜿ãã¹ãã§ããã
ãã®ä»¶ã¯1è¡ã®çŽãæ¹ã§æžã¿ãŸãããããCollectionsã®Counterã¯ã©ãåããŠãããããçè§£ããã«äœ¿ã£ãŠããããšãåé¡ã§ãããCounter ã¯å
éšçã«ã¯ dict ã®ãµãã¯ã©ã¹ã§ãmost_common() ã¯ããŒãã䜿ã£ã O(n log k) ã®æäœã§ãã100äžä»¶ãã£ãŠãäžäœ10ä»¶ã¯é«éã«è¿ããŸããéã«å
šä»¶ååŸããèªåã§ãœãŒãããã®ã¯ O(n log n) ã«ãªããŸããèŠæš¡ãå°ãããã°èª€å·®ã§ãããå°æ¥transcriptãå¢ãããšãã«å·®ãåºãŸãã
è©°ãŸãâ€ïŒMCP ãµãŒããŒåã空æåã«ãªãã±ãŒã¹ããã£ã
mcp__<server>__<tool> ã®åœ¢åŒãããµãŒããŒåãåãåºãéšåã§ãã
elif name.startswith("mcp__"):
parts = name.split("__")
if len(parts) >= 2:
mcp_calls[parts[1]] += 1
if len(parts) >= 2: ã®ã¬ãŒããå€ããŠããåæããŒãžã§ã³ã§ãmcp__ ã ãã®ããŒã«åïŒparts ã ["mcp", ""]ïŒãæ··å
¥ãããšããparts[1] ã空æååã«ãªã£ãŠ mcp_calls[""] += 1 ãç©ã¿äžãã£ãŠããŸãããåºåã« " 23 " ãšãã空ã®ãšã³ããªãåºãŠããŠæåã¯äœã ãããããŸããã§ããã
空ããŒã«åãçºçããåå ã¯äžå®å
šãªã¬ã³ãŒãã§ãããŸãã«MCPã®ã¬ã¹ãã³ã¹ãäžæãããŠããŒã«åãéäžã§åããtranscriptãçæãããŸããlen(parts) >= 2 ã®ã¬ãŒãã§åŒŸãã®ãäžçªã·ã³ãã«ãªå¯ŸåŠã§ããããå
¥ããã空ãšã³ããªã¯æ¶ããŸãããããã«èšãã° parts[1] ã空æåã®å Žåãã¹ããããããã®ã§ãæ¬æ¥ã¯ if len(parts) >= 2 and parts[1]: ãšãã¹ãã§ãããçŸåšã®ã³ãŒãã§ã¯ parts[1] ã空ã®å Žåã¯åŒŸãããã« mcp_calls[""] ã«ãªããŸãããåºåã§ã¯ most_common(10) ã«å«ãŸããã»ã©ã®ä»¶æ°ã«ã¯ãªã£ãŠããªãã®ã§å®å®³ã¯ãããŸããã
ã€ãŸãããã€ã³ã
åã®ç« ã§è©³è¿°ãã5ä»¶ïŒUnicodeDecodeErrorã»mtimeã®åœéœæ§ã»è£žã®except:ã»most_commonã®äºåºŠæéã»ç©ºMCPãµãŒããŒåïŒä»¥å€ã«ãå®éã®éçšã§ã¶ã€ãã£ã现ããçœ ããŸãšããŸãã
-
TR_DIRãããŒãã³ãŒããããŠããŠä»äººã®ç°å¢ã§åããªããã¹ã¯ãªãã13è¡ç®ã¯
TR_DIR="$HOME/.claude/projects/-Users-yourname"ã®ããã«ãŠãŒã¶ãŒåãåãŸã£ãŠããŸããå¥ã¢ã«ãŠã³ããå¥ãã·ã³ã«æã¡èŸŒãããšããŠåããªãã£ãã-Users-$(whoami)ã§è§£æ±ºã§ããŸããããããããã£ã¬ã¯ããªåã®ã¹ã©ãã·ã¥ããã€ãã³çœ®æãããŠããåœåèŠåãç¥ããªããšåå ãã€ãããŸããã -
--shortãã©ã°ã𿥿°æå®ãæä»ã«ãªã£ãŠãããåŒæ°ã¯$1ã®1ã€ã ããåãåãã®ã§usage-breakdown.sh --short 30dã®ããã«æžããŠã30dã¯ç¡èŠãããŸããã30æ¥åã®1è¡ãµããªã欲ããããšããçµã¿åãããçŽ çŽã«æžããªããå®éã¯usage-breakdown.sh 30dã®åºåã®1è¡ç®ã ãåãããã¹ã¯ãªããåŽã$1/$2察å¿ã«æ¹é ãããããããŸããã -
launchdããåŒã¶ãš
python3ã®PATHãéã£ãŠããªããlaunchdã§èµ·åããã¹ã¯ãªããã¯/usr/bin:/bin:/usr/sbin:/sbinã ãã®PATHã§åããŸããhomebrewãnvmãå ¥ããpython3ã¯/usr/local/binã/opt/homebrew/binçã«ãããããçŽ ã®launchd plistã§ã¯python3: command not foundã«ãªããŸããplistã®<key>EnvironmentVariables</key>ã«<key>PATH</key>ãæç€ºããããã¹ã¯ãªããã®å é ã§/usr/bin/env python3ã§ãªã絶察ãã¹ïŒ/opt/homebrew/bin/python3ïŒãæå®ããå¿ èŠããããŸãã -
StartInterval倿ŽåŸã«plistãåããŒãããŠããªãã£ãã
~/Library/LaunchAgents/com.lily.usage-breakdown.plistã®StartIntervalã300ïŒ5åïŒãã1800ïŒ30åïŒã«çŽããŠããlaunchctl unload+launchctl loadãå¿ãããšå€ãèšå®ã®ãŸãŸåãç¶ããŸãã倿Žãå¹ããŠãããã¯launchctl list com.lily.usage-breakdownã§LastExitStatusãšæ¬¡åèµ·åæå»ã確èªããã®ã確å®ã§ãããã¡ã€ã«ã ãæžãæããæ°ã«ãªã£ãŠãå®ã¯å€ãã£ãŠããªãã£ãââãšããç¶æ ã«æ°æ¥æ°ã¥ããªãã£ãããšããããŸãã -
glob.globã®è¿ãé ãä¿èšŒãããªãããã¡ã€ã«ã·ã¹ãã ã«ãã£ãŠäžŠã³é ãå€ãããŸããéèšçµæã¯åèšãåãã§ãããã¡ã€ã«ãåŠçããé åºãå€ãããštotal_filesã®ã«ãŠã³ãã«ã¯åœ±é¿ããŸããïŒã«ãŠã³ã¿ãŒã¯çޝç©ãªã®ã§ïŒãããããã°ã§ç¹å®ã®ãã¡ã€ã«ãäœçªç®ã«åŠçãããŠããã远ããšãã«é åºãæ¯åå€ããã®ã§æ··ä¹±ããŸãã確å®ã«é åºãåºå®ããããªãsorted(glob.glob(...))ãšæç€ºããæ¹ãå®å šã§ãã -
most_common(10)ã®äžéãåºå®ã§ãSkillãå¢ãããšäžäœãèŠããªããªããç°å¢ã«ã€ã³ã¹ããŒã«ãããŠããSkillã50ãè¶ ãããšã10äœä»¥äžã®SkillãéèšããèŠããªããªããŸãã鱿¬¡ãã¥ãŒãã³ã°ã®ç®çãªãã100å以äžã®ãã®ããšããéŸå€ã§çµãæ¹ãçŸå®çã§ããçŸåšã®ã³ãŒãã¯åºåæ°ãããŒãã³ãŒããªã®ã§ãç°å¢ãè²ã€ã«ã€ããŠèŠããæ å ±ãåãæšãŠãããŸãã -
7æ¥çªã®æ°åã ããèŠãŠplistã倿ŽããŠããŸã£ãã7æ¥éã®ãã©ã³ã¹ã¯ãªããæ°ãå°ãªãé±ïŒé£äŒæããªã©ïŒã¯çµ¶å¯Ÿæ°ãäœãèŠããŸããã
claude-in-chromeã20åããåŒã°ããŠããªããã¯ãæ®æ®µã140åã®é±ããèŠããšãä»é±ããŸããŸå°ãªãã£ãã ããã§ãã30æ¥çªãšã®æ¯èŒãå¿ ãã»ããã«ããªããšãå€ãå€ã§å€æããŠäžèŠãªãã¥ãŒãã³ã°ãããŠããŸããŸãã -
contentããªã¹ãã§ãªãæååã«ãªã£ãŠããã¬ã³ãŒãã®ã¬ãŒããå¿ãããisinstance(content, list)ã®ãã§ãã¯ã¯å ¥ã£ãŠããŸãããæåã®ããŒãžã§ã³ã§ã¯msg.get("content")ã ãã§æžãŸããŠããããã«æååãå ¥ã£ãŠãããšãfor block in content:ãcharã®å埩ã«ãªã£ãŠããŸããŸããã1æåãã€isinstance(block, dict)ãå€å®ããŠå šéšèœãšãã®ã§å®å®³ã¯ãããŸããã§ããããã«ãŒãåæ°ãç¡é§ã«å¢ããŠãã¡ã€ã«ãµã€ãºã倧ããtranscriptã§äœæã§ããã»ã©é ããªããŸããã -
ã¹ã¯ãªããã®åºåãä¿åããŠããªãã£ãã®ã§æç³»åæ¯èŒãã§ããªãã£ãã
usage-breakdown.sh 7dãæã§å©ããŠçºããã ãã§ã¯ãå é±ããå¢ãããæžã£ãããèšæ¶é Œã¿ã«ãªããŸããlaunchdã§é±1å/tmp/usage-weekly-$(date +%Y-%m-%d).txtã«æžãåºãããã«å€ããŠããããå æã¯MCPãé±550åã ã£ãã®ã仿ã¯280åã«åæžããããšããæ¯èŒã客芳çã«ã§ããããã«ãªããŸããã -
Skillåã«
:ãå«ãå Žåã®splitãplugin_skill_callsã«ã ãå ¥ãæå³ã誀èªãããplugin_skill_callsãšskill_callsã®äž¡æ¹ã«ã«ãŠã³ããå ¥ããŠããã®ã¯éèšè»žãåããããã§ãããæåã¯ãã°ã ãšæã£ãŠskill_callsãžã®å ç®ãæ¶ããŸãããçµæãšããŠåå¥ã¹ãã«åã®éèšãå šãŠ?ã«ãªãããSkillãåŒã°ããŠããã®ã«ååãå šéšäžæããšããåºåãåºãŠæ··ä¹±ããŸãããã³ãŒããèªããšãã¯å€å®åå²ã®elifã§ãªãifã䜿ãããŠããçç±ã確èªããã®ã倧åã§ãã
ãã¹ããã©ã¯ãã£ã¹
1. ãã¢ããã¥ã¡ã³ãã®ããªãã¿ã¯å¿ ãã·ã³ã°ã«ã¯ã©ãŒãã§å²ã
<<'PY' ãšæžããªããšPythonã³ãŒãå
ã« $ ãå«ãŸãããšãïŒf-stringã $HOME ã«èŠããéšåïŒã§ã·ã§ã«å±éãèµ°ããŸãã<<PY ãšæžããŠåããŠãããã¡ã¯ããŸããŸã§ã$tr_dir ãšãã倿°åãå¢ãããç¬éã«å£ããŸããã€ã³ã©ã€ã³Pythonã¹ã¯ãªãããæ±ãå Žåã®ã«ãŒã«ãšããŠåºå®ããŠãããŸãã
2. open() ã¯åžžã« errors="replace" ãæž¡ã
ãã°ã»transcriptã®é¡ã¯ãã€ããªãæ··å
¥ããå¯èœæ§ããããŸãïŒã¹ã¯ãªãŒã³ã·ã§ããã®base64ãå€éšã³ã³ãã³ãã®ã³ããŒçïŒãerrors="replace" ã¯ããŒã¿ã®ç²ŸåºŠããããå
šãã¡ã€ã«ãèµ°æ»ã§ãããããåªå
ããéèšç³»ã®åŠçã«åããŠããŸããå®èµ°çãäžããããã®äžæã§ãã
3. try/except ã¯ç²åºŠããšã«2å±€ã«åãã
ããã¡ã€ã«åäœã®å€±æããšã1è¡åäœã®å€±æãã¯ç¶ç¶ç¯å²ãéããŸããå€åŽã¯ãã¡ã€ã«ã¹ããããå åŽã¯è¡ã¹ãããââãã®2å±€æ§é ãæåããèšèšã«å ¥ãããšããããã°æã«ãäœè¡ç®ãå£ããŠãããããšãã©ã®ãã¡ã€ã«ãå£ããŠãããããåé¢ããŠè¿œããŸãã
4. isinstance ã¬ãŒãã¯èŠãç®ããã©ããŠãçç¥ããªã
rec.get("message", {}) 㯠"message": null ã匟ããŸãããisinstance(rec.get("message"), dict) ã®1è¡ããNoneã§AttributeErrorãåºãçµè·¯ãå®å
šã«å¡ããŸããtranscript.jsonlã¯ä»æ§å€ã®å€ãæ®éã«å«ãŸãããããåãä¿¡é Œããæ¯å確èªããã®ãå®å
šã§ãã
5. Noneãšç©ºdictãåæã«å¯ŸåŠãã or {} ãã¿ãŒã³
inp = block.get("input") or {}
if inp is None: inp = {} ããçããæå³ãæç¢ºã§ããor æŒç®åã¯falsyãªå€ïŒNoneã»ç©ºdictã»ç©ºæååïŒãå
šãŠ {} ã«çœ®ãæããã®ã§ãåŸç¶ã® .get() ãå®å
šã«åŒã¹ãŸãã
6. éèšè»žãè€æ°ã®Counterã«æã€
skill_callsïŒåå¥åïŒãš plugin_skill_callsïŒnamespaceïŒã®2æ¬ãæã€ããšã§ããexpoãã©ã°ã€ã³å
šäœãéãããšããäžäœã®èŠç¹ãšãexpo:eas-hostingã5åããšããåå¥ã®èŠç¹ãåãå®è¡ã§åãåºããŸããåŸãã軞ã远å ãããããèšè𿮵éã§ãäœåäœã§èŠãããããæŽçããŠããæ¹ãæ¥œã§ãã
7. 7dçªãš30dçªãå¿ ãã»ããã§äœ¿ã
7æ¥çªã¯ãã€ãºã«ææã§ããé£äŒã»ããã¯ã¢ãã埩å ã»å€§åäœæ¥é±ã®ã©ãããæ··å ¥ãããšå€ãå€ã«ãªããŸãã30æ¥çªã䞊ã¹ãŠãå®åžžçã«å€ãããä»é±ã ãå€ããããå€å®ããŠããplistã«æãå ¥ããââãã®2ãŠã£ã³ããŠéçšããã¥ãŒãã³ã°å€æã®ãã¬ãé²ããŸãã
8. --short ãã©ã°ã§çšéå¥åºåãèšè𿮵éããåãã
人éãèªã詳现ã¢ãŒããšããŠã£ãžã§ããã»ãã°ãã¡ã€ã«ã«é£ããã1è¡ã¢ãŒããæåããåããŠãããšãåäžã¹ã¯ãªãããè€æ°ã®æèã§äœ¿ãåããŸããåºå圢åŒãåŸãã远å ããããšãããšã³ãŒãã®åå²ãå¢ããŠèŠéããæªããªããŸãã
9. 鱿¬¡ãã°ããã¡ã€ã«ã«æžãåºããŠæç³»åãæ®ã
~/.claude/scripts/usage-breakdown.sh 7d > /tmp/usage-$(date +%Y-%m-%d).txt
ãããlaunchdã§æ¯é±ææã«èµ°ãããã ãã§ã4é±åãšã®æ¯èŒã diff ã§èŠãããŸãããæè¿ã³ã¹ããäžãã£ãæ°ãããããšããæèŠãæ°åã§æ€èšŒãããšããæå
ã«ãã°ãããããªããã§è©±ãå
šãå€ãããŸãã
10. plist倿ŽåŸã¯å¿ ã unload â load ã®2ã¹ããããèžã
launchctl unload ~/Library/LaunchAgents/com.lily.usage-breakdown.plist
launchctl load ~/Library/LaunchAgents/com.lily.usage-breakdown.plist
ãã¡ã€ã«ãæžãæããã ãã§ã¯åæ ãããŸãããlaunchctl list com.lily.usage-breakdown ã® "NextScheduledFire" ãèŠãŠæ¬¡åèµ·åæå»ãæ°ãã StartInterval ã«æ²¿ã£ãŠãããã確èªããç¿æ
£ãã€ããŸãã
11. launchdã®plistã«PATHãæç€ºãã
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
</dict>
homebrewãnvmã®ããŒã«ã䜿ãã¹ã¯ãªãããlaunchdããåããå Žåãããããªããš command not found ã§é»ã£ãŠå€±æããŸãã/usr/bin/env python3 ã ãã§ã¯è¶³ããªãç°å¢ããããŸãã
12. MCPãµãŒããŒåã®ç©ºæåã¬ãŒã㯠parts[1] ãŸã§ç¢ºèªãã
if len(parts) >= 2 and parts[1]:
mcp_calls[parts[1]] += 1
len(parts) >= 2 ã ãã§ã¯ mcp__ â ["mcp", ""] ã®ç©ºæåãéãæããŸããand parts[1] ãè¶³ãããšã§ã空ããŒã most_common ã«æ··å
¥ããã®ãé²ããŸãã
13. ã¹ã¯ãªããã¯1ãã¡ã€ã«å®çµã§èšèšãã
å€éšPythonãã¡ã€ã«ãžã®äŸåãæã€ãšããã¡ã€ã«ãç§»åã»åé€ããããšãã«é»ã£ãŠå£ããŸãã<<'PY' ... PY ã®ã€ã³ã©ã€ã³ãã¢ããã¥ã¡ã³ãæ¹åŒã¯ãã¹ã¯ãªãã1æ¬ãã©ãã«çœ®ããŠããã®ãŸãŸåãèªå·±å®çµåã«ããæãæè»œãªæ¹æ³ã§ãã
14. éèšçµæã®æ°åããååŸæ¹æ³ãžã®ä¿¡é Œããšåãé¢ããŠèªã
mtimeçªã®è©±ããã®å žåã§ããæ°åãåºãŠãããã®æ°åã®æ ¹æ ââã©ã®ãã¡ã€ã«ã®ã©ã®ãã£ãŒã«ããèªãã§ãããââãçè§£ããŠããªããšã誀ã£ãåæã§ãã¥ãŒãã³ã°ãé²ããŸããã¹ã¯ãªããã®åäœã1床æã§è¿œã£ãŠãããã¯ã¢ããåŸã«åœéœæ§ãåºãããšããéçãææ¡ããŠãããå®åžžéçšã«ä¹ããé åºã倧åã§ãã
ãŸãšã
Claude Codeã® /usage ãåºãã®ã¯ãã¢ãã«å¥ã®åèšé¡ãã ãã§ãã106è¡ã® usage-breakdown.sh ã¯ãã®ã®ã£ãããåããããã«æžããã¹ã¯ãªããã§ãtranscript.jsonlãPythonã§ããŒã¹ããŠSkillã»Agentã»MCPãµãŒããŒããšã®åŒã³åºãåæ°ãCounterã§éèšããŸãã
å®éã«7æ¥åãæµããš Bash: 3,656åïŒ72.9%ïŒ ãšãã宿
ãèŠãã30æ¥åãŸã§åºãããš claude-in-chrome: 1,571åïŒé±366åæç®ïŒ ãšããå®åžžçãªéããæµ®ãã³ãŸãããã®æ°åãåºã«ã鱿ç®100å以äžã®ã³ã³ããŒãã³ããç¹å®ããŠplistã®StartIntervalã調æŽããââãããæ¬çš¿ã®æé å
šäœã®ãŽãŒã«ã§ããã
ã€ãŸãããã€ã³ãããªãã¹ããšå€ãèŠããŸãããå šãŠãå®ã³ãŒããèªãã åŸã§ããæ°ã¥ããªãã£ãèœãšã穎ãã§ããã¹ã¯ãªããã®30ã50è¡ç®ã®éèšã³ã¢ã1床æã§èªãã§åäœã远ãã°ãããã ãã§ååã¯äºé²ã§ããŸããæ®ãã¯launchdãšã®çµã¿åããç¹æã®ç°å¢äŸåã§ãPATHãšunload/loadãæŒãããã°çä»ããŸãã
æå120äžã®èªåŸç°å¢ãæ¯ããŠããã®ã¯ãåã ã®SkillãMCPãµãŒããŒã®è³¢ãã ãã§ãªããã©ã®ã³ã³ããŒãã³ããã©ãã ãåããŠããããæ°åã§èŠãããä»çµã¿ãåžžæåã£ãŠããããšã§ããèšæž¬ã§ããªããã®ã¯æ¹åã§ããŸãããæå ã®transcript.jsonlã«åãããŒã¿ãæ¢ã«æºãŸã£ãŠããã®ã§ã仿¥äžã«åãããŸãã
ä»çµã¿ã®å šäœåã»æ120äžã®å èš³ã»30æ¥æé ã¯æænoteã«ãŸãšããŠããŸãã
ð Claude CodeèªåŸç°å¢ã§ãå®éã©ã皌ãã â ä»çµã¿ã»å®äŸã»å§ãæ¹ã»ãµããŒã
LilyïŒ@bokuwalilyïŒâ å人éçºè ãClaude Code ã§èªåååºç€ãçµã¿ãªãããiOSã¢ããªãWebãµãŒãã¹ãéç£ããŠããŸã
- å¶äœç©ã»èšäºã¯ bokuwalily.com ã«ãŸãšããŠããŸãð¥ïž
- AIã§ãå¯ãŠãŠãåãä»çµã¿ããäœã£ãŠæ120äžã«ãã話㯠noteã®ææèšäº ã«ð°
- OSS: github.com/bokuwalily ð
- ææ°æ å ±ã»ãåãåãã㯠X @bokuwalily ãžð
çããã® â€ïž ãã·ã§ã¢ãå±ã¿ã«ãªããŸãïŒ