> 生成一份对外可分享、脱敏的 AI-Native 开发者 README。 量化展示我对 Claude Code + Codex CLI + Kiro (AWS) + Trae (ByteDance) + Gemini Antigravity (Google) + Cursor 的使用深度、AI 协作风格、 项目与领域分布、兴趣主题,以及与 GitHub 提交的产出关联。 "分析我的 Claude / Codex / Kiro / Trae / Antigravity / Cursor 使用情况" / "总结我的 AI 使用" / "生成 AI 月度报告" / "按月份分析我的 AI 编码" / "分析 2026-05 的 AI 使用" / "build my AI usage profile" / "build my monthly AI coding report" / "analyze my AI usage for May 2026" / "summarize my Claude / Codex / Kiro / Trae / Antigravity / Cursor history" / "生成开发者画像". 全程本地、只读、默认匿名、不上传任何数据。
npx skills add https://github.com/study8677/Readme.skill --skill readme-skill
You (the AI agent invoking this skill) will read local Claude Code + Codex CLI
+ Kiro (AWS) + Trae (ByteDance) + Gemini Antigravity (Google) + Cursor data,
compute a fixed set of dimensions, and render both a Markdown profile and a
validated SVG poster under ./output/ in the user's requested language (Chinese
by default; English when the user asks in English or explicitly requests
English). The profile and poster can cover the default history view or an
explicit month / date range. You do all of the work — read the files with
Read, query sqlite via Bash, synthesize the prose yourself, then write and
validate the SVG. Do not write helper scripts; the skill is the recipe.
> 支持的 6 个 AI 编程工具(任一缺失都自动降级跳过):
> 1. Claude Code (~/.claude/) — Step 2
> 2. Codex CLI (~/.codex/) — Step 3
> 3. Kiro CLI / IDE (~/.kiro/ + ~/.local/share/kiro-cli/) — Step 3b
> 4. Trae IDE (~/Library/Application Support/Trae/ + 项目 .trae/) — Step 3c
> 5. Gemini Antigravity (~/.gemini/antigravity/brain/) — Step 3d
> 6. Cursor (~/Library/Application Support/Cursor/ + 项目 .cursor/) — Step 3e
> 默认行为:对外分享版 —— 项目名匿名、敏感信息脱敏。
> 如果用户明确说"私人版 / 不要脱敏 / show real names",跳过匿名步骤。
cd <repo-with-this-skill> # e.g. ~/Projects/Readme.skill
mkdir -p output
DATE=$(date +%Y%m%d)
Decide anonymization mode (default = on). Build an in-memory mapping
real_path → "项目 A/B/C" as you encounter project paths in later steps.
Use the same mapping consistently across all sections.
If the user asks for a month, quarter, stage, date range, "月度报告",
"按月份分析", "time range", "monthly report", or similar, set a report window
before reading any data. The window is a half-open local-date interval:
[REPORT_START, REPORT_END_EXCL).
Supported phrases:
2026-05, 2026年5月, May 2026 → REPORT_START=2026-05-01,REPORT_END_EXCL=2026-06-01, REPORT_LABEL=2026-05,
REPORT_SLUG=202605, REPORT_MODE=monthly
2026-04 到 2026-05, Apr-May 2026 → start at the first day ofthe first month, end at the first day after the last month,
REPORT_MODE=range
2026-05-03 到 2026-05-19 / 2026-05-03..2026-05-19 →include both named dates by setting REPORT_END_EXCL to the day after the
final date, REPORT_MODE=range
最近30天 / last 30 days → compute from today's local date,REPORT_MODE=range
If no explicit time window is requested, keep the existing default profile
behavior: AI tool totals may use all available local history, while GitHub and
local git use their existing 365-day windows. Set WINDOW_REQUESTED=0.
If a window is requested, set:
WINDOW_REQUESTED=1
REPORT_START=<YYYY-MM-DD>
REPORT_END_EXCL=<YYYY-MM-DD> # exclusive
REPORT_LABEL=<human-readable label, e.g. "2026-05" or "2026-04..2026-05">
REPORT_SLUG=<filesystem-safe slug, e.g. "202605" or "202604-202605">
For every source below, include only records whose timestamp is
>= REPORT_START 00:00:00 and < REPORT_END_EXCL 00:00:00 in local time.
Never mix all-time counts into a windowed report unless the metric is explicitly
labeled "all-time context" or "fallback, not window-filtered".
For windowed reports, also compute a previous comparison window of the same
length when possible:
# macOS date syntax. Use equivalent date math on other systems.
window_start_ts=$(date -j -f "%Y-%m-%d" "$REPORT_START" +%s)
window_end_ts=$(date -j -f "%Y-%m-%d" "$REPORT_END_EXCL" +%s)
WINDOW_DAYS=$(( (window_end_ts - window_start_ts) / 86400 ))
PREV_END_EXCL="$REPORT_START"
PREV_START=$(date -j -v-"${WINDOW_DAYS}"d -f "%Y-%m-%d" "$REPORT_START" +%Y-%m-%d)
~/.claude/ + 项目 .claude/)Read ~/.claude/stats-cache.json. Extract:
| 字段 | 含义 |
| --- | --- |
| totalSessions | session 总数 |
| totalMessages | 消息总数 |
| firstSessionDate | 首个 session ISO 时间 |
| longestSession.{duration,messageCount,timestamp} | 最长 session |
| hourCounts | {hour: count} 24h 热力 |
| modelUsage[model].{inputTokens,outputTokens,cacheReadInputTokens,cacheCreationInputTokens} | 每模型 token 细分 |
| dailyActivity[].{date,messageCount,sessionCount,toolCallCount} | 每日活跃 |
| dailyModelTokens[].{date,tokensByModel} | 每日按模型 token |
派生量(你来算):
claude_tokens_spent = Σ (inputTokens + outputTokens + cacheCreationInputTokens) —— 真实新付费 tokenclaude_cache_read = Σ cacheReadInputTokens —— 缓存复用,反映 prompt-caching 熟练度cache_to_spent_ratio = claude_cache_read / claude_tokens_spent —— 比值越大越熟时间窗口模式:如果 WINDOW_REQUESTED=1,优先从 dailyActivity 与
dailyModelTokens 中按 REPORT_START <= date < REPORT_END_EXCL 过滤后汇总
Claude sessions / messages / tokens / cache。modelUsage 是全局聚合;只有默认
profile 模式才能直接当总量使用。若某个 Claude 字段只有全局聚合、无法按日期切分,
在月度报告里写 — 或标注「仅有 all-time 聚合,未纳入窗口统计」,不要把全局值混进
月度值。
~/.claude/history.jsonl —— 每行 {display, timestamp, project, sessionId}。
# Top 15 slash commands
jq -r 'select(.display | startswith("/")) | (.display | split(" ")[0])' \
~/.claude/history.jsonl | sort | uniq -c | sort -rn | head -15
# 总条数 vs 命令条数 vs 直接 prompt 条数
total=$(wc -l < ~/.claude/history.jsonl)
cmd=$(jq -r 'select(.display | startswith("/")) | .display' ~/.claude/history.jsonl | wc -l)
echo "total=$total cmd=$cmd plain=$((total - cmd))"
时间窗口模式下,所有 history.jsonl 统计先过滤:
jq --arg start "$REPORT_START" --arg end "$REPORT_END_EXCL" '
select((.timestamp // "")[0:10] >= $start and (.timestamp // "")[0:10] < $end)
' ~/.claude/history.jsonl
记录:/effort、/plan、/skill*、/usage、/clear、/resume、/compact、/init 各自次数。
~/.claude/projects/)Each subdir is one project; per-project *.jsonl files = sessions.
The dir name encodes the absolute path with / → - (ambiguous when the
original path itself contains -).
# Top 15 by session-file count
for d in ~/.claude/projects/*/; do
n=$(ls "$d"*.jsonl 2>/dev/null | wc -l | tr -d ' ')
echo "$n $(basename "$d")"
done | sort -rn | head -15
To recover the canonical real path (so you can run git log later), read
the cwd field from the first JSONL in each dir:
head -1 ~/.claude/projects/<encoded>/*.jsonl 2>/dev/null \
| jq -r 'select(.cwd) | .cwd' | head -1
Claude Code 的 plan 文件目录不是固定值。默认在 ~/.claude/plans,
但用户可以通过 plansDirectory 改到项目工作目录下,例如
"./.claude/plans"。统计 plans 时必须先解析候选 plan 目录,不能只枚举
~/.claude/plans/*.md。
解析规则:
~/.claude/projects/*/*.jsonl 的 cwd 字段恢复 Claude Code 访问过的项目根目录。.claude/settings.local.json > .claude/settings.json > ~/.claude/settings.json > default。
plansDirectory:~/... 展开为 $HOME/...;./... 或其他相对路径按该项目根目录解析。~/.claude/plans。*.md 真实路径去重后,再统计 plan 数量和标题。# Plan titles (first # heading of each plan) from all resolved plan dirs.
# Include ~/.claude/plans plus any per-project plansDirectory targets.
# Count plan files by file count, not by title extraction success.
plan_count=<resolved-plan-file-count>
for f in <resolved-plan-files>; do
awk '/^# / { sub(/^# /, ""); print; exit }' "$f"
done
ls ~/.claude/skills/ | wc -l # skills installed / authored
ls ~/.claude/tasks/ | wc -l # tasks tracked
ls ~/.claude/todos/ | wc -l
For each ~/.claude/skills/*/SKILL.md and ~/.codex/skills/*/SKILL.md,
use the Read tool to inspect the frontmatter (top of file, between --- markers). Extract name and the full description as YAML semantics dictate.
Support all four YAML scalar styles:
| 写法 | 处理 |
| --- | --- |
| 单行: description: foo bar | 直接取冒号后内容 |
| 引号: description: "foo bar" 或 'foo bar' | 去掉首尾引号 |
| > folded(多行折叠) | join indented continuation lines with spaces |
| \| literal(多行保留) | preserve line breaks |
停止条件:遇到下一个未缩进的 frontmatter key(行首无空格且形如 key:),或遇到关闭的 --- 行。如果 description 字段缺失,回落到 <目录名> (no description)。
绝不使用 head \| grep —— 那会把 >/\| 多行风格静默截断到只剩 >,这是 v2.2 之前的真实 bug。务必 Read 完整 frontmatter 后按 YAML 语义解析。
枚举候选 skill 目录:
ls -d ~/.claude/skills/*/ ~/.codex/skills/*/ 2>/dev/null
然后对每个目录:Read 它的 SKILL.md 头部 ~30 行 → 按上表解析 YAML → 输出 <source>|<name>|<full_description>。
记录每个 skill 是「自建」还是「安装」。如果 skill 目录下有 git remote 指向用户自己的 repo,标记为自建;否则标记为安装。
Read ~/.claude/settings.json. Count:
hooks 个数(结构化自动化能力)mcpServers 个数(外部能力接入)permissions.defaultMode~/.codex/)The primary analytics store is ~/.codex/state_5.sqlite, table threads.
Always open with mode=ro so you can never write:
SQ='sqlite3 file:'"$HOME"'/.codex/state_5.sqlite?mode=ro&immutable=1'
# If WINDOW_REQUESTED=1, compute unix-second bounds once and add the filter to
# every threads query below. For queries that already have WHERE, append `AND`.
FROM_TS=$(date -j -f "%Y-%m-%d" "$REPORT_START" +%s 2>/dev/null || true)
TO_TS=$(date -j -f "%Y-%m-%d" "$REPORT_END_EXCL" +%s 2>/dev/null || true)
# created_at >= FROM_TS AND created_at < TO_TS
# Aggregate
$SQ "SELECT COUNT(*), SUM(tokens_used), MIN(created_at), MAX(created_at) FROM threads;"
# Model breakdown (note: empty/NULL model = older sessions, label as 'Codex (未标注)')
$SQ "SELECT COALESCE(NULLIF(model,''),'Codex(未标注)'), COUNT(*), SUM(tokens_used) \
FROM threads GROUP BY 1 ORDER BY 3 DESC;"
# Reasoning effort distribution (xhigh / high / medium / low / unspecified)
$SQ "SELECT COALESCE(NULLIF(reasoning_effort,''),'unspecified'), COUNT(*) \
FROM threads GROUP BY 1 ORDER BY 2 DESC;"
# Top 15 working dirs
$SQ "SELECT cwd, COUNT(*), SUM(tokens_used) FROM threads \
WHERE cwd != '' GROUP BY cwd ORDER BY 2 DESC LIMIT 15;"
# Hour-of-day heatmap
$SQ "SELECT strftime('%H', datetime(created_at,'unixepoch')), COUNT(*) \
FROM threads GROUP BY 1 ORDER BY 1;"
# Day-of-activity timeseries
$SQ "SELECT date(created_at,'unixepoch'), COUNT(*) FROM threads GROUP BY 1;"
# Sample titles + first user messages for keyword extraction (titles only — no body)
$SQ "SELECT title FROM threads WHERE title != '' ORDER BY created_at DESC LIMIT 200;"
$SQ "SELECT first_user_message FROM threads WHERE first_user_message != '' \
ORDER BY created_at DESC LIMIT 200;"
# CLI versions used (Codex evolution signal)
$SQ "SELECT cli_version, COUNT(*) FROM threads WHERE cli_version != '' \
GROUP BY 1 ORDER BY 2 DESC LIMIT 10;"
# --- 以下为 v2.0 新增查询 ---
# 月度聚合(Evolution 曲线用)
$SQ "SELECT strftime('%Y-%m', datetime(created_at,'unixepoch')), COUNT(*), \
SUM(tokens_used), COALESCE(NULLIF(model,''),'unknown') \
FROM threads GROUP BY 1,4 ORDER BY 1,3 DESC;"
# CLI 版本时间线(Evolution 曲线用)
$SQ "SELECT cli_version, MIN(date(created_at,'unixepoch','localtime')), \
MAX(date(created_at,'unixepoch','localtime')), COUNT(*) \
FROM threads WHERE cli_version != '' GROUP BY 1 ORDER BY 2;"
# 每项目 token 消耗(双工具编排分析用)
$SQ "SELECT cwd, COALESCE(NULLIF(model,''),'unknown'), COUNT(*), SUM(tokens_used) \
FROM threads WHERE cwd != '' GROUP BY 1,2 ORDER BY 1,4 DESC;"
~/.codex/history.jsonl — {session_id, ts, text}. Sample for keywords:
wc -l ~/.codex/history.jsonl # total prompts
jq -r '.text' ~/.codex/history.jsonl | head -300 > /tmp/codex_text.txt # corpus
jq -r '.session_id' ~/.codex/history.jsonl | sort -u | wc -l # distinct sessions
时间窗口模式下,先按 .ts 过滤再做计数、关键词采样和 distinct sessions:
jq --arg start "$REPORT_START" --arg end "$REPORT_END_EXCL" '
select((.ts // "")[0:10] >= $start and (.ts // "")[0:10] < $end)
' ~/.codex/history.jsonl
ls ~/.codex/skills/ | wc -l # codex skills
ls ~/.codex/automations/ | wc -l # scheduled automations
ls ~/.codex/rules/ | wc -l # custom rules
~/.kiro/ + ~/.local/share/kiro-cli/)Kiro 是 AWS 出的 agentic IDE / CLI(kirodotdev/Kiro)。Kiro CLI 把 ACP
session 存到 ~/.kiro/sessions/cli/(每个 session 两个文件:<id>.json
元数据 + <id>.jsonl 事件流),把 token / model / provider 细分存到
~/.local/share/kiro-cli/data.sqlite3。Steering / Agents / Skills / Prompts
等基础设施在 ~/.kiro/ 下,跟 Claude Code 风格一致。
所有读取必须只读:SQLite 用 mode=ro&immutable=1;JSON / JSONL 只
Read / jq,不要修改。本步骤先检测 ~/.kiro/ 是否存在,不存在直接跳过本节。
[ -d "$HOME/.kiro" ] || { echo "Kiro not installed; skip Step 3b"; }
KIRO_DB="$HOME/.local/share/kiro-cli/data.sqlite3"
if [ -f "$KIRO_DB" ]; then
KSQ='sqlite3 file:'"$KIRO_DB"'?mode=ro&immutable=1'
# 先 dump schema 再决定查询列名 —— Kiro CLI 仍在迭代,表名可能演进
$KSQ ".schema" | head -80
$KSQ ".tables"
fi
读 schema 后,按实际表名(常见为 messages / sessions / usage 等)
自适应编写聚合 SQL。期望提取的字段:
| 字段 | 含义 | 来源(按 schema 自适应)|
| --- | --- | --- |
| kiro_sessions | 总 session 数 | COUNT(DISTINCT session_id) |
| kiro_messages | 总消息数 | COUNT(*) from message-like 表 |
| kiro_input_tokens / kiro_output_tokens | 每模型 token | SUM(input_tokens) / SUM(output_tokens) |
| kiro_model_breakdown | 按 model / provider 分组 | GROUP BY model, provider |
| kiro_by_date | 按 date(created_at) 聚合 | 每日活跃 |
| kiro_by_hour | 按 strftime('%H', created_at) | 24h 热力 |
降级:如果 schema 找不到 token / model 列,仅按 session 计数即可,并在报告里说明
「Kiro 早期版本未持久化 token 细分,本节按 session 总量给出」。
时间窗口模式下,所有 Kiro SQL 聚合必须按实际 schema 的 created_at /
updated_at / timestamp-like 字段过滤到 [REPORT_START, REPORT_END_EXCL)。
如果 schema 没有可靠时间列,只把该表用于 all-time context,不参与月度指标。
KIRO_SESS="$HOME/.kiro/sessions/cli"
if [ -d "$KIRO_SESS" ]; then
# session 总数
ls "$KIRO_SESS"/*.json 2>/dev/null | wc -l
# 每个 session 抽元数据:cwd、agent、起止时间
for f in "$KIRO_SESS"/*.json; do
jq -r '[.cwd // "", .agent // "", .created_at // "", .updated_at // ""] | @tsv' "$f"
done | sort -u
# 项目分布(按 cwd 聚合)
for f in "$KIRO_SESS"/*.json; do
jq -r '.cwd // empty' "$f"
done | sort | uniq -c | sort -rn | head -15
fi
*.jsonl 是事件流(user/assistant/tool-call 逐条)。**只采样前若干行用于
关键词语料**(同 Claude projects/*/*.jsonl 的处理方式),不要把原文写进
report:
for f in "$KIRO_SESS"/*.jsonl; do
head -50 "$f" | jq -r 'select(.role == "user") | .content // empty' 2>/dev/null
done | head -300 > /tmp/kiro_corpus.txt # 关键词语料
跟 Claude / Codex 的 skills 体系一一对应,扫法一致:
# 全局 agents(每个文件是一个 .json,filename 即 agent 名)
ls ~/.kiro/agents/*.json 2>/dev/null | wc -l
# 全局 skills(每个目录一个,含 SKILL.md,frontmatter 同 Agent Skills 标准)
ls -d ~/.kiro/skills/*/ 2>/dev/null
# Steering 文件(项目规范 / 架构决策,markdown)
ls ~/.kiro/steering/*.md 2>/dev/null | wc -l
# Prompts 模板
ls ~/.kiro/prompts/ 2>/dev/null | wc -l
# Settings & MCP
[ -f ~/.kiro/settings/cli.json ] && cat ~/.kiro/settings/cli.json | jq 'keys'
[ -f ~/.kiro/settings/mcp.json ] && cat ~/.kiro/settings/mcp.json | jq '.mcpServers | keys'
对每个 ~/.kiro/skills/*/SKILL.md,沿用 Step 2.4b 的 YAML frontmatter 解析逻辑
(Read 完整 frontmatter,按 > / | / 引号 / 单行四种 scalar 处理)。
Kiro skills 用的就是 Agent Skills 开放标准,跟 Claude / Codex 字段完全相同
(name + description)。
把 ~/.kiro/skills/ 合并进 Step 2.4b 的 skill 总表,新增一列「来源 = Kiro」。
KIRO_KB="$HOME/.local/share/kiro-cli/knowledge_bases"
if [ -d "$KIRO_KB" ]; then
ls -d "$KIRO_KB"/*/ 2>/dev/null # 每个 agent 一个独立 KB
fi
知识库属于「AI 基础设施层」高级信号 —— 用户主动给 agent 喂资料。统计有几个
KB、覆盖哪些 agent 即可,不读 data.json 原文。
.kiro/ 配置(按项目)对 Step 5 候选目录路径列表里的每个项目根,再检查项目内的 workspace-level
Kiro 配置(这往往是用户日常工作的真实证据):
for path in <candidate-paths>; do
for kind in agents skills steering prompts; do
if [ -d "$path/.kiro/$kind" ]; then
echo "$path::$kind::$(ls "$path/.kiro/$kind" 2>/dev/null | wc -l)"
fi
done
done
合并到 6.4 「项目与领域」时,给配置了 .kiro/ 的项目打 Kiro+ 标记。
如果 Kiro 安装但 data.sqlite3 不存在(用户只用过 IDE 桌面版,未跑 CLI),
本步骤仅能采集到 Steering / Agents / Skills 配置数,不要编造 session / token 数字。
在最终报告的「Kiro 章节」明确写:「Kiro CLI 数据未生成,本节仅展示 Steering /
Agents / Skills 配置;如需完整 session/token 统计请先运行 Kiro CLI。」
~/Library/Application Support/Trae/ + 项目 .trae/)Trae 是字节跳动出的 AI IDE,基于 VS Code fork(Electron)。**chat 对话存在
本地 SQLite**(User/workspaceStorage/<hash>/state.vscdb,与 Cursor 同款机制),
但 token 用量统计走云端 API(query_user_usage_group_by_session),
本机不持久化。所以本步骤只读两类本地数据:
state.vscdb 里的 chat 元数据(数量、cwd、关键词).trae/ 与 home 配置里的 rules / skills / settings所有读取必须只读:SQLite 强制 mode=ro&immutable=1;不要触发任何 Trae
进程写操作。先检测目录是否存在,不存在直接跳过本节。
# macOS 路径(Linux 类似在 ~/.config/Trae/,Windows 在 %APPDATA%\Trae\)
TRAE_BASE="$HOME/Library/Application Support/Trae"
TRAE_WS="$TRAE_BASE/User/workspaceStorage"
[ -d "$TRAE_WS" ] || { echo "Trae not installed or no workspaces; skip Step 3c"; }
# 工作区数(每个 hash 目录 = 一个被打开过的项目)
ls -d "$TRAE_WS"/*/ 2>/dev/null | wc -l
# 每个工作区对应的真实项目路径(workspace.json 里有 folder/uri)
for d in "$TRAE_WS"/*/; do
if [ -f "$d/workspace.json" ]; then
jq -r '.folder // .configuration // empty' "$d/workspace.json"
fi
done | sort -u
每个工作区有自己的 state.vscdb;另外 ~/Library/Application Support/Trae/User/globalStorage/state.vscdb 是全局聚合库。**Trae 的 chat 表名 / key 前缀
在版本间会变化**(早期沿用 VS Code 的 ItemTable,新版本可能新增 Trae 专用表),
先 dump 一下结构再下查询:
TRAE_GLOBAL="$TRAE_BASE/User/globalStorage/state.vscdb"
if [ -f "$TRAE_GLOBAL" ]; then
TSQ='sqlite3 file:'"$TRAE_GLOBAL"'?mode=ro&immutable=1'
$TSQ ".tables"
$TSQ "SELECT name FROM sqlite_master WHERE type='table';"
# 常见结构:ItemTable(key TEXT, value BLOB) —— 类 VS Code KV
# Trae 把 chat 存为 key='trae.chat.*' 或 'composer.*' 形式(版本不同前缀不同)
$TSQ "SELECT key, length(value) FROM ItemTable \
WHERE key LIKE '%chat%' OR key LIKE '%conversation%' OR key LIKE '%composer%' \
ORDER BY length(value) DESC LIMIT 30;" 2>/dev/null
fi
# 工作区级 chat
for d in "$TRAE_WS"/*/; do
db="$d/state.vscdb"
[ -f "$db" ] || continue
ws_chat_keys=$(sqlite3 "file:$db?mode=ro&immutable=1" \
"SELECT COUNT(*) FROM ItemTable WHERE key LIKE '%chat%' OR key LIKE '%composer%';" 2>/dev/null)
echo "$(basename "$d") chat_keys=$ws_chat_keys"
done
期望提取:
| 字段 | 含义 | 备注 |
| --- | --- | --- |
| trae_workspaces | 打开过的项目数 | ls workspaceStorage/*/ 计数 |
| trae_chat_session_count | 估算的 chat session 数 | 按 chat-related key 数估算 |
| trae_active_projects | 有 chat 的项目数 | ws_chat_keys > 0 的工作区数 |
| trae_corpus | chat 标题 / 首条 user message | 仅采样若干条,用于关键词,不入报告原文 |
时间窗口模式下,Trae workspace / chat 只能在存在可靠 timestamp 或文件 mtime
落入窗口时计入窗口活跃。否则只作为「检测到 Trae 配置 / all-time context」展示,
不要计入月度 sessions、active projects 或关键词。
强烈降级提示:
LIKE 没匹中任何 row,老老实实在报告里写「Trae 本地 chat 仅检测到 workspace 数量 N,对话内容
key 命名约定本工具暂不解析」,不要编造 session 数。
state.vscdb 文件不存在,直接跳过该工作区。Trae 的 token / 模型用量走云端 API。第三方工具(如 tokscale)的做法是:
用户先 tokscale trae login,再调 query_user_usage_group_by_session 拉数据
缓存到 ~/.config/tokscale/trae-cache/sessions/*.json。
本 skill 不发起任何网络请求,所以 Trae 的 token 数字无法被采集。
最终报告里诚实写:「Trae 的 token 用量数据由 ByteDance 云端 API 持有,
本 skill 出于『100% 本地 + 只读』原则不接入;如需 Trae token,请使用
tokscale 等第三方工具单独采集后人工补入。」
可选:如果用户已经在 ~/.config/tokscale/trae-cache/sessions/ 里有
导出的 JSON 缓存,可以读它(只读、本地):
TOKSCALE_TRAE="$HOME/.config/tokscale/trae-cache/sessions"
if [ -d "$TOKSCALE_TRAE" ]; then
jq -s 'map(.token_count // 0) | add' "$TOKSCALE_TRAE"/*.json 2>/dev/null
jq -r '.model // empty' "$TOKSCALE_TRAE"/*.json 2>/dev/null | sort | uniq -c
fi
.trae/ 配置(rules / skills / .ignore)跟 Kiro .kiro/、Claude 项目 .claude/ 一样,Trae 在项目内提供 .trae/
工作区目录。这是「用户给 AI 立规矩」的一手证据。
for path in <candidate-paths>; do
trae_dir="$path/.trae"
[ -d "$trae_dir" ] || continue
echo "$path::trae::rules=$(ls "$trae_dir"/rules/*.md 2>/dev/null | wc -l)::skills=$(ls -d "$trae_dir"/skills/*/ 2>/dev/null | wc -l)::ignore=$([ -f "$trae_dir/.ignore" ] && echo 1 || echo 0)"
done
.trae/rules/*.md 与 .trae/skills/*/SKILL.md 都是 markdown,
继续沿用 Step 2.4b 的 YAML frontmatter 解析逻辑。把它们合并进 6.2 的
「AI 基础设施层」总表,新增一列「来源 = Trae」。
~/Library/Application Support/Trae/ 不存在 → 完全跳过本节.trae/ 配置」~/.gemini/antigravity/)Antigravity is the third local AI tool source. Treat each
~/.gemini/antigravity/brain/<uuid>/ directory as one Antigravity task/session.
Only count directories whose basename is a UUID; ignore non-task directories such
as tempmediaStorage.
Only read local text data:
*.metadata.json for artifact metadata and summariestask.md, implementation_plan.md, walkthrough.md.resolved, .resolved.0, .resolved.1, etc.Never read for analytics:
*.png, *.webp, *.jpg, *.jpeg)~/.gemini/antigravity/annotations/*.pbtxt~/.config/Antigravity/* browser/cache dataAG_BRAIN="$HOME/.gemini/antigravity/brain"
AG_UUID_RE='[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
# Count Antigravity task/session directories; exclude temp/media helper dirs
find "$AG_BRAIN" -mindepth 1 -maxdepth 1 -type d 2>/dev/null \
| grep -E "/$AG_UUID_RE$" | wc -l
# Artifact type breakdown from metadata in task/session directories
find "$AG_BRAIN" -mindepth 2 -maxdepth 2 -name '*.metadata.json' -type f 2>/dev/null \
| grep -E "/$AG_UUID_RE/[^/]+\.metadata\.json$" \
| xargs -r jq -r '.artifactType // "unknown"' | sort | uniq -c | sort -rn
# Activity by day from metadata updatedAt
find "$AG_BRAIN" -mindepth 2 -maxdepth 2 -name '*.metadata.json' -type f 2>/dev/null \
| grep -E "/$AG_UUID_RE/[^/]+\.metadata\.json$" \
| xargs -r jq -r '.updatedAt // empty' \
| cut -c1-10 | grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{2}$' \
| sort | uniq -c
# Monthly activity for Evolution curve
find "$AG_BRAIN" -mindepth 2 -maxdepth 2 -name '*.metadata.json' -type f 2>/dev/null \
| grep -E "/$AG_UUID_RE/[^/]+\.metadata\.json$" \
| xargs -r jq -r '.updatedAt // empty' \
| cut -c1-7 | grep -E '^[0-9]{4}-[0-9]{2}$' \
| sort | uniq -c
# Summaries for topic extraction; do not quote full text in the README
find "$AG_BRAIN" -mindepth 2 -maxdepth 2 -name '*.metadata.json' -type f 2>/dev/null \
| grep -E "/$AG_UUID_RE/[^/]+\.metadata\.json$" \
| xargs -r jq -r '.summary // empty' | head -200
# Markdown headings for topic extraction
find "$AG_BRAIN" -mindepth 2 -maxdepth 2 -type f \
\( -name 'task.md' -o -name 'implementation_plan.md' -o -name 'walkthrough.md' \
-o -name 'task.md.resolved*' -o -name 'implementation_plan.md.resolved*' \
-o -name 'walkthrough.md.resolved*' \) 2>/dev/null \
| grep -E "/$AG_UUID_RE/[^/]+$" \
| xargs -r grep -hE '^#{1,3} ' | head -200
# Checkbox volume, useful for task/planning depth
find "$AG_BRAIN" -mindepth 2 -maxdepth 2 -type f \
\( -name 'task.md' -o -name 'implementation_plan.md' -o -name 'walkthrough.md' \
-o -name 'task.md.resolved*' -o -name 'implementation_plan.md.resolved*' \
-o -name 'walkthrough.md.resolved*' \) 2>/dev/null \
| grep -E "/$AG_UUID_RE/[^/]+$" \
| xargs -r grep -hE '^- \[[ xX/-]\]' | wc -l
# Antigravity text artifact scale. This is NOT billing usage and MUST NOT be
# merged into Claude/Codex token totals.
find "$AG_BRAIN" -mindepth 2 -maxdepth 2 -type f \
\( -name 'task.md' -o -name 'implementation_plan.md' -o -name 'walkthrough.md' \
-o -name 'task.md.resolved*' -o -name 'implementation_plan.md.resolved*' \
-o -name 'walkthrough.md.resolved*' \) 2>/dev/null \
| grep -E "/$AG_UUID_RE/[^/]+$" \
| xargs -r wc -l -m \
| awk '
$NF != "total" { files++; lines += $1; chars += $2 }
END {
printf "antigravity_text_files=%d\n", files + 0
printf "antigravity_text_lines=%d\n", lines + 0
printf "antigravity_text_chars=%d\n", chars + 0
printf "antigravity_estimated_token_equivalent=%d\n", int(chars / 4 + 0.5)
}'
Compute:
antigravity_tasks = count of brain/<uuid>/ directories.antigravity_artifacts_by_type = counts by artifactType.antigravity_active_days = unique dates from valid updatedAt values.antigravity_first_active / antigravity_last_active = min/max valid updatedAt dates.antigravity_monthly_activity = monthly counts from valid updatedAt values.antigravity_topics = metadata summaries + markdown headings + checkbox section labels, used only for keywords and high-level themes.antigravity_text_files = count of eligible Antigravity text artifact files.antigravity_text_chars = total character count across eligible Antigravity text artifacts.antigravity_text_lines = total line count across eligible Antigravity text artifacts.antigravity_estimated_token_equivalent = round(antigravity_text_chars / 4) as a rough text-scale proxy only.时间窗口模式下,Antigravity 只统计 updatedAt、文件 mtime 或可解析 metadata 时间
落入 [REPORT_START, REPORT_END_EXCL) 的 task/artifact。没有可靠时间的 artifact
可以出现在 all-time context 或缺失说明里,不参与月度增量。
Antigravity data does not expose verified billing token counts. Use — in token columns or omit token metrics for Antigravity. If reporting antigravity_estimated_token_equivalent, label it exactly as estimated token-equivalent (non-billing) and keep it outside all real token totals, token economics tables, and billing/paid-token claims.
~/Library/Application Support/Cursor/ + 项目 .cursor/)Cursor 是 Anysphere 出的 AI IDE,基于 VS Code fork(Electron),存储模型
跟 Trae / VS Code 同款(User/workspaceStorage/<hash>/state.vscdb 的 ItemTable
KV 表,加 User/globalStorage/state.vscdb 全局聚合库)。**chat / composer
数据本地完整缓存,但 token 用量统计走云端 dashboard**(Cursor Pro 计费
依赖云端),本机不持久化精确 token 数字。所以本步骤只读两类本地数据:
state.vscdb 里的 chat / composer 元数据(数量、cwd、关键词).cursor/ 与 home 配置里的 rules / mcp / settings所有读取必须只读:SQLite 强制 mode=ro&immutable=1;不要触发任何 Cursor
进程写操作。先检测目录是否存在,不存在直接跳过本节。
# macOS 路径(Linux: ~/.config/Cursor/User/,Windows: %APPDATA%\Cursor\User\)
CURSOR_BASE="$HOME/Library/Application Support/Cursor"
CURSOR_WS="$CURSOR_BASE/User/workspaceStorage"
[ -d "$CURSOR_WS" ] || { echo "Cursor not installed or no workspaces; skip Step 3e"; }
# 工作区数(每个 hash 目录 = 一个被打开过的项目)
ls -d "$CURSOR_WS"/*/ 2>/dev/null | wc -l
# 每个工作区对应的真实项目路径(workspace.json 里有 folder / configuration)
for d in "$CURSOR_WS"/*/; do
if [ -f "$d/workspace.json" ]; then
jq -r '.folder // .configuration // empty' "$d/workspace.json"
fi
done | sort -u
全局聚合库在 User/globalStorage/state.vscdb。Cursor 的 chat / composer
key 命名比 Trae 略稳定一些(社区有逆向资料)。优先读取
composer.composerHeaders:它通常是 JSON object,内部 allComposers 数组包含
composer 标题、subtitle、创建/更新时间、workspaceIdentifier、trackedGitRepos、
变更行数等元数据。这些属于「内容线索」但不是完整对话正文,适合用于关键词、
项目分布和 Cursor 协作强度。常见 prefix 还有 composer.*、aiService.*、
workbench.panel.aichat.*、aiCodeBlockDiff.*。但仍然 版本会变化,
必须先 dump 结构再下查询:
CURSOR_GLOBAL="$CURSOR_BASE/User/globalStorage/state.vscdb"
if [ -f "$CURSOR_GLOBAL" ]; then
sqlite3 "file:$CURSOR_GLOBAL?mode=ro&immutable=1" ".tables"
# Composer / chat 类 key 排行(按 value 大小,大的通常是真实对话数据)
sqlite3 "file:$CURSOR_GLOBAL?mode=ro&immutable=1" \
"SELECT key, length(value) FROM ItemTable \
WHERE key LIKE 'composer.%' OR key LIKE 'aiService.%' \
OR key LIKE '%aichat%' OR key LIKE '%aiCodeBlockDiff%' \
ORDER BY length(value) DESC LIMIT 30;" 2>/dev/null
# Cursor 新版常见:composer.composerHeaders -> {"allComposers":[...]}。
sqlite3 "file:$CURSOR_GLOBAL?mode=ro&immutable=1" \
"SELECT value FROM ItemTable WHERE key = 'composer.composerHeaders';" 2>/dev/null \
| jq '.allComposers | length' 2>/dev/null
# 只抽元数据,不输出完整对话正文:name / subtitle / date / workspace /
# changed lines / tracked repos. Use this as cursor_corpus and project signal.
sqlite3 "file:$CURSOR_GLOBAL?mode=ro&immutable=1" \
"SELECT value FROM ItemTable WHERE key = 'composer.composerHeaders';" 2>/dev/null \
| jq -r '
(.allComposers // [])[]
| [
(.name // ""),
(.subtitle // ""),
((.createdAt // .lastUpdatedAt // 0) / 1000 | strftime("%Y-%m-%d")),
(.workspaceIdentifier.uri.fsPath // .workspaceIdentifier.uri.path // ""),
(.totalLinesAdded // 0),
(.totalLinesRemoved // 0),
((.trackedGitRepos // []) | map(.repoPath // empty) | join(","))
] | @tsv
' 2>/dev/null | head -300
# Cursor plans/spec-like work, often stored as object keys. Use keys as topic
# signals only; do not treat them as exact session counts unless schema is clear.
sqlite3 "file:$CURSOR_GLOBAL?mode=ro&immutable=1" \
"SELECT value FROM ItemTable WHERE key = 'composer.planRegistry';" 2>/dev/null \
| jq -r 'if type=="object" then keys[] else empty end' 2>/dev/null | head -200
fi
# 工作区级 chat / composer
for d in "$CURSOR_WS"/*/; do
db="$d/state.vscdb"
[ -f "$db" ] || continue
ws_chat_keys=$(sqlite3 "file:$db?mode=ro&immutable=1" \
"SELECT COUNT(*) FROM ItemTable WHERE key LIKE 'composer.%' OR key LIKE '%aichat%' OR key LIKE 'aiService.%';" 2>/dev/null)
echo "$(basename "$d") cursor_chat_keys=$ws_chat_keys"
done
期望提取:
| 字段 | 含义 | 备注 |
| --- | --- | --- |
| cursor_workspaces | 打开过的项目数 | ls workspaceStorage/*/ 计数 |
| cursor_composer_count | composer 会话估算 | 优先 composer.composerHeaders.allComposers | length;降级用 composer-related key 数 |
| cursor_chat_session_count | 估算的 chat session 数 | 按 aichat/aiService key 数估算 |
| cursor_active_projects | 有 chat / composer 的项目数 | ws_chat_keys > 0 的工作区数 |
| cursor_corpus | composer / chat 标题片段 | 从 name / subtitle / plan key 采样,用于关键词,不入报告原文 |
| cursor_projects_from_headers | Cursor 项目路径 | 从 workspaceIdentifier.uri.fsPath / trackedGitRepos[].repoPath 提取,最终输出仍按匿名规则处理 |
| cursor_lines_changed_hint | Cursor 辅助改动规模 | Σ totalLinesAdded/Removed,仅作为 Cursor 本地元数据参考,不与 git numstat 混为同一口径 |
时间窗口模式下,Cursor composer headers 有 createdAt / lastUpdatedAt(通常为
毫秒 epoch)时,按这些字段过滤到 [REPORT_START, REPORT_END_EXCL);workspace
mtime 只能作为弱信号。无法解析时间时,只作为「检测到 Cursor 配置 / all-time
context」展示,不参与月度 sessions、active projects 或关键词。
强烈降级提示:跟 Trae 一样,Cursor 内部 key 没有官方稳定文档。如果
LIKE 没匹中任何 row,老老实实写「Cursor 本地仅检测到 workspace 数量 N,
chat / composer 内容 key 命名约定本工具暂不解析」,不要编造 session 数。
Cursor Pro 的精确 token 用量在云端 dashboard。本机 ItemTable 里可能含有
部分 token 元数据(比如 aiService.applyAiHistory 等 key 内嵌 JSON
里会有 input/output token 字段),但 schema 不稳定也未公开。
本 skill 的策略:
ItemTable 里靠 jq 抽出 token 字段 → 作为参考值展示,明确注明「Cursor 本地估算 token,非云端 dashboard 计费值」。
本 skill 出于『100% 本地 + 只读』原则不接入」。
.cursor/ 配置(rules / mcp / ignore)跟 Kiro .kiro/、Trae .trae/ 一样,Cursor 在项目内提供 .cursor/ 工作区
目录。这是「用户给 AI 立规矩」的一手证据。
for project_path in <candidate-paths>; do
cursor_dir="$project_path/.cursor"
[ -d "$cursor_dir" ] || continue
echo "$project_path::cursor::rules=$(ls "$cursor_dir"/rules/*.{md,mdc} 2>/dev/null | wc -l)::mcp=$([ -f "$cursor_dir/mcp.json" ] && echo 1 || echo 0)::ignore=$([ -f "$cursor_dir/.cursorignore" ] && echo 1 || echo 0)"
done
# 兼容旧版根目录的 .cursorrules 单文件
for project_path in <candidate-paths>; do
[ -f "$project_path/.cursorrules" ] && echo "$project_path::cursorrules=1"
done
.cursor/rules/*.{md,mdc} 是 markdown / Markdown-with-frontmatter,**继续沿用
Step 2.4b 的 YAML frontmatter 解析逻辑**。把它们合并进 6.2 的「AI 基础设施层」
总表,新增一列「来源 = Cursor」。
~/Library/Application Support/Cursor/ 不存在 → 完全跳过 Step 3ecomposer.composerHeaders 缺失 → 降级用 composer/chat key 计数与 workspace folder.cursor/ 配置」本地估算仅作参考」
gh)gh auth status >/dev/null 2>&1 || { echo "gh not auth'd, skipping"; }
If authenticated:
# Default profile mode keeps the existing 365-day GitHub window. Windowed /
# monthly mode uses REPORT_START..REPORT_END_EXCL so GitHub matches local AI
# metrics.
if [ "${WINDOW_REQUESTED:-0}" = "1" ]; then
GH_FROM="${REPORT_START}T00:00:00Z"
GH_TO="${REPORT_END_EXCL}T00:00:00Z"
else
GH_FROM="$(date -u -v -365d +%Y-%m-%dT00:00:00Z)"
GH_TO="$(date -u +%Y-%m-%dT00:00:00Z)"
fi
# GitHub contributions + top repos in the current report window
gh api graphql -f query='
query($from: DateTime!, $to: DateTime!) {
viewer {
login name bio
contributionsCollection(from: $from, to: $to) {
totalCommitContributions
totalPullRequestContributions
totalIssueContributions
totalRepositoryContributions
totalPullRequestReviewContributions
restrictedContributionsCount
contributionCalendar { totalContributions
weeks { contributionDays { date contributionCount } } }
commitContributionsByRepository(maxRepositories: 25) {
contributions { totalCount }
repository { nameWithOwner isPrivate isFork stargazerCount
primaryLanguage { name } }
}
}
repositories(first: 1, ownerAffiliations: OWNER) { totalCount }
pullRequests(first: 1) { totalCount }
issues(first: 1) { totalCount }
}
}' -F from="$GH_FROM" -F to="$GH_TO"
Then page through repositories for language bytes (up to 5 pages × 100 repos):
gh api graphql -f query='
query($cursor: String) {
viewer { repositories(first: 100, after: $cursor, ownerAffiliations: OWNER,
isFork: false, orderBy: {field: UPDATED_AT, direction: DESC}) {
pageInfo { hasNextPage endCursor }
nodes { nameWithOwner isPrivate stargazerCount
languages(first: 10, orderBy: {field: SIZE, direction: DESC}) {
edges { size node { name } } } }
} } }' -F cursor=""
Aggregate languages by Σ size per language across all repos.
Build the candidate path set from:
cwd recovered for each ~/.claude/projects/<encoded>/cwd column from Codex threads tablecwd field in Kiro ~/.kiro/sessions/cli/*.jsonfolder field in Trae User/workspaceStorage/*/workspace.jsonDedupe the union before running git checks.
For each path that's a git repo, count the current user's commits in the
current report window. Default profile mode uses the past year; monthly/range
mode uses REPORT_START..REPORT_END_EXCL:
me=$(git config --global user.email)
if [ "${WINDOW_REQUESTED:-0}" = "1" ]; then
GIT_SINCE="$REPORT_START 00:00:00"
GIT_BEFORE="$REPORT_END_EXCL 00:00:00"
else
GIT_SINCE="1.year.ago"
GIT_BEFORE="now"
fi
for path in <candidate-paths>; do
[ -d "$path/.git" ] || continue
git -C "$path" log --since="$GIT_SINCE" --before="$GIT_BEFORE" --author="$me" \
--numstat --no-renames --pretty=format:'COMMIT|%H|%aI'
done
Aggregate:
commits (count of COMMIT| lines)additions, deletions (sum the numstat columns)last_commit_iso+ - per file extension → top 10 languages)If WINDOW_REQUESTED=1, every number in Step 6 is scoped to
REPORT_LABEL unless explicitly labeled otherwise. Do not silently fall back to
all-time data. If the selected window has no data, generate a short honest
report that says the time range has no measurable local activity instead of
expanding the window.
For windowed reports, add a "阶段变化" interpretation by comparing the current
window with PREV_START..PREV_END_EXCL when enough data exists:
Antigravity tasks, Kiro sessions, Trae/Cursor workspace signals
发生了什么变化"
If the previous comparison window has no data, use week-by-week or first-half vs
second-half changes inside the selected window. If even that is too sparse,
state that the report is a snapshot, not a trend.
dailyActivity (Claude) + Codex by_date + Claude history by_date
+ Kiro by_date (3b.1) + antigravity_active_days (3d) + Trae / Cursor
工作区最后访问日期(如果能从 workspace.json 或 state.vscdb 的 mtime
推断;推不出就略过这两项)
min..max of those dates/ claude_cache_read / 总 codex threads / codex_tokens /
kiro_sessions / kiro_tokens(如果 3b.1 拿到了)/
trae_workspaces / cursor_workspaces + cursor_composer_count /
antigravity_tasks(Antigravity task/session 数)
—— 这些数字必须出现在「一览」里,缺失项显示 —,不要省略行
If available, include antigravity_text_files, antigravity_text_chars, antigravity_text_lines, and antigravity_estimated_token_equivalent as an Antigravity artifact scale note, not as real token usage.
commits_per_day = git_local_commits / active_daysloc_churn_per_day = (additions + deletions) / active_dayssimultaneous_repos = count of repos with ≥1 commitcross_stack_langs = count of distinct primary languages across reposschema 有 model 列时按 3b.1 抽取)。
「Trae: 云端 only」/「Cursor: 云端权威,本地仅参考」。
—,不要估算。
Antigravity / Cursor 六选 N)。用过 ≥ 3 个工具 → 报告里强调「多引擎
编排者」叙事。
自研 skills 数、hooks/MCP 数、plans/tasks 数、automations 数
antigravity_tasks、artifact type breakdown、walkthrough / implementation_plan / task artifacts,用来描述「从任务 → 计划 → walkthrough」的交付闭环。
列出用户亲手构建的 skills / hooks / automations / rules / steering / agents,
每项给 名称 | 一句话描述 | 来源(Claude/Codex/Kiro/Trae)| 调用次数(如可从 history 统计)。
区分「自建」(用户原创)与「安装」(第三方)。
跨工具复用的 skill(同名 SKILL.md 同时出现在 ~/.claude/skills/ 和
~/.kiro/skills/)单独高亮 —— 这是真正的 AI 基础设施互操作信号。
这一段的叙事重点:不只是 AI 的使用者,更是 AI 工作流的建设者。
/plan count / non-command prompt counttotalMessages / totalSessions从 history.jsonl 中按 sessionId 分组,统计典型 session 内的命令序列模式:
/plan 开头的 session 占比 → 说明「先想再做」的习惯有多强/compact 或 /clear 的比例 → 上下文管理意识/effort 在 session 内的切换频率 → 是否按阶段调节推理深度/resume 使用率 = resume_count / totalSessions → session 连续性用 2-3 句话总结出用户的 session 驾驭模式(例如:
「典型流程:/plan 规划 → 迭代 → /compact 回收上下文 → 继续交付」)
claude_sessions + codex_threads + kiro_sessions (Step 3b.2) +
trae_workspace_hit (0/1,Step 3c.1) + antigravity_tasks (Step 3d) +
cursor_workspace_hit (0/1,Step 3e.1) + git_commits + git_lines
topic key;能匹配到已有项目 basename 时并入该项目,否则作为 Antigravity
topic bucket。
trae_workspace_hit*2 + cursor_workspace_hit*2 + antigravity_tasks*4 +
git_commits`
Cursor):对每个 Top 12 项目 / topic,按六种工具的活跃度分类:
'kiro' if kiro_sessions>0, 'trae' if trae_workspace_hit>0,
'antigravity' if antigravity_tasks>0, 'cursor' if cursor_workspace_hit>0]`
trae_workspace_hit + antigravity_tasks + cursor_workspace_hit`
<tool> 主导」<A>+<B>)」<A>+<B>+<C>...)」.kiro/ / .trae/ / .cursor/ workspace 配置(3b.5 / 3c.4 / 3e.4),在「编排模式」末尾加 [K] / [T] / [Cu] 角标
cwd basename、GitHub repo 描述 / topics / primary language、Codex thread titles、Claude history first prompts、本地文件名提示(如 package.json 依赖、frontend/、apps/web/、api/)。匿名化只发生在最终输出阶段。deploy、router、ops、docker 等单个工程词,就把一个有明显用户界面或业务功能的产品项目归到“基础设施 / 部署”。| 领域 | 关键词 / 证据(小写匹配 cwd basename + 标题 + 项目信号) |
| --- | --- |
| 产品 / 业务前端 | frontend, front-end, web, app, h5, mobile, miniapp, ui, ux, page, route, router, dashboard, console, admin, portal, client, website, next, react, vue, vite, svelte, tailwind, shadcn, electron, extension, 小程序, 前端, 页面, 官网, 管理台, 控制台, 后台 |
| 产品 / 业务后端 | backend, server, api, service, gateway, worker, queue, job, db, database, prisma, django, fastapi, express, nest, auth, billing, payment, user, backend service, 后端, 服务端, 接口, 鉴权, 支付, 用户 |
| 产品 / 业务全栈 | product, saas, crm, cms, workspace, studio, platform, marketplace, ecommerce, shop, chat, editor, dashboard + api, web + api, app + server, 产品, 业务, 工作台, 平台, 商城 |
| AI 工具 / Skill | skill, claude, codex, agent, subagent, mcp, prompt, workflow, plugin, antigravity, easy_claude, vibe-forge, readme.skill |
| 基础设施 / 部署 | deploy, infra, ops, monitor, observability, k8s, ci-cd, docker, compose, terraform, nginx, ingress, traefik, caddy, api-gateway, gateway infra, healthcheck, log, cron, 自动化部署, 巡检 |
| 数据 / 分析 | analytics, data, dataset, bi, report, metrics, dashboard analytics, crawler, scrape, readyourusers, bibili, 埋点, 数据, 报表, 分析, 采集 |
| ML / RL / 论文 | rllunwen, rl-, ml, model, training, eval, paper, thesis, 论文, 实验, 大创 |
| 文档 / Markdown | readme, doc, docs, documents, markdown, profile, report, handbook, 文档, 手册 |
| 其他 | 证据不足时的 fallback |
React、Next.js、dashboard、API、billing、agent、deploy。project、repo、test、fix、update、misc、code、task。信号不足,不要补想象中的业务特征。Corpus: 拼接 plan titles + Codex thread titles + first_user_messages
+ Antigravity metadata summaries + Antigravity markdown headings
+ 部分 history.text。
Tokenize:
[A-Za-z][A-Za-z0-9_-]+,小写化,长度 ≥ 2,去停用词[\u4e00-\u9fff]+ 串,做 2-char 滑窗,每个 chunk 内去重;过滤明显碎片(如"前项""解当""目了"),过滤含纯停用字的二元
英文停用词(精简):the, a, an, is, are, of, in, on, for, to, by, from, with,
this, that, it, you, we, they, do, does, please, help, use, used, plan,
make, get, just, also, will, would, can.
中文停用字:的 了 是 在 和 有 不 就 也 为 以 对 把 被 从 等 都 这 那 个 啊 呢
吧 呀 之 与 或 及 并 要 做 能 会 上 下 里 们 好 之 吗 一 也 就 都 还 到 去 给
跟 向 自 什 么 怎 哪 如 何 因 所 然 后 比 例 而 且 但 不 过 或 还 关 通 基 由
得 着 过 看 想 说 点 种 次 时 年 月 日 中 时 间 现 在.
输出:top 30 keywords,过滤掉只剩 1 出现的,过滤包含纯英文 stop-only 字符的。
用作"标签云"展示:tag1·N tag2·M tag3·K。
hourCounts (claude) + codex by_hour + history by_hour+ kiro by_hour (3b.1) + Antigravity updatedAt hour (3d) — Trae / Cursor
本地无可靠时间戳粒度,不并入
streak = 最长连续 1 天间隔的串
gh languages.bytes(当前仓库属性)与本地 git numstat ext(窗口内变更)排序commits_per_day = git_local_commits / active_daysloc_churn_per_day = (additions + deletions) / active_daysgithub_contribs_per_active_day = calendar_total / active_daystokens_per_commit / tokens_per_loc)已迁移到 6.10 Token 经济学,6.7 只讲 GitHub / 仓库 / 语言这一维度的目的是回答:如果没有 AI 协作,这种产出可能吗?
计算并叙述:
一个人用 Python + TypeScript + Rust + Go + Shell 跨 13 个仓库日均 10 commit,
这种广度只有 AI 辅助才现实。
「AI 让一个人拥有了小团队的交付能力:13 个仓库、5 门语言、日均 10 commit。」
目的:把静态快照变成成长叙事。让读者看到 AI 使用的成熟度曲线。
时间窗口模式下,本节改为「阶段 Evolution」:只展示窗口内的周/月变化,并用
上一等长周期作为 baseline(如可用)。不要把全量人生时间线塞进月度报告;全量里程碑
最多放 1 句 context。
数据来源:
threads 的 created_at + model + cli_versionhistory.jsonl 的 timestamp + display(斜杠命令)projects/ 目录的 JSONL 文件创建时间updatedAt + artifactType + summaries计算:
/plan 的日期 → Plan-mode 解锁/effort 的日期 → Reasoning effort 解锁/skill-creator 或自研 skill 出现的日期 → Skill 自建解锁/vibe-forge 或 /ssh-prod 的日期 → 自建 skill 投入生产渲染为 timeline 格式:
2026-01 Codex 起步,纯 prompt,CLI 0.81.0-alpha
2026-02 开始日常化,tokens 增长
2026-03 Claude Code 加入 → plan-mode + effort 调节 → 开始自建 skills
2026-04 双工具编排成熟,skills 生态完善,日均 10 commit
目的:不只展示"用了多少 token",而是讲清 token 投入怎么花、Cache leverage 多深、模型迁移如何省了成本。把 token 当 AI 时代的"原材料 + 杠杆"来叙事,不是产出的注脚。
数据来源:
stats-cache.json 的 modelUsage + dailyModelTokensthreads 的 tokens_used + 月度聚合(Step 3.1 已查)Antigravity estimated token-equivalent (non-billing) is a text-scale proxy from local artifacts. Do not add it to claude_tokens_spent, claude_cache_read, codex_tokens, total token-through, cache leverage, paid/new token totals, or per-model token tables. It may appear only in an Antigravity/local-artifact subsection or a clearly labeled footnote.
计算:
claude_spent + codex_tokens(新付费 token 总量)claude_cache_read(缓存复用 token 总量)claude_cache_read / claude_spent(每 1 个新 token 撬动几个缓存 token)model.spent / Σ all_models.spent(Claude 与 Codex 合在一起算)model.cache_read / model.spent(哪个模型 caching 习惯最熟)dailyModelTokens + Codex 月度聚合按月汇总,找增长拐点(例如 <YYYY-MM>: Opus 4.6 spent ↓ 40%,Sonnet 4.6 spent ↑ 60%)
claude_spent / git_commits 与 claude_spent / (additions + deletions)叙事重点:
时间窗口模式下,Token 经济学只统计窗口内 verified token。Claude 只能从
dailyModelTokens 等可按日切分的数据汇总;Codex / Kiro 通过 timestamp SQL 过滤;
Trae / Cursor 云端 token 仍不读取;Antigravity text-scale 仍是 non-billing context,
不进入 token totals。
Before writing the README, scan all string fields for these regex and replace
with <REDACTED:type>:
| pattern | replacement |
| --- | --- |
| sk-[A-Za-z0-9_-]{20,} | <REDACTED:openai-key> |
| sk-ant-[A-Za-z0-9_-]{20,} | <REDACTED:anthropic-key> |
| gh[oprs]_[A-Za-z0-9]{20,} | <REDACTED:github-token> |
| github_pat_[A-Za-z0-9_]{20,} | <REDACTED:github-pat> |
| AKIA[0-9A-Z]{16} | <REDACTED:aws-key> |
| xox[baprs]-[A-Za-z0-9-]{10,} | <REDACTED:slack-token> |
| https://open.feishu.cn/open-apis/bot/v2/hook/[A-Za-z0-9-]+ | <REDACTED:feishu-webhook> |
| \b[\w.+-]+@[\w-]+\.[\w.-]+\b | <REDACTED:email> |
Project name handling (anonymize=on):
项目 A/B/C/...in descending order of comprehensive score (Step 6.4)
Private Repo Xbasename, never the absolute pathIf user said "show real names" / "私人版":
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling
Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification
Take study8677/readme-skill from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.