perfetto-analyzer 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # perfetto-analyzer
2
+
3
+ AI skill for Android performance analysis using [Perfetto](https://perfetto.dev).
4
+
5
+ Automatically installs into all supported AI agents on your machine.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ # Run once — installs for all supported agents
11
+ npx perfetto-analyzer install
12
+
13
+ # Or install globally (auto-installs via postinstall)
14
+ npm install -g perfetto-analyzer
15
+ ```
16
+
17
+ ## Supported AI Agents
18
+
19
+ | Agent | Skills directory |
20
+ |---|---|
21
+ | Claude Code | `~/.claude/skills/perfetto-analyzer/` |
22
+ | GitHub Copilot | `~/.github/copilot/skills/perfetto-analyzer/` |
23
+ | Cursor | `~/.cursor/skills/perfetto-analyzer/` |
24
+ | Antigravity | `~/.antigravity/skills/perfetto-analyzer/` |
25
+ | Codex (OpenAI) | `~/.codex/skills/perfetto-analyzer/` |
26
+ | Devin | `~/.devin/skills/perfetto-analyzer/` |
27
+
28
+ Directories are created automatically if they don't exist.
29
+
30
+ ## Uninstall
31
+
32
+ ```bash
33
+ npx perfetto-analyzer uninstall
34
+ ```
35
+
36
+ ## What it does
37
+
38
+ After installation, ask your AI assistant to analyze an Android app's performance:
39
+
40
+ - **Collect a trace** from a connected device via `adb`
41
+ - **Analyze CPU, memory, frames (jank), and battery** from a `.pb` Perfetto trace
42
+ - **Generate a markdown report** with insights and actionable recommendations
43
+
44
+ ### Prerequisites
45
+
46
+ - `adb` installed and in PATH (Android SDK Platform-Tools)
47
+ - Python 3.9+
48
+ - `pip install perfetto`
49
+
50
+ ## Usage example
51
+
52
+ > "Analyze the performance of com.myapp.debug, collect a 30s frames trace"
53
+
54
+ The skill will:
55
+ 1. Verify the device is connected
56
+ 2. Launch the app if it isn't running
57
+ 3. Collect the Perfetto trace
58
+ 4. Parse callstacks and frame timelines
59
+ 5. Generate a report with hotspots and jank causes
60
+
61
+ ## License
62
+
63
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require("path");
4
+ const fs = require("fs");
5
+ const os = require("os");
6
+
7
+ const SKILL_NAME = "perfetto-analyzer";
8
+ const SKILL_SRC = path.join(__dirname, "..", "skill");
9
+
10
+ const AGENTS = [
11
+ { name: "Claude Code", dir: path.join(os.homedir(), ".claude", "skills") },
12
+ { name: "GitHub Copilot", dir: path.join(os.homedir(), ".github", "copilot", "skills") },
13
+ { name: "Cursor", dir: path.join(os.homedir(), ".cursor", "skills") },
14
+ { name: "Antigravity", dir: path.join(os.homedir(), ".antigravity", "skills") },
15
+ { name: "Codex", dir: path.join(os.homedir(), ".codex", "skills") },
16
+ { name: "Devin", dir: path.join(os.homedir(), ".devin", "skills") },
17
+ ];
18
+
19
+ function copyDir(src, dest) {
20
+ fs.mkdirSync(dest, { recursive: true });
21
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
22
+ const srcPath = path.join(src, entry.name);
23
+ const destPath = path.join(dest, entry.name);
24
+ if (entry.isDirectory()) {
25
+ copyDir(srcPath, destPath);
26
+ } else {
27
+ fs.copyFileSync(srcPath, destPath);
28
+ }
29
+ }
30
+ }
31
+
32
+ function removeDir(dir) {
33
+ if (fs.existsSync(dir)) {
34
+ fs.rmSync(dir, { recursive: true, force: true });
35
+ return true;
36
+ }
37
+ return false;
38
+ }
39
+
40
+ function padEnd(str, len) {
41
+ return str + " ".repeat(Math.max(0, len - str.length));
42
+ }
43
+
44
+ function install(silent) {
45
+ if (!silent) {
46
+ console.log(`\nInstalling ${SKILL_NAME} skill...\n`);
47
+ }
48
+
49
+ for (const agent of AGENTS) {
50
+ const dest = path.join(agent.dir, SKILL_NAME);
51
+ try {
52
+ copyDir(SKILL_SRC, dest);
53
+ if (!silent) {
54
+ console.log(` ✓ ${padEnd(agent.name, 16)} → ${dest}`);
55
+ }
56
+ } catch (err) {
57
+ console.error(` ✗ ${padEnd(agent.name, 16)} ERRO: ${err.message}`);
58
+ }
59
+ }
60
+
61
+ if (!silent) {
62
+ console.log(`\nDone! Restart your AI assistant to activate the skill.\n`);
63
+ }
64
+ }
65
+
66
+ function uninstall() {
67
+ console.log(`\nRemoving ${SKILL_NAME} skill...\n`);
68
+
69
+ for (const agent of AGENTS) {
70
+ const dest = path.join(agent.dir, SKILL_NAME);
71
+ const removed = removeDir(dest);
72
+ if (removed) {
73
+ console.log(` ✓ ${padEnd(agent.name, 16)} removed`);
74
+ } else {
75
+ console.log(` - ${padEnd(agent.name, 16)} not found (skipped)`);
76
+ }
77
+ }
78
+
79
+ console.log(`\nDone!\n`);
80
+ }
81
+
82
+ function showHelp() {
83
+ console.log(`
84
+ ${SKILL_NAME} — AI skill for Android performance analysis using Perfetto
85
+
86
+ Usage:
87
+ npx ${SKILL_NAME} Install skill for all supported AI agents
88
+ npx ${SKILL_NAME} install Install skill for all supported AI agents
89
+ npx ${SKILL_NAME} uninstall Remove skill from all AI agent directories
90
+ npx ${SKILL_NAME} help Show this help
91
+
92
+ Supported agents:
93
+ ${AGENTS.map((a) => ` - ${a.name}`).join("\n")}
94
+ `);
95
+ }
96
+
97
+ const args = process.argv.slice(2);
98
+ const command = args[0] || "install";
99
+ const isPostinstall = args.includes("--postinstall");
100
+
101
+ switch (command) {
102
+ case "install":
103
+ install(isPostinstall);
104
+ break;
105
+ case "uninstall":
106
+ uninstall();
107
+ break;
108
+ case "help":
109
+ case "--help":
110
+ case "-h":
111
+ showHelp();
112
+ break;
113
+ default:
114
+ console.error(`Unknown command: ${command}`);
115
+ showHelp();
116
+ process.exit(1);
117
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "perfetto-analyzer",
3
+ "version": "1.0.0",
4
+ "description": "AI skill for Android performance analysis using Perfetto — works with Claude Code, Cursor, GitHub Copilot, Codex, Antigravity and Devin",
5
+ "bin": {
6
+ "perfetto-analyzer": "bin/cli.js"
7
+ },
8
+ "files": [
9
+ "bin/",
10
+ "skill/"
11
+ ],
12
+ "scripts": {
13
+ "postinstall": "node bin/cli.js install --postinstall"
14
+ },
15
+ "keywords": [
16
+ "android",
17
+ "perfetto",
18
+ "performance",
19
+ "tracing",
20
+ "claude",
21
+ "cursor",
22
+ "copilot",
23
+ "codex",
24
+ "skill",
25
+ "ai-agent"
26
+ ],
27
+ "license": "MIT",
28
+ "engines": {
29
+ "node": ">=14"
30
+ }
31
+ }
package/skill/SKILL.md ADDED
@@ -0,0 +1,234 @@
1
+ ---
2
+ name: perfetto-analyzer
3
+ description: >
4
+ Analisa performance de apps Android usando Perfetto — abstrai adb, configuração de traces e interpretação de métricas.
5
+ Use quando o usuário quiser medir performance de um app Android, coletar traces, analisar memória (heap), CPU,
6
+ frames dropados, battery drain, ou quando mencionar Perfetto, profiling, trace .pb, jank, ANR, ou quiser entender
7
+ gargalos de performance no Android. Também use quando o usuário tiver um arquivo .pb do Perfetto e quiser insights.
8
+ Dispare mesmo que o usuário não mencione Perfetto explicitamente — se ele falar em "app lento", "memória crescendo",
9
+ "frames dropando", "CPU alta", "bateria acabando rápido" no contexto Android, esta skill é o caminho.
10
+ ---
11
+
12
+ # Perfetto Analyzer
13
+
14
+ Você é especialista em performance Android usando Perfetto. Seu papel é:
15
+ 1. **Coletar traces** via `adb` (Modo A) ou **analisar traces existentes** (Modo B)
16
+ 2. **Interpretar métricas** de memória, CPU, frames e battery
17
+ 3. **Gerar relatório markdown** com insights e recomendações acionáveis
18
+
19
+ ---
20
+
21
+ ## Antes de começar — perguntas obrigatórias
22
+
23
+ Antes de executar qualquer script, colete as informações necessárias perguntando ao usuário. **Nunca assuma valores padrão para duração ou tipo de trace** — são escolhas do usuário, não técnicas.
24
+
25
+ **Modo A (Coleta automática)** — device Android conectado:
26
+
27
+ Pergunte explicitamente (em uma única mensagem):
28
+ 1. **Package** do app — se não souber, sugira `adb shell pm list packages | grep <nome>` para descobrir
29
+ 2. **Tipo de trace** — apresente as opções: `frames` (jank/UI), `memory` (heap/leak), `cpu` (bottlenecks), `battery` (drain), `all` (análise completa)
30
+ 3. **Duração** — quantos segundos de gravação? Dica: 10–15s para fluxos específicos, 30s+ para leaks/battery
31
+
32
+ Só execute o script após ter as três respostas.
33
+
34
+ **Modo B (Análise de trace existente)** — usuário tem arquivo `.pb`:
35
+ → Precisa apenas do caminho do arquivo. Prossiga diretamente para a análise.
36
+
37
+ Se não ficou claro qual modo o usuário quer, pergunte antes de qualquer ação.
38
+
39
+ ---
40
+
41
+ ## Pré-requisitos
42
+
43
+ | Ferramenta | Como verificar | Instalação |
44
+ |---|---|---|
45
+ | `adb` | `adb version` | Android SDK Platform-Tools |
46
+ | Python 3.9+ | `python3 --version` | python.org |
47
+ | `perfetto_trace_processor` (Python) | `python3 -c "import perfetto"` | `pip install perfetto` |
48
+
49
+ Verifique antes de executar. Se faltar algo, oriente o usuário.
50
+
51
+ ---
52
+
53
+ ## Modo A — Coleta via adb
54
+
55
+ ### 1. Verificar device conectado
56
+
57
+ ```bash
58
+ adb devices
59
+ ```
60
+
61
+ Se `no devices` ou `offline`, oriente o usuário a:
62
+ - Ativar Opções do Desenvolvedor no Android
63
+ - Ativar Depuração USB
64
+ - Aceitar a permissão no device
65
+
66
+ ### 2. Coletar o trace
67
+
68
+ Execute o script de coleta:
69
+
70
+ ```bash
71
+ python3 <SKILL_DIR>/scripts/collect_trace.py \
72
+ --package <PACKAGE> \
73
+ --type <TRACE_TYPE> \
74
+ --duration <SEGUNDOS> \
75
+ --output /tmp/perfetto_trace.pb
76
+ ```
77
+
78
+ Onde `<TRACE_TYPE>` é um dos: `memory`, `cpu`, `frames`, `battery`, `all`
79
+
80
+ O script vai:
81
+ - Empurrar a config pro device via `adb push`
82
+ - Executar `adb shell perfetto` com a config
83
+ - Aguardar a duração especificada
84
+ - Puxar o arquivo `.pb` para `/tmp/perfetto_trace.pb`
85
+
86
+ Aguarde e mostre progresso ao usuário (o trace pode levar alguns segundos).
87
+
88
+ Após coleta bem-sucedida, prossiga para a etapa de análise.
89
+
90
+ ### 3. Instalar dependências se necessário
91
+
92
+ ```bash
93
+ pip install perfetto 2>/dev/null || pip3 install perfetto
94
+ ```
95
+
96
+ ---
97
+
98
+ ## Modo B — Análise de trace existente
99
+
100
+ Use o arquivo `.pb` fornecido como entrada para a análise.
101
+
102
+ ```bash
103
+ cp <ARQUIVO_DO_USUARIO> /tmp/perfetto_trace.pb
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Análise do Trace
109
+
110
+ ### Passo 1: Parsing
111
+
112
+ ```bash
113
+ python3 <SKILL_DIR>/scripts/parse_perfetto_pb.py \
114
+ --input /tmp/perfetto_trace.pb \
115
+ --output /tmp/perfetto_parsed.json \
116
+ --package <PACKAGE>
117
+ ```
118
+
119
+ O script extrai via SQL queries na Trace Processor API:
120
+ - Alocações de heap (nativo + ART)
121
+ - Samples de CPU por callstack
122
+ - Frame timeline (frames renderizados vs dropados)
123
+ - Contadores de battery
124
+
125
+ ### Passo 2: Análise de métricas
126
+
127
+ ```bash
128
+ python3 <SKILL_DIR>/scripts/analyze_metrics.py \
129
+ --input /tmp/perfetto_parsed.json \
130
+ --output /tmp/perfetto_insights.json
131
+ ```
132
+
133
+ Calcula: top callstacks, percentis de frame, anomalias, recomendações.
134
+
135
+ ### Passo 3: Gerar relatório
136
+
137
+ ```bash
138
+ python3 <SKILL_DIR>/scripts/generate_report.py \
139
+ --insights /tmp/perfetto_insights.json \
140
+ --package <PACKAGE_OU_UNKNOWN> \
141
+ --trace-type <TIPO_OU_all>
142
+ ```
143
+
144
+ O relatório vai para stdout. Apresente ao usuário formatado como markdown.
145
+
146
+ ---
147
+
148
+ ## Formato do Relatório
149
+
150
+ O relatório gerado segue este template. Apresente-o completo, sem truncar:
151
+
152
+ ```markdown
153
+ # Relatório de Performance — <package>
154
+ **Dispositivo:** <device> | **Data:** <data> | **Duração:** <Xs> | **Tipo:** <tipo>
155
+
156
+ ## Resumo Executivo
157
+ > Top 3-5 findings mais críticos, em ordem de impacto
158
+
159
+ ## Memória
160
+ ### Maiores Alocadores (Heap Nativo)
161
+ <tabela: callstack | bytes não-liberados | % total>
162
+
163
+ ### Objetos Java/Kotlin Retidos (ART)
164
+ <tabela: classe | instâncias | bytes>
165
+
166
+ ### Alertas
167
+ - ⚠️ [se heap churn alto, possível leak, etc.]
168
+
169
+ ## CPU
170
+ ### Top Funções (Self Time)
171
+ <tabela: função | thread | % CPU>
172
+
173
+ ### Callstacks Mais Frequentes
174
+ <top 5 por ocorrência>
175
+
176
+ ### Alertas
177
+ - ⚠️ [se main thread bloqueada, GC excessivo, etc.]
178
+
179
+ ## Frames
180
+ | Métrica | Valor | Threshold OK |
181
+ |---|---|---|
182
+ | Total de frames | N | — |
183
+ | Frames dropados | N (X%) | < 1% |
184
+ | Frame P50 | Xms | < 16ms |
185
+ | Frame P95 | Xms | < 32ms |
186
+ | Frame P99 | Xms | < 50ms |
187
+
188
+ ### Causas de Jank
189
+ <tabela: causa | ocorrências>
190
+
191
+ ## Battery
192
+ | Métrica | Valor |
193
+ |---|---|
194
+ | Carga drenada | X mC (miliCoulombs) |
195
+ | Duração do trace | Xs |
196
+ | Taxa média de drain | X mC/s |
197
+
198
+ ### Top Consumidores
199
+ <tabela: componente | consumo estimado>
200
+
201
+ ## Recomendações
202
+ 1. **[Título]** — [Descrição do problema + ação concreta]
203
+ 2. ...
204
+
205
+ ## Próximos Passos
206
+ - [ ] Verificar X em flame graph no perfetto.dev/ui
207
+ - [ ] Correlacionar Y com Z
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Referências
213
+
214
+ Leia estes arquivos quando precisar de mais contexto:
215
+
216
+ | Arquivo | Quando ler |
217
+ |---|---|
218
+ | `references/perfetto-traces-reference.md` | Quais traces coletar, configs textproto, quando usar cada um |
219
+ | `references/metrics-interpretation.md` | O que significa cada métrica, thresholds, red flags |
220
+ | `references/adb-quick-start.md` | Setup adb, troubleshooting de device, permissões |
221
+
222
+ ---
223
+
224
+ ## Erros Comuns
225
+
226
+ **`no devices/emulators found`** → Verificar USB debugging e `adb devices`
227
+
228
+ **`ImportError: No module named 'perfetto'`** → `pip install perfetto`
229
+
230
+ **`Error opening trace file`** → Arquivo .pb corrompido ou versão incompatível do Perfetto. Tentar reabrir no perfetto.dev/ui para validar.
231
+
232
+ **Trace vazio ou sem dados** → App pode não ter sido usada durante a coleta. Instruir o usuário a interagir com o app durante a gravação.
233
+
234
+ **`permission denied` no device** → `adb shell su -c perfetto ...` (requer root) ou usar heapprofd com `run-as`
@@ -0,0 +1,139 @@
1
+ # ADB Quick Start — Setup para Perfetto
2
+
3
+ ## Instalação do adb
4
+
5
+ ### macOS
6
+ ```bash
7
+ brew install android-platform-tools
8
+ # ou baixar manualmente:
9
+ # https://developer.android.com/tools/releases/platform-tools
10
+ ```
11
+
12
+ ### Linux (Ubuntu/Debian)
13
+ ```bash
14
+ sudo apt install android-tools-adb
15
+ ```
16
+
17
+ ### Verificar instalação
18
+ ```bash
19
+ adb version
20
+ # Android Debug Bridge version 1.0.41
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Conectar device
26
+
27
+ ### Via USB (recomendado para traces)
28
+
29
+ 1. No Android: **Configurações → Sobre o dispositivo → Número da compilação** (toque 7x)
30
+ 2. **Configurações → Opções do desenvolvedor → Depuração USB** → Ativar
31
+ 3. Conectar cabo USB
32
+ 4. Aceitar prompt "Permitir depuração USB?" no device (marque "Sempre permitir")
33
+
34
+ ```bash
35
+ adb devices
36
+ # List of devices attached
37
+ # XXXXXXXX device ← OK
38
+ # XXXXXXXX offline ← Precisa aceitar no device
39
+ # XXXXXXXX unauthorized ← Precisa aceitar no device
40
+ ```
41
+
42
+ ### Via Wi-Fi (Android 11+)
43
+
44
+ 1. **Opções do desenvolvedor → Depuração sem fio**
45
+ 2. **Parear device** → anotar IP:porta
46
+ 3. `adb pair <ip>:<porta>`
47
+ 4. `adb connect <ip>:<porta>`
48
+
49
+ **Atenção:** Traces via Wi-Fi podem ser mais lentos para fazer `pull`. Para traces grandes (> 50 MB), prefira USB.
50
+
51
+ ---
52
+
53
+ ## Troubleshooting
54
+
55
+ ### `no devices/emulators found`
56
+ ```bash
57
+ # Reiniciar servidor adb
58
+ adb kill-server
59
+ adb start-server
60
+ adb devices
61
+ ```
62
+
63
+ ### `device offline` ou `unauthorized`
64
+ - Desconectar e reconectar cabo
65
+ - Aceitar prompt no device
66
+ - Se persistir: **Opções do desenvolvedor → Revogar autorizações de depuração USB** e re-autorizar
67
+
68
+ ### `permission denied` ao executar Perfetto no device
69
+
70
+ O Perfetto requer permissão para coletar traces. Em Android 9+, o `traced` daemon já está rodando e aceita conexões de apps com permissão ou via shell.
71
+
72
+ ```bash
73
+ # Verificar se traced está rodando
74
+ adb shell pgrep -a traced
75
+
76
+ # Se não estiver:
77
+ adb shell setprop persist.traced.enable 1
78
+ adb shell start traced
79
+ adb shell start traced_probes
80
+ ```
81
+
82
+ Para heap profiling (heapprofd), o app precisa ser debuggable OU o device precisa estar rootado:
83
+ ```bash
84
+ # Verificar se app é debuggable
85
+ adb shell pm dump <PACKAGE> | grep DEBUGGABLE
86
+ ```
87
+
88
+ Se o app não for debuggable, use um build de debug ou:
89
+ ```bash
90
+ # Root: habilitar profiling em release builds
91
+ adb shell setprop security.perf_harden 0
92
+ ```
93
+
94
+ ### `Error: Detach failed`
95
+
96
+ Alguns devices exigem:
97
+ ```bash
98
+ adb shell "echo 0 > /proc/sys/kernel/perf_event_paranoid"
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Coleta manual via adb (referência)
104
+
105
+ O método mais robusto usa `adb exec-out` com stdin/stdout — sem gravar nada no device:
106
+
107
+ ```bash
108
+ # Config via stdin, trace via stdout — sem permissões no device
109
+ cat frames.textproto | adb exec-out perfetto --txt -c - -o - > /tmp/trace.pb
110
+ ```
111
+
112
+ Funciona em emuladores e devices físicos porque:
113
+ - `--txt` indica config em texto (textproto)
114
+ - `-c -` lê a config de stdin
115
+ - `-o -` escreve o trace em stdout
116
+ - `adb exec-out` transfere binário sem conversão de newlines (ao contrário de `adb shell`)
117
+
118
+ **Importante:** Não use `-o /sdcard/...` — o daemon do Perfetto roda com UID diferente do shell e não tem permissão de escrita no sdcard. Use stdout (`-o -`) ou `/data/misc/perfetto-traces/` (que exige pull separado).
119
+
120
+ ---
121
+
122
+ ## Comandos úteis durante troubleshooting de trace
123
+
124
+ ```bash
125
+ # Ver logs do sistema em tempo real
126
+ adb logcat -s perfetto traced heapprofd
127
+
128
+ # Verificar se o traced daemon está rodando
129
+ adb shell pgrep -a traced
130
+
131
+ # Ativar daemon manualmente se não estiver rodando
132
+ adb shell setprop persist.traced.enable 1 && adb shell start traced
133
+
134
+ # Listar processos do app
135
+ adb shell ps -ef | grep <PACKAGE>
136
+
137
+ # Ver PID do app (útil para heapprofd)
138
+ adb shell pidof <PACKAGE>
139
+ ```