Readme.skill — AI-Native 开发者档案生成器
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 withRead, query sqlite viaBash, synthesize the prose yourself, then write and validate the SVG. Do not write helper scripts; the skill is the recipe.
支持的 6 个 AI 编程工具(任一缺失都自动降级跳过):
- Claude Code (
~/.claude/) — Step 2- Codex CLI (
~/.codex/) — Step 3- Kiro CLI / IDE (
~/.kiro/+~/.local/share/kiro-cli/) — Step 3b- Trae IDE (
~/Library/Application Support/Trae/+ 项目.trae/) — Step 3c- Gemini Antigravity (
~/.gemini/antigravity/brain/) — Step 3d- Cursor (
~/Library/Application Support/Cursor/+ 项目.cursor/) — Step 3e
默认行为:对外分享版 —— 项目名匿名、敏感信息脱敏。 如果用户明确说"私人版 / 不要脱敏 / show real names",跳过匿名步骤。
Step 1 — 准备
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.
1.1 时间窗口 / 月度报告模式
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:
- Single month:
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 - Month range:
2026-04 到 2026-05,Apr-May 2026→ start at the first day of the first month, end at the first day after the last month,REPORT_MODE=range - Explicit dates:
2026-05-03 到 2026-05-19/2026-05-03..2026-05-19→ include both named dates by settingREPORT_END_EXCLto the day after the final date,REPORT_MODE=range - Relative 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)
Step 2 — 读取 Claude Code 数据 (~/.claude/ + 项目 .claude/)
2.1 预聚合统计(最权威,先看这个)
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 聚合,未纳入窗口统计」,不要把全局值混进
月度值。
2.2 Slash-command 热度
~/.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 各自次数。
2.3 项目分布 (~/.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
2.4 计划与 skill 自研
Claude Code 的 plan 文件目录不是固定值。默认在 ~/.claude/plans,
但用户可以通过 plansDirectory 改到项目工作目录下,例如
"./.claude/plans"。统计 plans 时必须先解析候选 plan 目录,不能只枚举
~/.claude/plans/*.md。
解析规则:
- 先从
~/.claude/projects/*/*.jsonl的cwd字段恢复 Claude Code 访问过的项目根目录。 - 对每个项目根目录,按 Claude Code settings 优先级读取:
.claude/settings.local.json>.claude/settings.json>~/.claude/settings.json> default。 - 如果有效 settings 中存在
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
2.4b Skill 清单(AI 基础设施采集)
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,标记为自建;否则标记为安装。
2.5 配置深度
Read ~/.claude/settings.json. Count:
hooks个数(结构化自动化能力)mcpServers个数(外部能力接入)permissions.defaultMode
Step 3 — 读取 Codex CLI 数据 (~/.codex/)
3.1 SQLite (read-only)
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;"
3.2 Codex 全局历史
~/.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
3.3 自研 artifacts
ls ~/.codex/skills/ | wc -l # codex skills
ls ~/.codex/automations/ | wc -l # scheduled automations
ls ~/.codex/rules/ | wc -l # custom rules
Step 3b — 读取 Kiro 数据 (~/.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/ 是否存在,不存在直接跳过本节。
3b.1 总量与 token 细分 (SQLite, read-only)
[ -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,不参与月度指标。
3b.2 ACP Session 文件 (JSON + JSONL)
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 # 关键词语料
3b.3 Kiro 基础设施层(agents / skills / steering / prompts / mcp)
跟 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」。
3b.4 Knowledge bases(实验功能,可选)
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 原文。
3b.5 工作区 .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+ 标记。
3b.6 Kiro 数据来源不可读时的诚实声明
如果 Kiro 安装但 data.sqlite3 不存在(用户只用过 IDE 桌面版,未跑 CLI),
本步骤仅能采集到 Steering / Agents / Skills 配置数,不要编造 session / token 数字。
在最终报告的「Kiro 章节」明确写:「Kiro CLI 数据未生成,本节仅展示 Steering /
Agents / Skills 配置;如需完整 session/token 统计请先运行 Kiro CLI。」
Step 3c — 读取 Trae 数据 (~/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
进程写操作。先检测目录是否存在,不存在直接跳过本节。
3c.1 工作区数量与项目分布
# 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
3c.2 Chat 元数据(SQLite, read-only)
每个工作区有自己的 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 或关键词。
强烈降级提示:
- Trae chat 的 key 格式没有公开稳定文档。如果
LIKE没匹中任何 row, 老老实实在报告里写「Trae 本地 chat 仅检测到 workspace 数量 N,对话内容 key 命名约定本工具暂不解析」,不要编造 session 数。 - 如果工作区目录为空或
state.vscdb文件不存在,直接跳过该工作区。
3c.3 Token 用量 —— 仅云端,本地无法读
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
3c.4 项目 .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」。
3c.5 Trae 数据缺失时的诚实声明
~/Library/Application Support/Trae/不存在 → 完全跳过本节- 存在但工作区 chat key 解析失败 → 仅展示「打开过的项目数 +
.trae/配置」 - token 数据永远缺失 → 明确写「本地未持有,需经云端 API 拉取,本 skill 不联网」
Step 3d — 读取 Gemini Antigravity 数据 (~/.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.jsonfor artifact metadata and summariestask.md,implementation_plan.md,walkthrough.md- text variants ending in
.resolved,.resolved.0,.resolved.1, etc.
Never read for analytics:
- screenshots or images (
*.png,*.webp,*.jpg,*.jpeg) ~/.gemini/antigravity/annotations/*.pbtxt~/.config/Antigravity/*browser/cache data- browser profiles or cache directories
AG_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 ofbrain/<uuid>/directories.antigravity_artifacts_by_type= counts byartifactType.antigravity_active_days= unique dates from validupdatedAtvalues.antigravity_first_active/antigravity_last_active= min/max validupdatedAtdates.antigravity_monthly_activity= monthly counts from validupdatedAtvalues.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.
Step 3e — 读取 Cursor 数据 (~/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
进程写操作。先检测目录是否存在,不存在直接跳过本节。
3e.1 工作区数量与项目分布
# 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
3e.2 Chat / Composer 元数据(SQLite, read-only)
全局聚合库在 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 |
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 数。
3e.3 Token 用量 —— 本地部分可见,权威数字仅云端
Cursor Pro 的精确 token 用量在云端 dashboard。本机 ItemTable 里可能含有
部分 token 元数据(比如 aiService.applyAiHistory 等 key 内嵌 JSON
里会有 input/output token 字段),但 schema 不稳定也未公开。
本 skill 的策略:
- 不发起任何网络请求,云端 dashboard 永远不读。
- 如果能从
ItemTable里靠 jq 抽出 token 字段 → 作为参考值展示,明确 注明「Cursor 本地估算 token,非云端 dashboard 计费值」。 - 抽不出来就老实说「Cursor token 数据由 Anysphere 云端 dashboard 持有, 本 skill 出于『100% 本地 + 只读』原则不接入」。
3e.4 项目 .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」。
3e.5 Cursor 数据缺失时的诚实声明
~/Library/Application Support/Cursor/不存在 → 完全跳过 Step 3e- 存在但
composer.composerHeaders缺失 → 降级用 composer/chat key 计数与 workspace folder - 存在但工作区 chat key 解析失败 → 仅展示「打开过的工作区数 +
.cursor/配置」 - token 数据本地不可信 → 明确写「权威 token 在云端 dashboard,本 skill 不联网; 本地估算仅作参考」
Step 4 — GitHub (via 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.
Step 5 — 本地 Git 提交
Build the candidate path set from:
- Real
cwdrecovered for each~/.claude/projects/<encoded>/ cwdcolumn from Codexthreadstablecwdfield in Kiro~/.kiro/sessions/cli/*.jsonfolderfield in TraeUser/workspaceStorage/*/workspace.json
Dedupe 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 ofCOMMIT|lines)additions,deletions(sum the numstat columns)last_commit_iso- Per-extension LOC (count
+-per file extension → top 10 languages)
Step 6 — 计算 10 个维度(你做推理,不要写脚本)
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:
- activity delta: active days, Claude sessions/messages, Codex threads, Antigravity tasks, Kiro sessions, Trae/Cursor workspace signals
- output delta: GitHub contributions, local commits, LOC churn, active repos
- AI investment delta: verified Claude/Codex/Kiro tokens, Claude cache leverage
- mix shift: top tools, top domains, top projects, model migration, command mix
- narrative conclusion: 2-4 bullets answering "这个阶段 AI 编码带来了什么效果 / 发生了什么变化"
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.
6.1 一览
- 总活跃天数 = unique union of all dates from
dailyActivity(Claude) + Codexby_date+ Claudehistory by_date- Kiro
by_date(3b.1) +antigravity_active_days(3d) + Trae / Cursor 工作区最后访问日期(如果能从workspace.json或state.vscdb的 mtime 推断;推不出就略过这两项)
- Kiro
- 跨度 =
min..maxof those dates - 总 sessions / 总消息 / claude_spent(Σ input+output+cache_creation)
/ 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 数)
—— 这些数字必须出现在「一览」里,缺失项显示
—,不要省略行 - 同期 GitHub: commits, PRs, issues, calendar_total
- 本地 git: commits / +additions / −deletions / repos
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.
- Velocity 指标(v2.0 新增):
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 repos
6.2 AI-Native 实践(核心章节)
- 多工具 / 多模型编排: 列出每个模型的 spent / cache_read tokens。
- Claude / Codex / Kiro model breakdown 合并到同一张 token 表(Kiro schema 有 model 列时按 3b.1 抽取)。
- Trae / Cursor 的 token 数据本地不可信(云端权威),表中标注 「Trae: 云端 only」/「Cursor: 云端权威,本地仅参考」。
- Gemini Antigravity 的 tasks/artifacts 单列展示,token 不可得时显示
—,不要估算。 - 总编排维度 = 同时活跃使用的 AI 工具数(Claude / Codex / Kiro / Trae / Antigravity / Cursor 六选 N)。用过 ≥ 3 个工具 → 报告里强调「多引擎 编排者」叙事。
- 高级能力使用: plan-mode 次数、effort 调节次数、skill 调用次数、 自研 skills 数、hooks/MCP 数、plans/tasks 数、automations 数
- Antigravity 任务制协作:
antigravity_tasks、artifact type breakdown、 walkthrough / implementation_plan / task artifacts,用来描述「从任务 → 计划 → walkthrough」的交付闭环。 - Prompt caching 熟练度: cache_to_spent_ratio
- Reasoning effort 分布: xhigh/high/medium/low 占比
- AI 基础设施层(v2.0 新增 —— 这是最 AI-native 的信号):
列出用户亲手构建的 skills / hooks / automations / rules / steering / agents,
每项给
名称 | 一句话描述 | 来源(Claude/Codex/Kiro/Trae)| 调用次数(如可从 history 统计)。 区分「自建」(用户原创)与「安装」(第三方)。 跨工具复用的 skill(同名 SKILL.md 同时出现在~/.claude/skills/和~/.kiro/skills/)单独高亮 —— 这是真正的 AI 基础设施互操作信号。 这一段的叙事重点:不只是 AI 的使用者,更是 AI 工作流的建设者。
6.3 协作风格
- Top 10 slash commands (cmd, count, 简短解读)
- Plan-to-direct ratio =
/plan count / non-command prompt count - 平均消息/session =
totalMessages / totalSessions - 最长 session: 时长(小时) + 消息数
- Session 架构(v2.0 新增):
从 history.jsonl 中按 sessionId 分组,统计典型 session 内的命令序列模式:
- 以
/plan开头的 session 占比 → 说明「先想再做」的习惯有多强 - session 内使用
/compact或/clear的比例 → 上下文管理意识 /effort在 session 内的切换频率 → 是否按阶段调节推理深度/resume使用率 = resume_count / totalSessions → session 连续性 用 2-3 句话总结出用户的 session 驾驭模式(例如: 「典型流程:/plan 规划 → 迭代 → /compact 回收上下文 → 继续交付」)
- 以
6.4 项目与领域
- 合并维度: each project key (real_cwd) accumulates `claude_session
…(truncated)