burrows99/trace-cli
GitHub: burrows99/trace-cli
trace-cli 是一款面向 AI agent 的运行时追踪与静态分析 CLI 工具,通过非暂停断点和统一的 JSON 信封格式帮助 agent 理解软件的真实运行行为。
Stars: 2 | Forks: 0
# trace-cli


执行追踪器与分析器。将它指向一个正在运行的程序,为其设置断点和触发器 -> **一个 JSON 信封**:按顺序排列的每一次命中(调用栈、局部变量、监控的表达式、计时),在 Node 和 Chrome 中具有完全相同的结构。静态分析(调用图、依赖、复杂度、符号)无需运行任何内容即可输出相同的信封。
**断点永远不会暂停。** 它们被配置为非暂停的 *logpoint* —— 每次命中都会发送其调用栈、所有在作用域内的局部变量(从源码读取,无需命名),以及任何 `--expression`,然后 VM 会继续保持全速运行。它是为读取追踪信息并重新调整断点的 Agent 构建的,而不是为手动单步调试的人类构建的。
```
trace-cli run breakpoints + a trigger → a full trace (Node curl · Chrome journey + video, via CDP)
trace-cli graph | deps | complexity | symbols code structure without running it
trace-cli serve collector + realtime dashboard: every trace, live
trace-cli doctor | schema which backing tools are installed · the output JSON Schema
```
Chrome 运行还会录制一段 **debug-replay 视频** —— 断点面板(调用栈/局部变量/监控)旁边的实时屏幕画面,并与每次命中的节奏同步:

*一个结账总额丢失了美分;随着 bug 的累积,面板逐步显示 `sum: 0 → 19 → 43`。 ▶ [全分辨率 mp4](docs/assets/checkout-replay.mp4)。*
## 安装说明
- **CLI / 库 (npm):** `npm i -g trace-cli` 安装全局的 `trace-cli`,或者 `npm i trace-cli` 用于导入类。Node ≥ 18。
- **Claude Code 插件** (捆绑了 `trace` 技能 + `bin/` 二进制文件):
claude plugin marketplace add /path/to/trace-cli
claude plugin install trace@trace-oss
- `trace-cli doctor` 会报告存在哪些底层支持工具 (chrome, ffmpeg, language servers, …)。
原生优先:`run`、`graph`、`deps`、`complexity`、`symbols`、`doctor`、`schema` 均直接在主机上运行 —— 无需 Docker。Docker 仅用于可选的收集器(见下文)。
## 使用方法
一个引擎,一个协议驱动程序 —— JS 家族(Node `--inspect` 和 Chrome)使用 **CDP**。
```
# Node:attach 到一个 --inspect port,发起一次 curl,追踪该请求
trace-cli run --node 9229 \
--curl 'curl -s http://localhost:3000/v1/dashboard' \
--breakpoint src/dashboard/dashboard.service.ts:149 \
--expression 'user.id'
# Chrome:在 --remote-debugging-port 上驱动一个脚本化的 UI 旅程,录制屏幕 + trace-panel 视频
trace-cli run --chrome 9222 --breakpoint src/pages/Login.tsx:42 \
--url http://localhost:3000/login --step 'type:#email=me@example.com' --step 'click:text=Sign in'
# ……或者省略 port — 该 CLI 会启动一个一次性的 headless Chrome,进行追踪、录制,并在完成后将其销毁
trace-cli run --chrome --url http://localhost:5173/route --breakpoint src/pages/Route.tsx:42
```
- **观察位置:** `--breakpoint `,可重复使用。作用域内的局部变量会被自动捕获;`--expression ''` 可以为每次命中添加计算值。
- **驱动方式:** Node -> `--curl`。Chrome -> `--url`(单次导航)和/或 `--step` —— 一个有序的旅程(`goto`/`click`/`type`/`waitfor`/`wait`/`newtab`/`eval`;`text=…` 或 CSS 选择器)。Chrome 至少需要 1 个 `--breakpoint`。
- **输出:** `stdout` = 追踪渲染;`--json [path]` 输出信封(使用 `--concise` 为 Agent 精简内容,使用 `--detailed` 获取所有信息);`stderr` = 结构化日志 (`-v`/`-q`)。退出码 `0` 正常 · `1` 运行时错误 · `2` 用法错误。
- **Chrome 始终会录制** 回放 -> 如果设置了 `S3_ENDPOINT` 则上传到 S3 (`data.recording.url`),否则使用本地路径;可以使用 `--output ` 覆盖。`console.*` 和未捕获的异常会记录在 `data.console` 中。
## 实时仪表板
`trace-cli serve` 是一个 **收集器 + 实时 Web 仪表板**(独立的 Next.js:通过 SSE 展示会话列表 + 每个追踪的调用栈、局部变量、监控表达式、突变谱系和回放视频的时间线)。

```
export DATABASE_URL=postgres://user:pass@localhost:5432/trace
trace-cli serve --port 4000 # → http://localhost:4000 (table auto-created, no migrations)
```
任何追踪都会 **自动流式传输到本地运行的收集器** —— 无需额外标志。可以使用 `--emit ` 或 `TRACE_COLLECTOR_URL` 覆盖目标地址。每个信封都会成为 `trace_sessions` 表中的一行(JSONB + 摘要);Chrome 回传会上传到 S3 并在页面内播放。API: `POST /v1/traces` · `GET /api/sessions[/:id]` · `GET /api/stream` (SSE)。
Docker Compose 捆绑了仪表板、Postgres 和一个用于模拟的 S3,只需一条命令即可完成本地设置:
```
docker compose up --build # dashboard :4747 · Postgres :5432 · S3 :9000
# 然后从可以访问到目标的原生环境中运行该 CLI;它会自动检测 collector
export S3_ENDPOINT=http://localhost:9000
trace-cli run --chrome 9222 --url http://localhost:3000 --breakpoint src/App.tsx:9
```
## 静态分析
无需运行任何内容即可分析 **代码结构** —— 输出相同的信封,不需要实时的目标。
```
trace-cli graph --entry src/auth/auth.service.ts:42:9 # call graph (also file@symbol); root + LSP server auto-detected
trace-cli deps --entry src/index.ts # module-import graph + circular groups (madge)
trace-cli complexity src # per-function cyclomatic complexity (lizard)
trace-cli symbols src/app.ts # a file's definition outline (tree-sitter)
```
`graph` 使用了基于 LSP 的真实 **语言服务器**(`prepareCallHierarchy` + `callHierarchy/outgoingCalls`) —— 也就是 IDE 中的 *Show Call Hierarchy* 引擎,因此它在 DI、接口和导入方面都能保持类型准确,而不是基于正则表达式的猜测。内置了 TS/JS 支持;对于其他语言,可以通过 `--server` 指向任何支持调用层级的 LSP(`pyright`、`gopls`、`rust-analyzer`、`clangd`、`jdtls`)。
## 追踪信封
每个子命令都会发出相同的信封;只有 `data` 会有所不同。`Event` 是统一的标准 —— CDP 命中、一个 span 以及 UI 操作最终都会成为同一时间线上的 `Event`(通过 `source` + `sessionId` 进行跨源关联)。
```
{
"tool": "trace", "command": "run.node", "ok": true,
"meta": { "sessionId": "…", "durationMs": 142 },
"target": { "kind": "node", "source": "cdp", "trigger": "curl …" },
"data": {
"breakpoints": [ { "file": "server.js", "line": 42, "bound": true } ],
"events": [ { "sequence": 1, "kind": "breakpoint", "location": { "file": "server.js", "line": 42 },
"label": "priceFor", "time": 12, "attributes": { "stack": ["…"], "locals": {}, "exprs": {} } } ],
"lineage": [ { "name": "total", "kind": "expr", "changes": 2,
"series": [ { "sequence": 1, "value": 0 }, { "sequence": 2, "value": 9.99, "changed": true } ] } ],
"response": { "exitCode": 0, "body": "…" }
},
"diagnostics": []
}
```
**突变谱系** (`data.lineage`) 是 *派生* 出来的:针对每一个被监控的值,展示它随着流程的继续是如何变化的(`total: 0 → 9.99 → 14.49`) —— 即跨命中次数的值随时间变化情况,而不是单次命中的快照。完整 schema:`trace-cli schema`。
## 试用
`test/servers/` 下提供了示例服务器 —— 一个 Node 订单 API 和一个 React 结账页面,各自植入了一个 bug:
```
# Node
PORT=3100 node --inspect=9230 test/servers/node-api/server.js &
trace-cli run --node 9230 --curl 'curl -s "http://127.0.0.1:3100/checkout?cart=widget:2,gadget:1&coupon=SAVE10®ion=US"' \
--breakpoint "test/servers/node-api/server.js@subtotal += it.lineTotal" --expression subtotal --expression 'it.sku'
# React (Chrome) — 通过 Vite source maps 的前端;仅使用 --chrome 即可启动 headless Chrome 本身
( cd test/servers/react-app && npm install && npm run dev ) & # :5180
trace-cli run --chrome --url http://localhost:5180 \
--breakpoint "test/servers/react-app/src/price.ts@sum = sum + parseInt" --expression sum
```
首先运行 `trace-cli serve`(或者 `docker compose up`),两者都会实时显示在仪表板中。`test/servers/scenarios.sh` 可以运行全套场景。
## 路线图
- **已构建:** Node · 基于 CDP 的 Chrome(附加接入或自动启动,脚本化旅程 + 回放视频) · 静态分析 (`graph`/`deps`/`complexity`/`symbols`) · 收集器 + 仪表板 · Docker。
- **下一步**(相同的信封格式):通过第二个 `ProtocolDriver` 支持 **DAP 语言** (Python, Go, Java, C/C++) · OTel span 摄取 · 跨层级的 `traceparent` 握手。详见 [`docs/MIGRATION.md`](docs/MIGRATION.md)。
## 贡献
欢迎提交 Issue 或 PR。请从 `master` 分支拉取代码,保持类优先/领域驱动的代码布局,并运行 `npm test`(它会先进行构建)。新的追踪目标需要实现 `ProtocolDriver`;新的静态分析器则是 `src/cli/commands/` 下的一个 `TraceCommand` —— 两者都遵循相同的信封标准。
## 许可证
MIT © 2026 Raunak Burrows —— 详见 [LICENSE](LICENSE)。
库 (TypeScript)
``` import { DynamicCommand, Trace } from "trace-cli"; // DynamicCommand powers `trace run` const { trace } = await new DynamicCommand().run({ target: "node", port: 9229, curl: 'curl -s http://127.0.0.1:3100/price?qty=3', breakpoints: ["test/servers/node-api/server.js:42"], }); const envelope = trace.toJSON(); // domain → wire JSON const restored = Trace.fromPlain(envelope); // rehydrate a stored envelope ``` 同样导出的有:`Tracer`、`CdpDriver` (`ProtocolDriver`)、`LineageAnalyzer`、`Recorder`、`S3ArtifactStore`、`Collector`/`PostgresSessionStore`。标签:AI智能体, Chrome DevTools Protocol, GNU通用公共许可证, MITM代理, Node.js, SOC Prime, 云安全监控, 动态追踪, 开发工具, 测试用例, 自动化攻击, 请求拦截, 静态分析