burrows99/trace-cli

GitHub: burrows99/trace-cli

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

Stars: 2 | Forks: 0

# trace-cli ![license MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![node >=18](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg) 执行追踪器与分析器。将它指向一个正在运行的程序,为其设置断点和触发器 -> **一个 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 视频** —— 断点面板(调用栈/局部变量/监控)旁边的实时屏幕画面,并与每次命中的节奏同步: ![Debug replay — Chrome journey + live trace panel](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/578823bcd4144456.gif) *一个结账总额丢失了美分;随着 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` 中。
库 (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`。
## 实时仪表板 `trace-cli serve` 是一个 **收集器 + 实时 Web 仪表板**(独立的 Next.js:通过 SSE 展示会话列表 + 每个追踪的调用栈、局部变量、监控表达式、突变谱系和回放视频的时间线)。 ![Realtime dashboard — a Chrome session with its replay video and mutation lineage](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/7c32fae102144501.png) ``` 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)。
标签:AI智能体, Chrome DevTools Protocol, GNU通用公共许可证, MITM代理, Node.js, SOC Prime, 云安全监控, 动态追踪, 开发工具, 测试用例, 自动化攻击, 请求拦截, 静态分析