Metadata-Version: 2.4
Name: ai-code-stats
Version: 0.1.0
Summary: 统计 CodingAgent (Claude Code / Codex) 的 AI 代码采纳率、AI 代码行数与 token 消耗，按 git 仓库 × 提交人维度上报
Author: ai-code-stats
License: MIT
Keywords: claude-code,codex,git,metrics,ai-coding
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Provides-Extra: http
Requires-Dist: requests>=2.25; extra == "http"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: jsonschema>=4.0; extra == "dev"

# ai-code-stats

统计 **CodingAgent（Claude Code / Codex）生成代码的采纳率、AI 代码行数与 token 消耗**，
按 **git 仓库 × 提交人** 维度，在每次提交时上报。上报后端可插拔（HTTP / 本地文件 / 自定义命令），
数据用带版本的 JSON Schema 定义，跨 macOS / Windows / Linux。

> 📖 **完整使用说明（安装/配置/上报示例/排查）见 [docs/USAGE.md](docs/USAGE.md)。**

## 它能回答什么

- 这次提交里 **AI 写了多少行**、**人最终采纳了多少**（采纳率）。
- 每次提交的 **总代码行数 / AI 代码行数 / AI 占比**，分「全量」和「有效代码」两种口径。
- 这次提交关联的 AI **token 消耗**（input / output / cache）。

## 工作原理

```
 AI 编辑 (PostToolUse 钩子)            git 提交 (post-commit / post-merge 钩子)
 ┌─────────────────────────┐         ┌──────────────────────────────────────┐
 │ 解析 Edit/Write/apply_patch│        │ 取 commit 变更（含重命名检测）          │
 │ 新增行 → 归一化 + 哈希      │  ───▶  │ 与窗口内 AI 指纹做「多重集消费式匹配」    │
 │ 标记是否「有效代码」        │ pending│ 算 采纳率 / AI 占比 / token             │
 │ 落 .git/ai-code-stats/      │        │ 组 JSON 信封 → 派发各 Reporter          │
 └─────────────────────────┘         └──────────────────────────────────────┘
```

- **采纳率** = 落入本次 commit 的 AI 行数 / 窗口内 AI 生成的行数。
- **AI 占比** = 匹配到 AI 指纹的 commit 新增行 / commit 总新增行。
- 匹配基于**归一化内容哈希**，所以即使 AI 写的代码被移动到别的文件也能命中。

## 安装

需要 Python ≥ 3.9 与 git。

```bash
pip install ai-code-stats          # 或：pip install -e .（开发）

# 在目标仓库根目录执行，安装 git 钩子 + Claude + Codex 钩子
ai-code-stats install

# 只装某一项 / 预览不写入
ai-code-stats install --git
ai-code-stats install --claude --scope user      # 写 ~/.claude/settings.json
ai-code-stats install --codex --dry-run

# 卸载（幂等，保留你自己的钩子内容）
ai-code-stats uninstall
```

> Codex 钩子写入 `$CODEX_HOME/config.toml`（默认 `~/.codex/config.toml`）。由于 Codex 钩子
> schema 仍在演进，安装后建议 `ai-code-stats install --codex --dry-run` 核对，并确认你的
> Codex 版本支持内联 `[[hooks.PostToolUse]]`。

## 配置

解析顺序（后者覆盖前者）：内置默认 → 用户级 `config.json` → 仓库 `.ai-code-stats.json` →
`AI_CODE_STATS_CONFIG` 指向的文件。字符串支持 `${ENV:VAR}` 注入密钥。

```jsonc
{
  "enabled": true,
  "privacy": {
    "store_plaintext": true,     // 本地是否保留 AI 行明文（仅落在 .git/ 内）
    "redact_in_reports": true    // 上报只含统计数字，不含源码
  },
  "files": {
    "include": [],               // 为空=按已知代码扩展名统计；非空=只统计匹配项
    "exclude": ["**/node_modules/**", "**/*.min.js", "package-lock.json"]
  },
  "attribution": {
    "count_modes": ["raw", "effective"],
    "primary": "effective",      // 主指标用「有效代码」口径
    "merge_strategy": "skip",    // merge 提交：skip 或 first_parent
    "detect_renames": true
  },
  "reporters": [
    { "type": "json_file", "path": "{repo_data}/reports.jsonl" },
    { "type": "http_webhook",
      "url": "https://metrics.example.com/ingest",
      "headers": { "Authorization": "Bearer ${ENV:AI_CODE_STATS_TOKEN}" },
      "mapping": {                // 把信封映射成任意后端 schema（点路径取值）
        "repo": "data.repo_id",
        "rate": "data.ai.effective.adoption_rate",
        "tokens": "data.tokens.total"
      }
    },
    { "type": "command", "argv": ["my-forwarder"] }  // 信封 JSON 经 stdin 传入
  ]
}
```

### 统计口径

- **raw（全量）**：所有新增/删除行。
- **effective（有效代码）**：剔除空行与纯注释行（按语言注释语法识别）。

### 文件过滤

默认只统计已知代码语言扩展名的文件，并排除 lock 文件、生成产物、vendored 目录、二进制。
可用 `files.include` / `files.exclude`（glob，支持 `**`）定制。

## 数据契约

`schemas/` 下三份带版本的 JSON Schema：

| Schema | 用途 |
|--------|------|
| `ai_edit_event.schema.json` | 单次 AI 编辑事件（本地暂存） |
| `commit_stat.schema.json`   | 一次提交的完整统计 |
| `report_envelope.schema.json` | 上报统一信封 |

信封示例：

```json
{
  "schema_version": "1.0",
  "kind": "commit_stat",
  "produced_at": "2026-06-15T08:00:00Z",
  "producer": { "plugin": "ai-code-stats", "version": "0.1.0", "os": "darwin" },
  "data": {
    "repo_id": "github.com/org/repo",
    "commit": { "sha": "…", "branch": "main", "is_merge": false },
    "committer": { "name": "Dev", "email": "dev@x.com" },
    "totals": { "files_changed": 2, "raw": { "lines_added": 5 }, "effective": { "lines_added": 3 } },
    "ai": {
      "raw":       { "ai_lines_added": 4, "adoption_rate": 1.0, "ai_share_of_commit": 0.8 },
      "effective": { "ai_lines_added": 3, "adoption_rate": 1.0, "ai_share_of_commit": 1.0 }
    },
    "tokens": { "input": 120, "output": 30, "total": 150 }
  }
}
```

## 常用命令

```bash
ai-code-stats status              # 查看待归因事件与 token 快照
ai-code-stats report              # 打印当前 HEAD 的统计信封（不发送、不消费）
ai-code-stats flush               # 重试发送失败的上报队列
```

## 隐私

- AI 行**明文只落在仓库内 `.git/ai-code-stats/`**，不会被提交（在 `.git/` 下）。
- 上报默认 `redact_in_reports=true`，**只发统计数字**，不含源码。
- 需要更强隐私可设 `privacy.store_plaintext=false`，本地只存哈希。

## 已知限制

- `merge` 提交默认跳过归因（diff 含合并噪声），可配 `first_parent`。
- `rebase` / `cherry-pick` / `commit --amend` 下采纳率为近似值。
- token 归属按「自上次提交以来该 session 的累计增量」估算，跨多仓库并行会有近似。

## 开发

```bash
PYTHONPATH=src python3 -m pytest        # 运行测试
PYTHONPATH=src python3 -m ai_code_stats.cli --help
```

架构分层：`agents/`（Agent 适配）· `classify`（过滤/分类）· `attribution`（归因）·
`tokens`（token 聚合）· `reporters/`（可插拔上报）· `githook/`（提交统计）· `install/`（安装器）。
新增上报后端：实现 `reporters/base.Reporter` 并在 `reporters/registry.REPORTER_TYPES` 注册。
新增 Agent：实现 `agents/base.AgentAdapter` 并在 `agents/registry` 注册。
