letfixit 0.1.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/.env.example +33 -0
- package/README.md +226 -0
- package/adapters/android/build.gradle +28 -0
- package/adapters/android/src/main/kotlin/dev/perfanalyzer/ChoreographerAdapter.kt +43 -0
- package/adapters/android/src/main/kotlin/dev/perfanalyzer/LogcatReader.kt +64 -0
- package/adapters/android/src/main/kotlin/dev/perfanalyzer/MemoryObserver.kt +46 -0
- package/adapters/android/src/main/kotlin/dev/perfanalyzer/OkHttpInterceptor.kt +53 -0
- package/adapters/android/src/main/kotlin/dev/perfanalyzer/PerfAnalyzer.kt +100 -0
- package/adapters/flutter/lib/perf_analyzer.dart +73 -0
- package/adapters/flutter/lib/src/frame_observer.dart +45 -0
- package/adapters/flutter/lib/src/network_observer.dart +72 -0
- package/adapters/flutter/lib/src/rebuild_observer.dart +57 -0
- package/adapters/flutter/lib/src/universal_event.dart +50 -0
- package/adapters/flutter/lib/src/vm_service_adapter.dart +81 -0
- package/adapters/flutter/pubspec.lock +184 -0
- package/adapters/flutter/pubspec.yaml +13 -0
- package/config/model.manifest.example.json +108 -0
- package/config/model.manifest.json +108 -0
- package/core/schema/universal_event.dart +63 -0
- package/dashboard/dist/assets/index-D5TCSsvB.js +107 -0
- package/dashboard/dist/index.html +118 -0
- package/package.json +62 -0
- package/scripts/encrypt-model.js +86 -0
- package/scripts/fill-manifest.js +67 -0
- package/scripts/load-env.js +20 -0
- package/scripts/model_crypto.js +14 -0
- package/scripts/setup-model.js +269 -0
- package/server/adb_bridge.js +201 -0
- package/server/adb_score.js +77 -0
- package/server/ai_proxy.js +373 -0
- package/server/analysis_engine.js +222 -0
- package/server/android_bridge.js +124 -0
- package/server/android_live.js +167 -0
- package/server/data/device_gpu_db.json +465 -0
- package/server/device_db.js +94 -0
- package/server/device_review.js +146 -0
- package/server/finding_generator.js +56 -0
- package/server/flutter_bridge.js +414 -0
- package/server/index.js +619 -0
- package/server/ios_bridge.js +181 -0
- package/server/model_config.js +54 -0
- package/server/report_template.js +169 -0
- package/server/session_manager.js +370 -0
- package/server/widget_gpu_classifier.js +77 -0
- package/server/widget_triage.js +78 -0
- package/setup.sh +160 -0
package/setup.sh
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
BOLD='\033[1m'
|
|
5
|
+
GREEN='\033[0;32m'
|
|
6
|
+
CYAN='\033[0;36m'
|
|
7
|
+
YELLOW='\033[1;33m'
|
|
8
|
+
RED='\033[0;31m'
|
|
9
|
+
RESET='\033[0m'
|
|
10
|
+
|
|
11
|
+
# ── Paths ─────────────────────────────────────────────────────────────────────
|
|
12
|
+
MODEL_DIR="./bin/nemotron"
|
|
13
|
+
MODEL_PATH="$MODEL_DIR/model.gguf"
|
|
14
|
+
|
|
15
|
+
# Nemotron-3-Nano-4B-Coding-Agent Q4_K_M GGUF (~2.4 GB)
|
|
16
|
+
# Primary source: HuggingFace (public, no auth required)
|
|
17
|
+
HF_MODEL_URL="https://huggingface.co/S4MPL3BI4S/Nemotron-3-Nano-4B-Coding-Agent-GGUF/resolve/main/Nemotron-3-Nano-4B-Coding-Agent.Q4_K_M.gguf"
|
|
18
|
+
|
|
19
|
+
# Optional team cache: set GDRIVE_MODEL_ID in .env or environment to a
|
|
20
|
+
# Google Drive file ID so teammates skip the HuggingFace download.
|
|
21
|
+
# Share the file publicly (Anyone with link → Viewer) before setting the ID.
|
|
22
|
+
GDRIVE_MODEL_ID="${GDRIVE_MODEL_ID:-}"
|
|
23
|
+
|
|
24
|
+
echo ""
|
|
25
|
+
echo -e "${BOLD}🔍 Perf Analyzer v0.1.0 — Setup${RESET}"
|
|
26
|
+
echo "────────────────────────────────────────────"
|
|
27
|
+
|
|
28
|
+
# ── 1. Server dependencies ────────────────────────────────────────────────────
|
|
29
|
+
echo -e "\n${CYAN}[1/6] Installing server dependencies...${RESET}"
|
|
30
|
+
cd server && npm install --silent && cd ..
|
|
31
|
+
echo -e "${GREEN} ✅ Server ready${RESET}"
|
|
32
|
+
|
|
33
|
+
# ── 2. Dashboard dependencies ─────────────────────────────────────────────────
|
|
34
|
+
echo -e "\n${CYAN}[2/6] Installing dashboard dependencies...${RESET}"
|
|
35
|
+
cd dashboard && npm install --silent && cd ..
|
|
36
|
+
echo -e "${GREEN} ✅ Dashboard dependencies ready${RESET}"
|
|
37
|
+
|
|
38
|
+
# ── 3. Build dashboard ────────────────────────────────────────────────────────
|
|
39
|
+
echo -e "\n${CYAN}[3/6] Building dashboard...${RESET}"
|
|
40
|
+
cd dashboard && npm run build --silent && cd ..
|
|
41
|
+
echo -e "${GREEN} ✅ Dashboard built → dashboard/dist/${RESET}"
|
|
42
|
+
|
|
43
|
+
# ── 4. Copy .env ──────────────────────────────────────────────────────────────
|
|
44
|
+
echo -e "\n${CYAN}[4/6] Setting up environment...${RESET}"
|
|
45
|
+
if [ ! -f .env ]; then
|
|
46
|
+
cp .env.example .env
|
|
47
|
+
echo -e "${GREEN} ✅ Created .env from .env.example${RESET}"
|
|
48
|
+
else
|
|
49
|
+
echo -e "${YELLOW} ⚠️ .env already exists — skipped (edit it manually to change settings)${RESET}"
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# ── 5. llama.cpp server (llama-server) ───────────────────────────────────────
|
|
53
|
+
echo -e "\n${CYAN}[5/6] Setting up llama-server (llama.cpp)...${RESET}"
|
|
54
|
+
|
|
55
|
+
if command -v llama-server &>/dev/null; then
|
|
56
|
+
echo -e "${YELLOW} ⚠️ llama-server already installed — skipped${RESET}"
|
|
57
|
+
llama-server --version 2>&1 | head -1 | sed 's/^/ ↳ /'
|
|
58
|
+
else
|
|
59
|
+
echo -e " 📥 Installing llama.cpp (llama-server)..."
|
|
60
|
+
curl -LsSf https://llama.app/install.sh | sh
|
|
61
|
+
if command -v llama-server &>/dev/null; then
|
|
62
|
+
echo -e "${GREEN} ✅ llama-server installed${RESET}"
|
|
63
|
+
llama-server --version 2>&1 | head -1 | sed 's/^/ ↳ /'
|
|
64
|
+
else
|
|
65
|
+
echo -e "${RED} ❌ llama-server install failed — install manually:${RESET}"
|
|
66
|
+
echo -e " curl -LsSf https://llama.app/install.sh | sh"
|
|
67
|
+
echo -e "${YELLOW} ↳ Continuing without local AI — cloud API fallback will be used.${RESET}"
|
|
68
|
+
fi
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# ── 6. Nemotron-3-Nano-4B model ───────────────────────────────────────────────
|
|
72
|
+
echo -e "\n${CYAN}[6/6] Setting up local AI model (Nemotron-3-Nano-4B)...${RESET}"
|
|
73
|
+
mkdir -p "$MODEL_DIR"
|
|
74
|
+
|
|
75
|
+
if [ -f "$MODEL_PATH" ] && [ "$(stat -f%z "$MODEL_PATH" 2>/dev/null || stat -c%s "$MODEL_PATH" 2>/dev/null)" -gt 104857600 ]; then
|
|
76
|
+
echo -e "${YELLOW} ⚠️ Nemotron model already downloaded — skipped${RESET}"
|
|
77
|
+
else
|
|
78
|
+
# ── Try Google Drive team cache first (fastest if your team set this up) ──
|
|
79
|
+
if [ -n "$GDRIVE_MODEL_ID" ]; then
|
|
80
|
+
echo -e " 📥 Trying Google Drive team cache (GDRIVE_MODEL_ID is set)..."
|
|
81
|
+
if command -v gdown &>/dev/null; then
|
|
82
|
+
if gdown "https://drive.google.com/uc?id=${GDRIVE_MODEL_ID}" -O "$MODEL_PATH" 2>&1; then
|
|
83
|
+
chmod +x "$MODEL_PATH"
|
|
84
|
+
echo -e "${GREEN} ✅ Nemotron downloaded from Google Drive → $MODEL_PATH${RESET}"
|
|
85
|
+
SKIP_HF=true
|
|
86
|
+
else
|
|
87
|
+
echo -e "${YELLOW} ⚠️ Google Drive download failed — falling back to HuggingFace${RESET}"
|
|
88
|
+
fi
|
|
89
|
+
else
|
|
90
|
+
echo -e " ℹ️ gdown not found — installing..."
|
|
91
|
+
if command -v pip3 &>/dev/null; then
|
|
92
|
+
pip3 install -q gdown
|
|
93
|
+
if gdown "https://drive.google.com/uc?id=${GDRIVE_MODEL_ID}" -O "$MODEL_PATH" 2>&1; then
|
|
94
|
+
chmod +x "$MODEL_PATH"
|
|
95
|
+
echo -e "${GREEN} ✅ Nemotron downloaded from Google Drive → $MODEL_PATH${RESET}"
|
|
96
|
+
SKIP_HF=true
|
|
97
|
+
else
|
|
98
|
+
echo -e "${YELLOW} ⚠️ Google Drive download failed — falling back to HuggingFace${RESET}"
|
|
99
|
+
fi
|
|
100
|
+
else
|
|
101
|
+
echo -e "${YELLOW} ⚠️ pip3 not found — cannot install gdown, falling back to HuggingFace${RESET}"
|
|
102
|
+
fi
|
|
103
|
+
fi
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# ── HuggingFace direct download (no account needed, public model) ──────────
|
|
107
|
+
if [ "${SKIP_HF:-false}" != "true" ]; then
|
|
108
|
+
echo -e " 📥 Downloading Nemotron-3-Nano-4B Q4_K_M from HuggingFace (~2.4 GB)..."
|
|
109
|
+
echo -e " ℹ️ This is a one-time download. It will not repeat on future setups."
|
|
110
|
+
echo ""
|
|
111
|
+
|
|
112
|
+
# huggingface-cli is fastest if the user has it (handles resumable downloads)
|
|
113
|
+
if command -v huggingface-cli &>/dev/null; then
|
|
114
|
+
huggingface-cli download \
|
|
115
|
+
S4MPL3BI4S/Nemotron-3-Nano-4B-Coding-Agent-GGUF \
|
|
116
|
+
Nemotron-3-Nano-4B-Coding-Agent.Q4_K_M.gguf \
|
|
117
|
+
--local-dir "$MODEL_DIR" \
|
|
118
|
+
--local-dir-use-symlinks False
|
|
119
|
+
# huggingface-cli saves with original filename — rename to model.gguf
|
|
120
|
+
if [ -f "$MODEL_DIR/Nemotron-3-Nano-4B-Coding-Agent.Q4_K_M.gguf" ]; then
|
|
121
|
+
mv "$MODEL_DIR/Nemotron-3-Nano-4B-Coding-Agent.Q4_K_M.gguf" "$MODEL_PATH"
|
|
122
|
+
fi
|
|
123
|
+
else
|
|
124
|
+
curl -L --progress-bar -C - -o "$MODEL_PATH" "$HF_MODEL_URL"
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
chmod +x "$MODEL_PATH"
|
|
128
|
+
echo -e "${GREEN} ✅ Nemotron ready → $MODEL_PATH${RESET}"
|
|
129
|
+
fi
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
# ── Done ──────────────────────────────────────────────────────────────────────
|
|
133
|
+
echo ""
|
|
134
|
+
echo -e "${BOLD}${GREEN}✅ Setup complete!${RESET}"
|
|
135
|
+
echo ""
|
|
136
|
+
echo -e "${BOLD}Quick start:${RESET}"
|
|
137
|
+
echo ""
|
|
138
|
+
echo -e " ${CYAN}1. Run your Flutter app with VM service enabled:${RESET}"
|
|
139
|
+
echo " flutter run --vm-service-port=8181 --disable-service-auth-codes"
|
|
140
|
+
echo ""
|
|
141
|
+
echo -e " ${CYAN}2. Start Perf Analyzer (it will ask for the VM port):${RESET}"
|
|
142
|
+
echo " npm start"
|
|
143
|
+
echo " └─ Starts Nemotron on :8080 + dashboard on :8081"
|
|
144
|
+
echo ""
|
|
145
|
+
echo -e " ${CYAN}3. Add the Flutter adapter to your app's pubspec.yaml:${RESET}"
|
|
146
|
+
echo " perf_analyzer:"
|
|
147
|
+
echo " path: /path/to/perf_analyzer/adapters/flutter"
|
|
148
|
+
echo ""
|
|
149
|
+
echo -e " ${CYAN}4. Initialize in main():${RESET}"
|
|
150
|
+
echo " await PerfAnalyzer.start();"
|
|
151
|
+
echo ""
|
|
152
|
+
echo -e " ${CYAN}5. (Optional) Add cloud AI fallback keys to .env:${RESET}"
|
|
153
|
+
echo " GROQ_API_KEY, GEMINI_API_KEY, or CLAUDE_API_KEY"
|
|
154
|
+
echo " Nemotron runs locally by default — keys only used as fallback."
|
|
155
|
+
echo ""
|
|
156
|
+
echo -e " ${BOLD}📊 Dashboard → http://localhost:8081${RESET}"
|
|
157
|
+
echo ""
|
|
158
|
+
echo -e "${YELLOW} 💡 Team tip: upload the model to Google Drive, set GDRIVE_MODEL_ID in .env,"
|
|
159
|
+
echo -e " and teammates will skip the HuggingFace download on future setups.${RESET}"
|
|
160
|
+
echo ""
|