È un file solo. Apri Claude Code e incolla questo. Claude crea la skill per te:
Incolla in Claude Codecrea la skill e conferma che /brain-grade funziona
Create the file ~/.claude/skills/brain-grade/SKILL.md with exactly this content, then confirm /brain-grade works:
---
name: brain-grade
description: >-
Six Claudes grade how smart you actually are, using your own past chats as evidence: five judges (IQ, logic, emotional intelligence, creativity, street smarts) each grade you alone out of 100 and compare you to the average person, then a coach tells you exactly what to fix. Use when the user types /brain-grade, optionally followed by my-chats (the default) or a path to a file or folder of chat exports.
argument-hint: "[my-chats | folder or file of chat exports]"
license: MIT
metadata:
author: "Alex Chen (@nocodealex)"
homepage: "https://chen.media"
version: "1.0.0"
---
# /brain-grade
The user types `/brain-grade`. You will grade how smart they actually are from what they wrote in their past chats: five judges, each alone, then a coach. Never flatter. A normal score is a middle score, and you say so plainly.
## 1. Say what you will read, and ask once
- `my-chats` (or nothing) = the user's own Claude Code chats in `~/.claude/projects`. A path = a file or folder of exports: Claude Code `.jsonl`, a ChatGPT export (`conversations.json`), or `.txt` / `.md` files.
- Tell the user in ONE message: you will read only what THEY wrote (never Claude's replies), up to 320 of their messages, with tokens, emails and phone numbers masked; it is saved only in `.brain-grade/` in this folder; you will then start six sub-agents that read it. Ask: "Go ahead? (yes/no)". Wait for a yes. If it is a no, stop.
## 2. Collect the evidence
Save the script at the end of this file as `.brain-grade/collect.py`, then run `python3 .brain-grade/collect.py <the argument>` (nothing for `my-chats`). It prints how many messages and chats it found and writes `.brain-grade/<date>/evidence.md`: your messages, numbered `[#12 2026-10-03 project]`. If it kept fewer than 30 messages, say there is not enough evidence for a fair grade, say what to point it at (`/brain-grade <folder of exports>`), and stop.
## 3. Five judges, alone
Start five sub-agents at once (one message, five calls). Give each ONLY the path to `evidence.md` and ONE judge below. Nobody sees anybody else's answer. Each judge grades ONE kind of smart, nothing else.
1. **IQ.** How fast and deep the thinking is: does the user grasp new ideas quickly, form abstractions, ask the question that cuts to the core, connect things that look unrelated?
2. **Logic.** How precise and rigorous: are the asks clear and consistent, does the user notice contradictions, check a claim before trusting it, break a problem into steps, think about edge cases, or send vague and conflicting instructions?
3. **EQ.** How the user deals with people, Claude included: tone, patience, the context they give so others can help, how they handle frustration and mistakes, whether they read what the other side needs.
4. **Creativity.** Original angles and unusual combinations, taste, ideas the user generates themselves rather than asking for ideas.
5. **Street smarts.** Practical judgment: knowing what matters and what to skip, using leverage and shortcuts, trying things in the real world, avoiding over-building, finishing things.
Rules for every judge, and tell them all of it:
- 50 is the average adult on this scale, and most people land between 35 and 65. Start at 50 and move only on evidence in the file. 70 or more needs three different quotes that show it. 85 or more needs the same strength in different months. Below 50 is normal and must be said plainly. Never round up to be kind.
- Every claim quotes the file word for word with its number, for example `[#41] "..."`. No quote, no claim. Never invent anything about the user.
- This is only what the user wrote to an AI. Say what the evidence cannot show.
Each judge answers in exactly this form, under 150 words: `SCORE: <0-100>`, `CONFIDENCE: low, medium or high`, `RAISED BY:` one quote and why, `HELD DOWN BY:` one quote and why, `ONE LINE:` the verdict in plain words.
## 4. The coach
When the five are back, start one more sub-agent: the coach. Give it `evidence.md` and the five answers. It lists the THREE habits that cost the user the most, worst first. For each: a quote as evidence, what it costs, and the exact fix: one sentence, and one prompt or rule the user can copy tomorrow. If the user asks Claude for the answer to a hard problem straight away, without trying it first, the coach names it as a habit and gives the fix (try it yourself for five minutes, then ask Claude to attack your attempt instead of answering).
## 5. Write the result
Create `.brain-grade/<date>/REPORT.md` with: the table below, the five judges' quotes, the coach's fix list, and "What this cannot show". Then show the user, in chat: the table, the three fixes, and where the file is. Touch no other files.
| Judge | Score | vs the average person (50) | Confidence | One line |
|---|---|---|---|---|
- vs the average person = the score minus 50, written `+14` or `-9`. 50 is a fixed reference for a typical adult, not a measured number: say so under the table.
- Add one overall line: the mean of the five, and the judge who was hardest on the user.
- End the report with this line: `Made with /brain-grade by Alex Chen (@nocodealex) · chen.media`
## Rules
- Be honest. If the user is strong at something, say so with the quote that proves it. If the chats show little, say little.
- This is a structured opinion made by language models from a slice of how someone writes. It is not an IQ test, not a psychological assessment and not advice about work or health.
- Keep it private: nothing is uploaded or posted by this skill, and the evidence stays in `.brain-grade/`.
## The collector script
Save exactly this as `.brain-grade/collect.py`:
```python
#!/usr/bin/env python3
"""brain-grade: collect YOUR OWN messages from past chats into one evidence file.
python3 collect.py [my-chats | path ...] [--out DIR]
my-chats (the default) reads your Claude Code chats in ~/.claude/projects. A path is a file or folder of exports: Claude Code
.jsonl, a ChatGPT export (conversations.json) or plain .txt / .md files. Only what YOU wrote is kept, never the replies; tokens,
emails and phone numbers are masked. Nothing leaves this computer: the script only writes DIR/evidence.md.
"""
import datetime
import glob
import json
import os
import re
import sys
LIMIT = 320
MAXLEN = 650
MINLEN = 25
SKIP = ("<", "Caveat:", "[Request interrupted", "This session is being continued", "/")
MASK = [(re.compile(p), r) for p, r in (
(r"\b(?:sk|pk|rk|ghp|gho|ghs|github_pat|xox[abprs]|AKIA|AIza|ya29)[-_A-Za-z0-9]{16,}", "[token]"),
(r"(?i)\b(?:password|passwd|secret|token|api[_ -]?key)\b\s*[:=]\s*\S+", "[secret]"),
(r"(?i)bearer\s+[A-Za-z0-9._~+/=-]{20,}", "[token]"),
(r"[\w.+-]+@[\w-]+\.[\w.-]+", "[email]"),
(r"(?<!\d)(?:\+?\d[\s().-]?){10,14}(?!\d)", "[phone]"))]
def clean(text):
text = re.sub(r"\s+", " ", text).strip()
for rx, rep in MASK:
text = rx.sub(rep, text)
return text[:MAXLEN]
def keep(text):
t = text.strip()
return len(t) >= MINLEN and not t.startswith(SKIP)
def blocks_text(content):
if isinstance(content, str):
return content
if isinstance(content, list):
return "\n".join(b.get("text", "") for b in content if isinstance(b, dict) and b.get("type") == "text")
return ""
def from_jsonl(path):
out, label = [], os.path.basename(os.path.dirname(path)).strip("-").split("-")[-1][:24] or "chat"
try:
with open(path, encoding="utf-8", errors="replace") as f:
for line in f:
try:
d = json.loads(line)
except ValueError:
continue
if d.get("type") != "user" or d.get("isSidechain") or d.get("isMeta"):
continue
text = blocks_text((d.get("message") or {}).get("content"))
if keep(text):
out.append((str(d.get("timestamp", ""))[:10], label, os.path.basename(path)[:8], text))
except OSError:
pass
return out
def from_chatgpt(path):
out = []
try:
data = json.load(open(path, encoding="utf-8", errors="replace"))
except (OSError, ValueError):
return out
for conv in data if isinstance(data, list) else []:
day = ""
if isinstance(conv, dict) and conv.get("create_time"):
day = datetime.datetime.fromtimestamp(conv["create_time"]).strftime("%Y-%m-%d")
for node in ((conv or {}).get("mapping") or {}).values():
m = (node or {}).get("message") or {}
if (m.get("author") or {}).get("role") != "user":
continue
parts = (m.get("content") or {}).get("parts") or []
text = "\n".join(p for p in parts if isinstance(p, str))
if keep(text):
out.append((day, "chatgpt", str(conv.get("id", ""))[:8], text))
return out
def from_text(path):
try:
raw = open(path, encoding="utf-8", errors="replace").read()
except OSError:
return []
return [("", os.path.basename(path)[:24], "text", p) for p in re.split(r"\n\s*\n", raw) if keep(p)]
def gather(args):
out = []
targets = [os.path.expanduser(a) for a in args if not a.startswith("--")]
if not targets or targets == ["my-chats"]:
targets = [os.path.expanduser("~/.claude/projects")]
for t in targets:
if t == os.path.expanduser("~/.claude/projects"):
files = sorted(glob.glob(os.path.join(t, "*", "*.jsonl")))
else:
files = [t] if os.path.isfile(t) else sorted(glob.glob(os.path.join(t, "**", "*"), recursive=True))
for p in files:
if not os.path.isfile(p):
continue
if p.endswith(".jsonl"):
out += from_jsonl(p)
elif os.path.basename(p) == "conversations.json" or (p.endswith(".json") and "conversation" in p.lower()):
out += from_chatgpt(p)
elif p.endswith((".txt", ".md")):
out += from_text(p)
return out
def pick(msgs):
seen, uniq = set(), []
for m in msgs:
k = re.sub(r"\W+", "", m[3].lower())[:80]
if k not in seen:
seen.add(k)
uniq.append(m)
uniq.sort(key=lambda m: m[0])
if len(uniq) <= LIMIT:
return uniq, len(uniq)
longest = {id(m) for m in sorted(uniq, key=lambda m: -len(m[3]))[:LIMIT // 2]}
rest = [m for m in uniq if id(m) not in longest]
step = len(rest) / float(LIMIT - len(longest))
even = {id(rest[int(i * step)]) for i in range(LIMIT - len(longest))}
return [m for m in uniq if id(m) in longest or id(m) in even], len(uniq)
def main(argv):
out_dir = ".brain-grade/" + datetime.date.today().isoformat()
if "--out" in argv:
out_dir = argv[argv.index("--out") + 1]
argv = [a for i, a in enumerate(argv) if a != "--out" and (i == 0 or argv[i - 1] != "--out")]
msgs = gather(argv)
kept, total = pick(msgs)
os.makedirs(out_dir, exist_ok=True)
sessions = len({(m[1], m[2]) for m in msgs})
with open(os.path.join(out_dir, "evidence.md"), "w", encoding="utf-8") as f:
f.write(f"# Evidence: {len(kept)} of your {total} messages, from {sessions} chats\n\nOnly what you wrote. Masked: tokens, emails, phone numbers.\n\n")
for i, (day, label, sid, text) in enumerate(kept, 1):
f.write(f"[#{i} {day} {label}] {clean(text)}\n\n")
print(f"messages found: {total} chats: {sessions} kept: {len(kept)} file: {os.path.join(out_dir, 'evidence.md')}")
if __name__ == "__main__":
main(sys.argv[1:])
```
Open a new Claude Code session afterwards so it picks the skill up.
Preferisci il terminale? Crea la cartella (), poi salva lo stesso testo come al suo interno.
La skill sta in , quindi funziona in ogni progetto. Per toglierla: .