perfetto-analyzer 1.0.3 → 1.0.4

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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.4] - 2026-07-09
4
+
5
+ ### Adicionado
6
+ - **`generate_report.py`** — Seção "Próximos Passos" agora inclui sugestões de traces de correlação automáticas quando fazem sentido:
7
+ - `cpu` com Compose: sugere `frames` para confirmar se as recomposições causam drops reais
8
+ - `cpu` com problemas: sugere `memory` para verificar heap churn nos mesmos hot paths
9
+ - `frames` com jank: sugere `cpu` para identificar a callstack durante o deadline miss
10
+ - `memory` com problemas: sugere `cpu` (hotspots de alocação) e `frames` (GC causando jank)
11
+ - `battery` com problemas: sugere `cpu` e `all`
12
+ - Trace tipo `all`: nenhuma sugestão (já captura tudo)
13
+
3
14
  ## [1.0.3] - 2026-07-09
4
15
 
5
16
  ### Corrigido
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perfetto-analyzer",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
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"
@@ -77,6 +77,66 @@ def severity_emoji(s):
77
77
  JVM_NOISE = {"RuntimeInit", "ZygoteInit", "NativeStart", "Looper.loop"}
78
78
 
79
79
 
80
+ def _correlations(trace_type, recommendations):
81
+ """Sugere traces complementares com base no tipo atual e nos problemas encontrados."""
82
+ if trace_type == "all":
83
+ return []
84
+
85
+ categories = {r.get("category") for r in recommendations}
86
+ titles = " ".join(r.get("title", "") for r in recommendations)
87
+ suggestions = []
88
+
89
+ if trace_type == "cpu":
90
+ if "Recomposição" in titles or "Compose" in titles:
91
+ suggestions.append((
92
+ "frames",
93
+ "Correlacionar recomposições com drops reais — o trace de frames mostra se as "
94
+ "recomposições detectadas aqui estão de fato causando frames janked visíveis.",
95
+ ))
96
+ if "cpu" in categories:
97
+ suggestions.append((
98
+ "memory",
99
+ "Verificar se heap churn está pressionando a CPU — GC frequente aparece como "
100
+ "picos de CPU; o trace de memória confirma alocações excessivas nos mesmos hot paths.",
101
+ ))
102
+
103
+ elif trace_type == "frames":
104
+ if "frames" in categories:
105
+ suggestions.append((
106
+ "cpu",
107
+ "Identificar a callstack responsável pelos drops — o trace de CPU a 60 Hz mostra "
108
+ "exatamente qual função estava rodando durante cada deadline miss.",
109
+ ))
110
+
111
+ elif trace_type == "memory":
112
+ if "memory" in categories:
113
+ suggestions.append((
114
+ "cpu",
115
+ "Localizar os hotspots de alocação no callstack — o trace de CPU revela quais "
116
+ "funções disparam as alocações identificadas aqui.",
117
+ ))
118
+ suggestions.append((
119
+ "frames",
120
+ "Verificar se o churn de memória/GC está causando jank — pausas de GC aparecem "
121
+ "como frames dropados no trace de frames.",
122
+ ))
123
+
124
+ elif trace_type == "battery":
125
+ suggestions.append((
126
+ "cpu",
127
+ "Identificar quais funções consomem mais CPU e drenam a bateria — o trace de CPU "
128
+ "mapeia o gasto energético a callstacks específicos.",
129
+ ))
130
+ if recommendations:
131
+ suggestions.append((
132
+ "all",
133
+ "Trace completo para correlação total — combina CPU, frames e memória para uma "
134
+ "visão unificada do drain.",
135
+ ))
136
+
137
+ return suggestions
138
+
139
+
80
140
  def generate_report(data, package, trace_type):
81
141
  now = datetime.now().strftime("%Y-%m-%d %H:%M")
82
142
  duration = data.get("trace_duration_seconds", 0)
@@ -357,11 +417,16 @@ def generate_report(data, package, trace_type):
357
417
  lines += ["Nenhum problema detectado automaticamente. Revise o trace manualmente no [Perfetto UI](https://perfetto.dev/ui).", ""]
358
418
 
359
419
  # Próximos Passos
360
- lines += [
361
- "---",
362
- "",
363
- "## Próximos Passos",
364
- "",
420
+ correlations = _correlations(trace_type, recommendations)
421
+
422
+ next_steps = ["---", "", "## Próximos Passos", ""]
423
+
424
+ if correlations:
425
+ for next_type, reason in correlations:
426
+ next_steps.append(f"- [ ] **Trace `{next_type}`** — {reason}")
427
+ next_steps.append("")
428
+
429
+ next_steps += [
365
430
  "- [ ] Abrir o arquivo `.pb` em [perfetto.dev/ui](https://perfetto.dev/ui) para análise visual",
366
431
  "- [ ] Usar o SQL Explorer do Perfetto UI para queries customizadas",
367
432
  "- [ ] Correlacionar picos de CPU/memória com interações do usuário na timeline",
@@ -372,6 +437,8 @@ def generate_report(data, package, trace_type):
372
437
  f"*Gerado por perfetto-analyzer em {now}*",
373
438
  ]
374
439
 
440
+ lines += next_steps
441
+
375
442
  return "\n".join(lines)
376
443
 
377
444