Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .claude/rules/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ and the 6-trace scene regression gate.
| MCP, memory, report, provider, session, or agent runtime | `cd backend && npm run test:scene-trace-regression` |
| Skill YAML | `cd backend && npm run validate:skills` plus scene trace regression |
| Strategy/template Markdown | `cd backend && npm run validate:strategies` plus scene trace regression |
| Trace corpus, Skill/Strategy coverage, or generator | `npm run trace:regression`; also run the focused Node corpus tests for tooling changes |
| Frontend generated types | `cd backend && npm run generate:frontend-types` plus relevant tests |
| AI plugin UI | Browser verification in `start-dev.sh`, relevant `perfetto/ui` tests/typecheck, then `./scripts/update-frontend.sh` |
| Perfetto upstream sync, trace processor pin, SQL/stdlib index, or committed UI prebuild | Follow `.claude/rules/perfetto-sync.md`; normally `git diff --check`, `npm run check:frontend-prebuild`, `npm --prefix backend run cli:e2e`, scene trace regression, submodule remote reachability, and Skill/Strategy validation when those files changed |
Expand Down Expand Up @@ -97,6 +98,8 @@ The regression uses 6 canonical traces:
| Flutter TextureView | `Scroll-Flutter-327-TextureView.pftrace` |
| Flutter SurfaceView | `Scroll-Flutter-SurfaceView-Wechat-Wenyiwen.pftrace` |

The aliases above resolve through `Trace/catalog.json`; maintained source must not add paths to the retired flat fixture directory. Full release/corpus verification is `npm run trace:regression`. Its report distinguishes positive semantic execution from explicit graceful-empty, unavailable-prerequisite, and definition-only contracts; inventory assignment alone is not a semantic pass.

## Focused Unit Tests

Useful focused suites:
Expand Down Expand Up @@ -128,7 +131,7 @@ Startup:
```bash
cd backend
npx tsx src/scripts/verifyAgentSseScrolling.ts \
--trace ../test-traces/lacunh_heavy.pftrace \
--trace ../Trace/real/android-startup-heavy/trace.pftrace \
--query "分析启动性能" \
--output test-output/e2e-startup.json \
--keep-session
Expand Down Expand Up @@ -184,13 +187,13 @@ rendering pipelines differ:
```bash
cd backend
npx tsx src/scripts/verifyAgentSseScrolling.ts \
--trace "../test-traces/Scroll-Flutter-327-TextureView.pftrace" \
--trace "../Trace/real/flutter-scroll-texture-view/trace.pftrace" \
--query "分析 Flutter 滑动性能" \
--output test-output/e2e-flutter-textureview.json \
--keep-session

npx tsx src/scripts/verifyAgentSseScrolling.ts \
--trace "../test-traces/Scroll-Flutter-SurfaceView-Wechat-Wenyiwen.pftrace" \
--trace "../Trace/real/flutter-scroll-surface-view/trace.pftrace" \
--query "分析 Flutter 滑动性能" \
--output test-output/e2e-flutter-surfaceview.json \
--keep-session
Expand All @@ -202,13 +205,13 @@ Fast/full mode:
cd backend
npx tsx src/scripts/verifyAgentSseScrolling.ts \
--mode fast \
--trace ../test-traces/scroll-demo-customer-scroll.pftrace \
--trace ../Trace/real/android-scroll-customer/trace.pftrace \
--query "这个 trace 的应用包名和主要进程是什么?" \
--output test-output/e2e-fast.json

npx tsx src/scripts/verifyAgentSseScrolling.ts \
--mode full \
--trace ../test-traces/scroll-demo-customer-scroll.pftrace \
--trace ../Trace/real/android-scroll-customer/trace.pftrace \
--query "分析滑动性能" \
--output test-output/e2e-full.json
```
Expand Down
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ backend/logs/
*.log

# Test data & outputs
test-traces/
Trace/
backend/test-output/
coverage/

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/backend-agent-regression-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ on:
- ".dockerignore"
- "docker-compose*.yml"
- "scripts/trace-processor-pin.env"
- "test-traces/**"
- "Trace/**"
- ".github/dependabot.yml"
- ".github/workflows/**"
push:
Expand All @@ -37,7 +37,7 @@ on:
- ".dockerignore"
- "docker-compose*.yml"
- "scripts/trace-processor-pin.env"
- "test-traces/**"
- "Trace/**"
- ".github/dependabot.yml"
- ".github/workflows/**"

Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,8 @@ providers.json

# Local E2E evidence (may contain Trace-derived data and machine paths)
/output/
.gstack/

# Trace corpus private staging and materialized constructed outputs
/Trace/real/.private/
/Trace/.generated/
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ smp report <sessionId> --open

# Record an Android trace from a connected device, then analyze it.
smp capture presets
smp capture suggest "Analyze Camera open-to-first-preview latency" --app com.example.camera
smp capture config --preset camera --app com.example.camera --duration 20
smp capture android --preset startup --app com.example.app --duration 10 --out launch.perfetto-trace
smp capture android --preset cpu --app '*' --duration 30 --categories dalvikviktime my_custom_tag --out cpu-custom.perfetto-trace
smp capture android --preset power --app com.example.app --duration 60 --out power.perfetto-trace
Expand All @@ -318,6 +320,14 @@ smp capture android --config ~/tools/perfetto_shell/perfetto.config --out ~/tool
smp repl
```

The `camera` preset collects Camera/HAL/vendor atrace candidates, Binder and
scheduler context, FrameTimeline, and DMA-BUF or legacy ION ftrace events. The
atrace candidates and memory ftrace events are optional; availability depends
on the Android release, device/vendor implementation, and kernel support. A
trace may still lack portable Camera open, request/result, buffer, or preview
presentation anchors; SmartPerfetto reports that evidence gap instead of
fabricating an open-to-first-frame number.

The npm CLI package is the supported standalone terminal product. It does not start or bundle the Web UI launcher; use Docker or a GitHub portable package when you need the browser experience. The first analysis uses the bundled pinned `trace_processor_shell` binary when available, and can download the pinned binary automatically on unsupported targets. Android capture itself never downloads tools at runtime: `adb` is resolved from `ADB_PATH`, an approved bundled slot, then `PATH`; pre-Android Q or `--sideload` tracebox capture requires an approved bundled `tracebox` or `--tracebox /path/to/tracebox`. If your network cannot reach Google's artifact bucket, set `TRACE_PROCESSOR_PATH=/path/to/trace_processor_shell` to use a local binary, or set `TRACE_PROCESSOR_DOWNLOAD_BASE` / `TRACE_PROCESSOR_DOWNLOAD_URL` to a trusted mirror; downloaded binaries are still checked against the pinned SHA256. `smartperfetto` remains available as the long command name; source checkout scripts are only for maintainers debugging the CLI. See [CLI Reference](docs/reference/cli.en.md) for all commands, capture presets, REPL slash commands, storage layout, and resume behavior.

## API Integration
Expand Down
9 changes: 9 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ smp report <sessionId> --open

# 从已连接 Android 设备抓 trace,并可直接分析。
smp capture presets
smp capture suggest "分析 Camera 打开到首帧预览延迟" --app com.example.camera
smp capture config --preset camera --app com.example.camera --duration 20
smp capture android --preset startup --app com.example.app --duration 10 --out launch.perfetto-trace
smp capture android --preset cpu --app '*' --duration 30 --categories dalvikviktime my_custom_tag --out cpu-custom.perfetto-trace
smp capture android --config ~/tools/perfetto_shell/perfetto.config --out ~/tools/perfetto_shell/trace/dut-game-launch.ptrace --analyze --query "分析应用启动"
Expand All @@ -312,6 +314,13 @@ smp capture android --config ~/tools/perfetto_shell/perfetto.config --out ~/tool
smp repl
```

`camera` 预设会采集设备可能提供的 Camera/HAL/厂商 atrace 候选、Binder 与
scheduler 上下文、FrameTimeline,以及 DMA-BUF 或旧版 ION ftrace 事件。atrace
候选和这些内存 ftrace 事件均为可选证据,具体是否可用取决于 Android 版本、
设备/厂商实现与内核支持。trace 仍可能缺少可移植的 Camera open、request/result、
buffer 或预览 presentation 锚点;遇到这种证据缺口时,SmartPerfetto 会明确报告
缺失,而不会编造“打开到首帧”耗时。

npm CLI 包是正式独立终端产品,不启动也不包含 Web UI launcher;需要浏览器体验时使用 Docker 或 GitHub 免安装包。第一次分析时,CLI 会优先使用包内固定版本 `trace_processor_shell`;当前平台没有内置 binary 时会自动下载固定版本。Android 抓 trace 本身不会现场下载工具:`adb` 按 `ADB_PATH`、已批准的包内 slot、`PATH` 顺序解析;Android Q 之前或显式 `--sideload` 的 tracebox 抓取需要已批准的包内 `tracebox`,或通过 `--tracebox /path/to/tracebox` 指定。若网络无法访问 Google artifact bucket,可以设置 `TRACE_PROCESSOR_PATH=/path/to/trace_processor_shell` 使用本机已有 binary,或设置 `TRACE_PROCESSOR_DOWNLOAD_BASE` / `TRACE_PROCESSOR_DOWNLOAD_URL` 指向可信镜像;下载内容仍会按固定 SHA256 校验。`smartperfetto` 仍保留为长命令名;源码 checkout 里的脚本只用于维护者调试 CLI。完整命令、抓取预设、REPL slash 命令、存储布局和 resume 语义见 [CLI 参考](docs/reference/cli.md)。

## API 接入
Expand Down
61 changes: 61 additions & 0 deletions Trace/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<!-- Generated by Trace/tools/trace-corpus.cjs. Do not edit by hand. -->
# SmartPerfetto Trace Corpus

This directory is the source-controlled trace test and reference corpus.

- [Real trace cases](./real/README.md): 6
- [Constructed trace cases](./constructed/README.md): 12
- [Machine-readable catalog](./catalog.json)
- [Skill and Strategy coverage](./coverage.json)

Skill execution quality: 131 semantic, 10 explicit graceful-empty, 3 explicit unavailable prerequisite, 87 definition-only.

## Commands

`npm run trace:validate` checks manifests, hashes, generated indexes, publication gates, legacy path coupling, and exact current Skill/Strategy inventory coverage.

`npm run trace:build` deterministically materializes every base-plus-overlay case under ignored `Trace/.generated/` and reparses it with the pinned trace processor.

`npm run trace:regression` validates, builds, and executes the complete deterministic corpus. Per-case evidence is written below `Trace/.generated/constructed/<case-id>/`.

## Add a real case

Stage a capture privately first; repeat `--result`, `--log`, and `--tag` as needed:

`node Trace/tools/trace-corpus.cjs import-real --id typical-startup --title "Typical startup" --description "Representative cold start" --scene startup --trace /path/to/trace.pftrace --origin "maintainer capture" --result /path/to/result.json --log /path/to/session.log --android-release 16 --api-level 36 --device "Pixel"`

The command copies evidence atomically into ignored `Trace/real/.private/<id>/`. Review the trace and manifest before publication. Promotion requires explicit approvals and rolls back if catalog validation fails:

`node Trace/tools/trace-corpus.cjs promote-real typical-startup --license CC-BY-4.0 --consent owner-approved --privacy-review approved --sanitization-review approved`

## Extend constructed cases

Constructed cases keep source scenarios and overlay protobufs in Git; combined traces are generated. Copy [the scenario template](./constructed/_templates/scenario.example.json), declare Android compatibility in `case.json`, assign each target explicitly, then run `npm run trace:regression`. Adding a Skill or Strategy without a current expectation fails validation. Use separate case ids with non-overlapping API ranges when Android behavior differs.

## Real cases

| Case | Scene | Android | Publication | Analysis |
| --- | --- | --- | --- | --- |
| [Android 16 customer scroll](./real/android-scroll-customer/) | scrolling | Android 16 / API 36 | legacy-tracked | 1 file(s) |
| [Android 15 standard AOSP scroll](./real/android-scroll-standard/) | scrolling | Android 15 / API 35 | legacy-tracked | 1 file(s) |
| [Android 16 heavy startup](./real/android-startup-heavy/) | startup | Android 16 / API 36 | legacy-tracked | 1 file(s) |
| [Android 16 light startup](./real/android-startup-light/) | startup | Android 16 / API 36 | legacy-tracked | 1 file(s) |
| [Android 15 Flutter SurfaceView scroll](./real/flutter-scroll-surface-view/) | scrolling | Android 15 / API 35 | legacy-tracked | 1 file(s) |
| [Android 15 Flutter TextureView scroll](./real/flutter-scroll-texture-view/) | scrolling | Android 15 / API 35 | legacy-tracked | 1 file(s) |

## Constructed cases

| Case | Scene | Android | Base | Coverage |
| --- | --- | --- | --- | --- | --- |
| [Binder, lock, and I/O blocking](./constructed/binder-io-blocking/) | io | Android 16 / API 36 (tested API 35-36) | android-startup-heavy | 25 target(s) |
| [Framework rendering pipeline signatures](./constructed/framework-pipelines/) | pipeline | Android 16 / API 36 (tested API 35-36) | android-startup-heavy | 33 target(s) |
| [General analysis and runtime contracts](./constructed/general-runtime-contracts/) | general | Android 16 / API 36 (tested API 35-36) | android-scroll-customer | 14 target(s) |
| [GPU workload and frequency](./constructed/gpu-workload/) | gpu | Android 16 / API 36 (tested API 35-36) | android-scroll-customer | 10 target(s) |
| [Input and interaction latency](./constructed/input-interaction-latency/) | interaction | Android 16 / API 36 (tested API 35-36) | android-scroll-customer | 13 target(s) |
| [Linux and Android system state](./constructed/linux-system-state/) | linux | Android 16 / API 36 (tested API 35-36) | android-startup-light | 5 target(s) |
| [Media, network, and camera pipeline](./constructed/media-network-camera/) | media | Android 16 / API 36 (tested API 35-36) | android-scroll-customer | 8 target(s) |
| [Memory and GC pressure](./constructed/memory-gc-pressure/) | memory | Android 16 / API 36 (tested API 35-36) | android-startup-light | 19 target(s) |
| [Power and thermal throttling](./constructed/power-thermal/) | power | Android 16 / API 36 (tested API 35-36) | android-scroll-customer | 19 target(s) |
| [Rendering pipeline jank](./constructed/rendering-jank/) | scrolling | Android 16 / API 36 (tested API 35-36) | android-scroll-customer | 46 target(s) |
| [Scheduler and CPU contention](./constructed/scheduler-cpu-contention/) | cpu | Android 16 / API 36 (tested API 35-36) | android-scroll-customer | 36 target(s) |
| [Startup and process lifecycle](./constructed/startup-lifecycle/) | startup | Android 16 / API 36 (tested API 35-36) | android-startup-heavy | 24 target(s) |
Loading