# pi-charles

[English](./README.md) | [中文](./README.zh-CN.md)

**面向 [pi](https://pi.dev) coding agent 的 Charles Proxy 分析工具包。**

npm 包名：[`pi-charles`](https://www.npmjs.com/package/pi-charles)

设计原则：工具只做数据通道——取数据、过滤、呈现；推理交给 agent。

## 核心机制

### Checkpoint 时间线

每次调用 `harvest_data()` 会：

1. 导出当前 Charles session
2. 只保留上次收割之后的新条目（按 `times.start` 毫秒时间戳）
3. 写入内存 **ARCHIVE**
4. 在时间线上追加一个 **checkpoint**
5. 清空 Charles session 并重启录制（保持导出轻量）

用 `load_checkpoint(n)` 可回到任意历史窗口，所有过滤工具自动在该窗口内工作。

### 资源文件占位符

图片 / JS / CSS / 二进制 body 会替换为 `[image/png 45.2KB]` 形式的占位符。agent 可知类型与大小，需要时再调 `get_raw_data`。

### 关键词互锁

`filter_by_keyword` 匹配数 > 30 时，须先调用 `check_keyword_exists`，避免一次性灌入大量 body 撑爆上下文。

## 前置条件

Charles Proxy 已启动，并开启 Web Interface：**Proxy → Web Interface Settings**

- 勾选 **Enable web interface**
- 默认无用户名密码（anonymous），可通过 `/charles` 或 `CHARLES_USER`/`CHARLES_PASS` 覆盖

## 安装

### npm（推荐）

```bash
pi install npm:pi-charles
```

### Git

```bash
pi install git:github.com/geebos/pi-charles
pi install git:github.com/geebos/pi-charles@v1.0.0
```

### GitHub Packages（可选）

发布名为 `@geebos/pi-charles`（平台要求 scope）：

```bash
# ~/.npmrc
# @geebos:registry=https://npm.pkg.github.com
# //npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN

pi install npm:@geebos/pi-charles
```

### 本地开发

```bash
git clone https://github.com/geebos/pi-charles.git
cd pi-charles
npm install
pi -e ./extensions/index.ts
# 或
pi install ./
```

## 配置命令：`/charles`

在 pi 内配置 Charles 连接（界面文案为英文）：

```text
/charles              打开设置界面（TUI）
/charles show         查看当前配置
/charles test         测试 Charles 连接
/charles reset        恢复默认值
/charles set user <v> 设置用户名
/charles set pass <v> 设置密码
/charles set host <v> 设置代理主机
/charles set port <v> 设置代理端口
```

| 配置项 | 默认值 | 说明 |
| --- | --- | --- |
| Username | (空) | Charles Web Interface 用户名（可选）  |
| Password | (空) | Charles Web Interface 密码（可选）  |
| Proxy host | `control.charles` | Charles HTTP 代理地址 |
| Proxy port | `80` | Charles HTTP 代理端口 |

配置写入 `~/.pi/agent/extensions/pi-charles/config.json`，保存后立即生效。

优先级：**环境变量 > 配置文件 > 默认值**。

## 工具

### 收割

| 工具 | 说明 |
| --- | --- |
| `harvest_data(fresh_start?)` | 增量收割并创建 checkpoint。`fresh_start=true` 插入重置点 |
| `load_recording(file_path)` | 加载本地 `.chlsj` 录包 |

### 时间线

| 工具 | 说明 |
| --- | --- |
| `list_checkpoints()` | 列出所有 checkpoint |
| `load_checkpoint(checkpoint_id)` | 切换到指定 checkpoint 窗口 |

### 概览

| 工具 | 说明 |
| --- | --- |
| `summarize_traffic()` | host / path / 状态码 / 方法分布 |

### 过滤

| 工具 | 说明 |
| --- | --- |
| `filter_by_host(host_keyword)` | 按域名过滤 |
| `filter_by_path(path_keyword)` | 按 URL 路径过滤 |
| `filter_by_method(method)` | 按 HTTP 方法过滤 |
| `filter_by_status(status_code)` | 按 HTTP 状态码过滤 |
| `check_keyword_exists(keyword)` | 探测关键词位置，解锁 `filter_by_keyword` |
| `filter_by_keyword(keyword)` | 返回含关键词的条目预览 |
| `filter_by_encryption(threshold?)` | 香农熵扫描疑似加密 body |

### 详情 / 环境

| 工具 | 说明 |
| --- | --- |
| `get_raw_data(entry_id)` | 获取完整原始数据 |
| `set_throttling(preset?)` | 开启 / 关闭弱网模拟（会话结束自动还原） |

## 典型工作流

```text
harvest_data()
summarize_traffic()
filter_by_host("api.xxx")
filter_by_encryption()
get_raw_data(entry_id)
```

切换分析目标：

```text
harvest_data({ fresh_start: true })
# 在 App 中触发目标操作
harvest_data()
```

回溯历史：

```text
list_checkpoints()
load_checkpoint({ checkpoint_id: 2 })
filter_by_keyword({ keyword: "sign" })
```

## 环境变量

| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `CHARLES_USER` | `pi-charles` | Web Interface 用户名 |
| `CHARLES_PASS` | `123456` | Web Interface 密码 |
| `CHARLES_PROXY_HOST` | `127.0.0.1` | 代理地址 |
| `CHARLES_PROXY_PORT` | `8888` | 代理端口 |

## 发布

推送版本 tag 会跑两个工作流（仅 tag 触发，避免与 Release 重复发布）：

| 工作流 | 仓库 | 包名 |
| --- | --- | --- |
| **Publish to npm** | npmjs.com | `pi-charles` |
| **github-publish** | GitHub Packages | `@geebos/pi-charles` |

```bash
git tag v1.0.0
git push origin v1.0.0
```

手动重发已有 tag：Actions → 对应 workflow → **Run workflow** → 输入 `v1.0.0`。

### npm Trusted Publishing（无需 token）

`Publish to npm` 使用 [Trusted Publishing](https://docs.npmjs.com/trusted-publishers)（OIDC），**不要**配置 `NPM_TOKEN`。

在 npmjs.com → **pi-charles** → **Settings** → **Trusted Publisher** 配置一次：

| 字段 | 值 |
| --- | --- |
| Provider | GitHub Actions |
| Organization or user | `geebos` |
| Repository | `pi-charles` |
| Workflow filename | `publish-npm.yml` |
| Allowed actions | `npm publish` |

要求：Node 24 / npm ≥ 11.5.1（workflow 已配置），`permissions.id-token: write`。

### GitHub Packages

使用自动提供的 `GITHUB_TOKEN`（`packages: write`），无需额外 secret。

## 致谢

本项目由 Python FastMCP 项目
[tianhetonghua/Charles-mcp-server](https://github.com/tianhetonghua/Charles-mcp-server)
迁移为 TypeScript [pi](https://pi.dev) 插件包。

## License

[MIT](./LICENSE)
