perfetto-analyzer 1.0.1 → 1.0.3
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/CHANGELOG.md +30 -0
- package/package.json +3 -2
- package/skill/scripts/parse_perfetto_pb.py +5 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.0.3] - 2026-07-09
|
|
4
|
+
|
|
5
|
+
### Corrigido
|
|
6
|
+
- **`parse_perfetto_pb.py`** — Dados de frames vazios em devices físicos. O fallback para Android < 12 usava correspondência exata do nome do slice (`'Choreographer#doFrame'`), mas em muitos devices físicos o nome vem com sufixo de frame number (`'Choreographer#doFrame 12345'`). Corrigido usando `LIKE 'Choreographer#doFrame%'` e `LIKE '%DrawFrame%'`.
|
|
7
|
+
|
|
8
|
+
## [1.0.2] - 2026-07-09
|
|
9
|
+
|
|
10
|
+
### Corrigido
|
|
11
|
+
- **`generate_report.py`** — `TypeError: 'NoneType' object is not subscriptable` ao gerar relatório de traces do tipo `battery`. Ocorria quando `thread_name` estava presente no dicionário com valor `None` (amostras de CPU sem thread associada). Corrigido em 4 ocorrências com `(value or "?")[:N]` no lugar de `value[:N]`.
|
|
12
|
+
- **`memory.textproto`** — App travava durante coleta de memória por causa do `block_client: true` no heapprofd, que bloqueava as threads do app a cada chamada `malloc()`. Alterado para `block_client: false`.
|
|
13
|
+
- **`memory.textproto`** — Reduzido `sampling_interval_bytes` de `4096` para `8192` para diminuir o overhead de profiling.
|
|
14
|
+
- **`all.textproto`** — Mesmas correções de `block_client` e `sampling_interval_bytes` aplicadas ao tipo `all`.
|
|
15
|
+
- **`all.textproto`** — Adicionado `android.java_hprof` que estava ausente: o tipo `all` não capturava objetos Java/Kotlin retidos no heap ART.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## [1.0.0] - 2026-07-09
|
|
20
|
+
|
|
21
|
+
### Adicionado
|
|
22
|
+
- Coleta automática de traces Perfetto via `adb` com suporte aos tipos `memory`, `cpu`, `frames`, `battery` e `all`.
|
|
23
|
+
- Abertura automática do app via launcher caso não esteja em execução no momento da coleta.
|
|
24
|
+
- Parsing de callstacks de CPU com CTE recursiva percorrendo a cadeia completa de `stack_profile_callsite` até profundidade 60.
|
|
25
|
+
- Identificação de hotspots do código do app filtrando frames pelo prefixo do package (com remoção de sufixos de build variant: `debug`, `release`, `staging`, etc.).
|
|
26
|
+
- Correlação de amostras de CPU com janelas de frames janked (`actual_frame_timeline_slice WHERE on_time_finish = 0`).
|
|
27
|
+
- Relatório markdown estruturado com Resumo Executivo, Memória, CPU, Frames, Bateria e Recomendações priorizadas por severidade.
|
|
28
|
+
- Instalação automática para 6 harness agents: Claude Code, GitHub Copilot, Cursor, Antigravity, Codex e Devin.
|
|
29
|
+
- CLI com comandos `install` e `uninstall` via `npx perfetto-analyzer`.
|
|
30
|
+
- Instalação automática via `postinstall` ao usar `npm install -g perfetto-analyzer`.
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "perfetto-analyzer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "AI skill for Android performance analysis using Perfetto — works with Claude Code, Cursor, GitHub Copilot, Codex, Antigravity and Devin",
|
|
5
5
|
"bin": {
|
|
6
6
|
"perfetto-analyzer": "bin/cli.js"
|
|
7
7
|
},
|
|
8
8
|
"files": [
|
|
9
9
|
"bin/",
|
|
10
|
-
"skill/"
|
|
10
|
+
"skill/",
|
|
11
|
+
"CHANGELOG.md"
|
|
11
12
|
],
|
|
12
13
|
"scripts": {
|
|
13
14
|
"postinstall": "node bin/cli.js install --postinstall"
|
|
@@ -164,12 +164,16 @@ def extract_frames(tp):
|
|
|
164
164
|
""")
|
|
165
165
|
|
|
166
166
|
if not frames:
|
|
167
|
+
# Fallback para Android < 12 ou devices sem frame timeline.
|
|
168
|
+
# O nome do slice varia por versão: 'Choreographer#doFrame', 'Choreographer#doFrame 12345', etc.
|
|
167
169
|
frames = query_to_dicts(tp, """
|
|
168
170
|
SELECT
|
|
169
171
|
s.name,
|
|
170
172
|
s.dur / 1e6 AS duration_ms
|
|
171
173
|
FROM slice s
|
|
172
|
-
WHERE s.name
|
|
174
|
+
WHERE s.name LIKE 'Choreographer#doFrame%'
|
|
175
|
+
OR s.name LIKE '%DrawFrame%'
|
|
176
|
+
OR s.name = 'doFrame'
|
|
173
177
|
ORDER BY s.ts
|
|
174
178
|
LIMIT 5000
|
|
175
179
|
""")
|