feat: initial commit - Jhonny Editor

- Adicionado estrutura completa do projeto
- Configurado MCP server para Premiere Pro
- Adicionado documentação e skills
- Configurado Gitignore para o projeto
This commit is contained in:
João Henrique
2026-09-08 09:59:31 -04:00
commit b541f502ba
1507 changed files with 387650 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
#!/bin/bash
set -e
# Tigre (codeclass) - Deploy do servidor web novo em Swift
# Sobe um nivel: o script vive em admin/, o projeto e a pasta pai.
#
# Uso:
# admin/deploy-codeclass.command # porta 5050 (padrão)
# admin/deploy-codeclass.command 8080 # porta customizada
#
# O que faz:
# 1) localiza a toolchain Swift (Xcode) e compila o codeclass (swift build)
# 2) derruba qualquer instancia antiga na porta de destino
# 3) sobe o servidor novo em background (TigreApp serve) com as classes
# novas (TranscriptionService + AppleVisionAnalyzer)
# 4) abre o navegador quando o servidor responder
#
# Diferente de deploy.command (legado Python/Flask em code/app.py), este
# script sobe o servidor do codeclass/ (100% Swift). Na porta 5050 eles se
# conflitam: rode APENAS UM deles por vez.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
PORT="${1:-5050}"
CLASSDIR="$PROJECT_DIR/codeclass"
echo "============================================================"
echo " Tigre (codeclass) :: Deploy do servidor web novo (Swift)"
echo " Pasta: $PROJECT_DIR"
echo " Porta: $PORT"
echo "============================================================"
echo
# 1) Toolchain Swift (Xcode 26 / swift 6.3). Respeita PATH se ja configurado.
SWIFT="$(command -v swift || true)"
if [ -z "$SWIFT" ] && [ -x "/Volumes/Merongo/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift" ]; then
export PATH="/Volumes/Merongo/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:$PATH"
SWIFT="swift"
fi
if [ -z "$SWIFT" ]; then
echo "ERRO: swift nao encontrado no PATH nem no Xcode padrao."
echo " Instale Xcode 26+ ou exporte o PATH da toolchain."
exit 1
fi
# 2) Compilar o codeclass
echo "[1/3] Compilando o codeclass (swift build)..."
cd "$CLASSDIR"
"$SWIFT" build 2>&1 | tail -5
echo " Build OK."
echo
# 3) Derrubar instancias antigas na porta de destino
echo "[2/3] Parando instancia anterior na porta $PORT..."
lsof -ti:"$PORT" | xargs kill -9 2>/dev/null || true
sleep 1
true
# 4) Subir o servidor novo em background (nao trava o terminal)
echo "[3/3] Levantando o servidor novo (TigreApp serve)..."
echo " http://localhost:$PORT"
echo
LOG="/tmp/tigre-codeclass-web.log"
nohup "$SWIFT" run TigreApp serve --port "$PORT" --project-root "$PROJECT_DIR" > "$LOG" 2>&1 &
SERVER_PID=$!
echo " PID do servidor: $SERVER_PID (log: $LOG)"
echo
# Abre o navegador padrao assim que o servidor responder (nao trava o boot)
(
for _ in $(seq 1 45); do
if curl -s -o /dev/null "http://localhost:$PORT"; then
open "http://localhost:$PORT"
break
fi
sleep 1
done
) &
# Mostra o log por alguns segundos para confirmar o boot
sleep 5
echo "--- primeiras linhas do log ---"
tail -10 "$LOG"
echo
echo "============================================================"
echo " Servidor novo (codeclass) no ar em http://localhost:$PORT"
echo " Para encerrar: lsof -ti:$PORT | xargs kill -9"
echo "============================================================"
+110
View File
@@ -0,0 +1,110 @@
#!/bin/bash
set -e
# Doza Assist - Deploy (Graphify + Servidor)
# Sobe um nivel: o script vive em admin/, o projeto e a pasta pai
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_DIR"
echo "============================================================"
echo " Doza Assist :: Deploy - Graphify + Servidor"
echo " Pasta: $(pwd)"
echo "============================================================"
echo
# 1) Resolve quem executa o graphify (preferencia: uv, depois graphify no PATH)
if command -v uv >/dev/null 2>&1; then
RUN="uv tool run --from graphifyy graphify"
elif command -v graphify >/dev/null 2>&1; then
RUN="graphify"
else
echo "graphify nao encontrado. Instalando via pip..."
python3 -m pip install -q --upgrade graphifyy
RUN="graphify"
fi
# 2) Roda o graphify SEMPRE (deep + update; code-only se nao houver API key)
ARGS="--mode deep --update"
if [ -n "$GEMINI_API_KEY" ] || [ -n "$GOOGLE_API_KEY" ] || [ -n "$MOONSHOT_API_KEY" ] \
|| [ -n "$ANTHROPIC_API_KEY" ] || [ -n "$OPENAI_API_KEY" ] || [ -n "$DEEPSEEK_API_KEY" ]; then
:
else
echo "AVISO: nenhuma LLM API key detectada. Usando --code-only (codigo apenas;"
echo " docs/imagens serao ignorados). Para extracao semantica completa,"
echo " defina GEMINI_API_KEY ou GOOGLE_API_KEY."
ARGS="--mode deep --update --code-only"
fi
echo
echo "Executando graphify (DEEP + UPDATE)..."
echo
$RUN "." $ARGS || echo "[AVISO] graphify falhou; o deploy continua mesmo assim."
# 2.5) Reindexar o RAG (doza.code_chunks) - so roda se rag/.env estiver
# preenchido; requer o tunel SSH do banco aberto (ver rag/SETUP.md).
# Best-effort: nunca trava o deploy.
echo
echo "Reindexando RAG..."
PORT=55435
export RAG_DB_PORT=$PORT
export RAG_DB_HOST=127.0.0.1
bash "$PROJECT_DIR/rag/ensure_tunnel.sh" || true
RAG_VENV_PY="$PROJECT_DIR/code/.venv/bin/python3"
if [ ! -x "$RAG_VENV_PY" ]; then
RAG_VENV_PY="python3"
fi
if [ -f "$PROJECT_DIR/rag/.env" ] && grep -q '^RAG_DB_PASSWORD=.\+' "$PROJECT_DIR/rag/.env"; then
"$RAG_VENV_PY" -m pip install -q -r "$PROJECT_DIR/rag/requirements.txt" 2>/dev/null || true
"$RAG_VENV_PY" "$PROJECT_DIR/rag/index_code.py" || echo "[AVISO] indexacao RAG falhou (tunel/banco indisponivel?); deploy continua."
else
echo "[INFO] rag/.env sem RAG_DB_PASSWORD preenchida; pulando indexacao RAG."
fi
# 3) Derrubar qualquer instancia antiga do servidor
echo
echo "Parando instancias anteriores do servidor..."
lsof -ti:5050 | xargs kill -9 2>/dev/null || true
pkill -f "python.*app.py" 2>/dev/null || true
sleep 1
true
# 4) Levantar o servidor Doza Assist
APP_DIR="$PROJECT_DIR/code"
cd "$APP_DIR"
# Ensure Homebrew binaries (ffmpeg, etc.) are on PATH
if [ -d "/opt/homebrew/bin" ]; then
export PATH="/opt/homebrew/bin:$PATH"
elif [ -d "/usr/local/bin" ]; then
export PATH="/usr/local/bin:$PATH"
fi
VENV_PY="$APP_DIR/.venv/bin/python3"
if [ ! -x "$VENV_PY" ]; then
echo "ERRO: ambiente Python do macOS nao encontrado:"
echo " $VENV_PY"
echo
echo "Execute primeiro: admin/install.command"
exit 1
fi
echo
echo "============================================================"
echo " Levantando o servidor Doza Assist..."
echo " http://localhost:5050"
echo "============================================================"
echo
# Abre o navegador padrao assim que o servidor responder (nao trava o boot)
(
for _ in $(seq 1 30); do
if curl -s -o /dev/null "http://localhost:5050"; then
open "http://localhost:5050"
break
fi
sleep 1
done
) &
"$VENV_PY" app.py
+57
View File
@@ -0,0 +1,57 @@
#!/bin/bash
set -e
# Graphify - atualizacao profunda e incremental do projeto
# Sobe um nivel: o script vive em admin/, o projeto e a pasta pai
SCRIPT_DIR="$(dirname "$0")"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_DIR"
echo "============================================================"
echo " Graphify :: atualizacao profunda e incremental do projeto"
echo " Pasta: $(pwd)"
echo "============================================================"
echo
# 1) Resolve quem executa o graphify (preferencia: uv, depois graphify no PATH)
if command -v uv >/dev/null 2>&1; then
RUN="uv tool run --from graphifyy graphify"
echo "Runner: uv tool run --from graphifyy graphify"
elif command -v graphify >/dev/null 2>&1; then
RUN="graphify"
echo "Runner: graphify (PATH)"
else
echo "graphify nao encontrado. Instalando via pip..."
python3 -m pip install -q --upgrade graphifyy
RUN="graphify"
echo "Runner: graphify (apos install)"
fi
# 2) Atualizacao profunda e incremental
# --mode deep : extracao semantica agressiva (arestas INFERRED mais ricas)
# --update : re-extrai so o que mudou; 1a execucao faz o build completo
# Sem LLM API key, cai em --code-only (varre so o codigo, sem docs/imagens)
ARGS="--mode deep --update"
if [ -n "$GEMINI_API_KEY" ] || [ -n "$GOOGLE_API_KEY" ] || [ -n "$MOONSHOT_API_KEY" ] \
|| [ -n "$ANTHROPIC_API_KEY" ] || [ -n "$OPENAI_API_KEY" ] || [ -n "$DEEPSEEK_API_KEY" ]; then
:
else
echo "AVISO: nenhuma LLM API key detectada. Usando --code-only (codigo apenas;"
echo " docs/imagens serao ignorados). Para extracao semantica completa,"
echo " defina GEMINI_API_KEY ou GOOGLE_API_KEY e rode novamente."
ARGS="--mode deep --update --code-only"
fi
echo
echo "Executando graphify em modo DEEP + UPDATE..."
echo
$RUN "." $ARGS
echo
echo "============================================================"
echo " Concluido! Resultados em: $(pwd)/graphify-out"
echo " - graph.html (grafo interativo - abra no navegador)"
echo " - GRAPH_REPORT.md (relatorio de auditoria)"
echo " - graph.json (dados brutos / GraphRAG-ready)"
echo "============================================================"
echo
echo "Dica: torne executavel uma unica vez com: chmod +x graphify-update.command"
+99
View File
@@ -0,0 +1,99 @@
#!/bin/bash
set -e
# Doza Assist - Instalador (macOS)
# Sobe um nivel: o script vive em admin/, o projeto e a pasta pai
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
CODE_DIR="$PROJECT_DIR/code"
VENV_DIR="$CODE_DIR/.venv"
echo "============================================================"
echo " Doza Assist - Instalador"
echo " Pasta: $CODE_DIR"
echo "============================================================"
echo
# Homebrew no PATH (ffmpeg, python3 via brew, etc.)
if [ -d "/opt/homebrew/bin" ]; then
export PATH="/opt/homebrew/bin:$PATH"
elif [ -d "/usr/local/bin" ]; then
export PATH="/usr/local/bin:$PATH"
fi
# 1) Verificar Python
echo "[1/4] Verificando Python..."
if ! command -v python3 >/dev/null 2>&1; then
echo "ERRO: python3 nao encontrado."
echo "Instale via Homebrew: brew install python@3.12"
echo "Ou baixe de: https://www.python.org/downloads/"
exit 1
fi
PY_VER="$(python3 --version 2>&1 | awk '{print $2}')"
echo " Python encontrado: $PY_VER"
# 2) Criar ambiente virtual
echo
echo "[2/4] Criando ambiente virtual..."
if [ -d "$VENV_DIR" ] && [ ! -x "$VENV_DIR/bin/python3" ]; then
# venv existente nao e do macOS (ex.: criado no Windows, tem Scripts/ em vez de bin/)
echo " AVISO: existe um .venv incompativel com macOS em:"
echo " $VENV_DIR"
if [ -f "$VENV_DIR/pyvenv.cfg" ]; then
echo " Origem registrada:"
sed -n 's/^home = / /p' "$VENV_DIR/pyvenv.cfg"
fi
echo
echo " Para continuar e preciso recriar esse ambiente."
echo " O diretorio sera movido para .venv.bak (nada e apagado)."
printf " Recriar agora? [s/N] "
read -r RESP
case "$RESP" in
[sS]|[sS][iI][mM]|[yY]|[yY][eE][sS]) ;;
*) echo " Cancelado pelo usuario. Nada foi alterado."; exit 1 ;;
esac
rm -rf "$VENV_DIR.bak"
mv "$VENV_DIR" "$VENV_DIR.bak"
echo " Ambiente antigo movido para: $VENV_DIR.bak"
fi
if [ ! -d "$VENV_DIR" ]; then
python3 -m venv "$VENV_DIR"
echo " Ambiente virtual criado."
else
echo " Ambiente virtual ja existe."
fi
VENV_PY="$VENV_DIR/bin/python3"
# 3) Instalar dependencias
echo
echo "[3/4] Instalando dependencias..."
"$VENV_PY" -m pip install --upgrade pip >/dev/null 2>&1
"$VENV_PY" -m pip install -r "$CODE_DIR/requirements.txt"
echo " Dependencias instaladas."
# 4) Verificar ffmpeg
echo
echo "[4/4] Verificando ffmpeg..."
if ! command -v ffmpeg >/dev/null 2>&1; then
echo " ffmpeg nao encontrado."
echo " Para instalar via Homebrew: brew install ffmpeg"
echo " Ou baixe de: https://ffmpeg.org/download.html"
else
echo " ffmpeg encontrado: $(command -v ffmpeg)"
fi
echo
echo "============================================================"
echo " Instalacao concluida!"
echo
echo " Para iniciar o servidor:"
echo " cd \"$CODE_DIR\""
echo " .venv/bin/python3 app.py"
echo
echo " Ou execute: admin/deploy.command"
echo
echo " Acesse: http://localhost:5050"
echo "============================================================"
echo
+155
View File
@@ -0,0 +1,155 @@
#!/bin/bash
# Tigre (codeclass) - Empacota o TigreAppUI em um bundle .app real.
# Sobe um nivel: o script vive em admin/, o projeto e a pasta pai.
#
# Uso:
# admin/make-app.command # build debug + bundle no ~/Applications
# TIGRE_APP_CONFIG=release admin/... # build release (otimizado)
# TIGRE_APP_DIR=/tmp/Tigre.app admin/... # bundle em outro local
#
# O que faz:
# 1) compila o TigreAppUI (swift build)
# 2) gera o icone do app (make_icon.py + sips + iconutil -> AppIcon.icns)
# 3) monta ~/Applications/Tigre.app:
# Tigre.app/
# └── Contents/
# ├── Info.plist
# ├── MacOS/Tigre (binario compilado)
# └── Resources/AppIcon.icns
# 4) codesign ad-hoc (evita atrito com Gatekeeper/LaunchServices)
#
# NÃO instala nem desinstala nada no sistema: um .app e so uma pasta; cada
# execucao SOBRESCREVE o bundle. "Desinstalar" = apagar a pasta.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
CLASSDIR="$PROJECT_DIR/codeclass"
APP_NAME="Tigre"
APP_DIR="${TIGRE_APP_DIR:-$HOME/Applications/$APP_NAME.app}"
CONFIG="${TIGRE_APP_CONFIG:-debug}"
CONTENTS="$APP_DIR/Contents"
MACOS_DIR="$CONTENTS/MacOS"
RES_DIR="$CONTENTS/Resources"
echo "============================================================"
echo " Tigre :: Empacotando $APP_NAME.app"
echo " Config: $CONFIG"
echo " Destino: $APP_DIR"
echo "============================================================"
echo
# 1) Toolchain Swift (Xcode 26 / swift 6.3). Respeita PATH se ja configurado.
SWIFT="$(command -v swift || true)"
if [ -z "$SWIFT" ] && [ -x "/Volumes/Merongo/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift" ]; then
export PATH="/Volumes/Merongo/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:$PATH"
SWIFT="swift"
fi
if [ -z "$SWIFT" ]; then
echo "ERRO: swift nao encontrado no PATH nem no Xcode padrao."
exit 1
fi
# 2) Compilar o codeclass (ida incremental; release e mais lento)
echo "[1/4] Compilando o codeclass ($CONFIG)..."
cd "$CLASSDIR"
STDOUT_LOG="/tmp/tigre-build.log"
if "$SWIFT" build -c "$CONFIG" > "$STDOUT_LOG" 2>&1; then
tail -3 "$STDOUT_LOG" | sed 's/^/ /' || true
else
echo " ERRO de compilacao. Ultimas linhas:"
tail -20 "$STDOUT_LOG" | sed 's/^/ /'
exit 1
fi
BIN="$CLASSDIR/.build/$CONFIG/TigreAppUI"
if [ ! -x "$BIN" ]; then
echo "ERRO: binario nao encontrado apos build: $BIN"
exit 1
fi
echo " Build OK."
echo
# 3) Icone do app
# Fonte: app-icon.png na RAIZ do projeto (prioridade), depois admin/app-icon.png
# (compat), e fallback make_icon.py (gera o "T" laranja sintetico).
echo "[2/4] Gerando icone (AppIcon.icns)..."
CUSTOM_ICON=""
for _cand in "$PROJECT_DIR/app-icon.png" "$SCRIPT_DIR/app-icon.png"; do
if [ -f "$_cand" ]; then
CUSTOM_ICON="$_cand"
break
fi
done
ICON_PNG="/tmp/tigre_icon_1024.png"
if [ -n "$CUSTOM_ICON" ]; then
echo " Usando icone customizado ($(echo "$CUSTOM_ICON" | sed "s|$PROJECT_DIR|.|"), $(sips -g pixelWidth "$CUSTOM_ICON" 2>/dev/null | awk '/pixelWidth/{print $2}')px)"
# Resample p/ 1024 (o iconutil exige o slot 512@2x = 1024) e deriva os demais
sips -z 1024 1024 "$CUSTOM_ICON" --out "$ICON_PNG" >/dev/null 2>&1
else
echo " app-icon.png ausente — usando icone padrao (make_icon.py)"
python3 "$SCRIPT_DIR/make_icon.py" "$ICON_PNG"
fi
ICONSET="/tmp/Tigre.iconset"
rm -rf "$ICONSET"
mkdir -p "$ICONSET"
for sz in 16 32 128 256 512; do
sips -z "$sz" "$sz" "$ICON_PNG" --out "$ICONSET/icon_${sz}x${sz}.png" >/dev/null 2>&1
dbl=$((sz * 2))
sips -z "$dbl" "$dbl" "$ICON_PNG" --out "$ICONSET/icon_${sz}x${sz}@2x.png" >/dev/null 2>&1
done
iconutil -c icns "$ICONSET" -o "/tmp/TigreAppIcon.icns"
rm -rf "$ICONSET" "$ICON_PNG"
echo " Icone OK."
# 4) Montar o bundle .app
echo "[3/4] Montando o bundle..."
rm -rf "$APP_DIR"
mkdir -p "$MACOS_DIR" "$RES_DIR"
cp "$BIN" "$MACOS_DIR/$APP_NAME"
cp "/tmp/TigreAppIcon.icns" "$RES_DIR/AppIcon.icns"
cat > "$CONTENTS/Info.plist" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>Tigre</string>
<key>CFBundleDisplayName</key>
<string>Tigre</string>
<key>CFBundleIdentifier</key>
<string>com.genial.tigre</string>
<key>CFBundleVersion</key>
<string>0.1.0</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleExecutable</key>
<string>${APP_NAME}</string>
<key>CFBundleIconFile</key>
<string>AppIcon</string>
<key>LSMinimumSystemVersion</key>
<string>14.0</string>
<key>LSUIElement</key>
<false/>
<key>NSHighResolutionCapable</key>
<true/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.productivity</string>
</dict>
</plist>
PLIST
echo " Bundle montado."
# 5) Assinatura ad-hoc (sem identity de Developer ID, suficiente p/ uso local)
echo "[4/4] Assinatura ad-hoc..."
codesign --force --deep -s - "$APP_DIR" 2>&1 | sed 's/^/ /' || true
echo " Pronto: $APP_DIR"
echo
echo " Para lançar: open \"$APP_DIR\""
echo " Para remover: rm -rf \"$APP_DIR\""
echo
+146
View File
@@ -0,0 +1,146 @@
#!/usr/bin/env python3
"""
Gera o ícone do Tigre (app GUI SwiftUI) em 1024x1024 PNG.
Desenho: fundo escuro arredondado (gradiente), um "T" em laranja com
listras diagonais escuras (pele de tigre). A geração dos tamanhos menores
e do .icns é feita pelo make-app.command via sips + iconutil.
Uso:
python3 admin/make_icon.py [caminho_de_saida.png]
"""
import struct
import zlib
import sys
import os
SIZE = 1024
def create_png(width, height, pixels):
"""Cria um PNG RGBA."""
def chunk(ctype, data):
c = ctype + data
crc = struct.pack('>I', zlib.crc32(c) & 0xFFFFFFFF)
return struct.pack('>I', len(data)) + c + crc
header = b'\x89PNG\r\n\x1a\n'
ihdr = chunk(b'IHDR', struct.pack('>IIBBBBB', width, height, 8, 6, 0, 0, 0))
raw = b''
for y in range(height):
raw += b'\x00'
for x in range(width):
i = (y * width + x) * 4
raw += bytes(pixels[i:i+4])
idat = chunk(b'IDAT', zlib.compress(raw, 9))
return header + ihdr + idat + chunk(b'IEND', b'')
def lerp(a, b, t):
return int(a + (b - a) * t)
def draw_icon(size):
px = [0] * (size * size * 4)
def set_px(x, y, r, g, b, a=255):
if 0 <= x < size and 0 <= y < size:
i = (y * size + x) * 4
af = a / 255.0
px[i] = lerp(px[i], r, af)
px[i+1] = lerp(px[i+1], g, af)
px[i+2] = lerp(px[i+2], b, af)
px[i+3] = max(px[i+3], a)
def in_rrect(x, y, x0, y0, x1, y1, r):
"""Ponto dentro de retângulo arredondado (sem AA — ok, sips suaviza)."""
if x < x0 or x > x1 or y < y0 or y > y1:
return False
cx = min(max(x, x0 + r), x1 - r)
cy = min(max(y, y0 + r), y1 - r)
return (x - cx) ** 2 + (y - cy) ** 2 <= r * r
def fill_rrect(x0, y0, x1, y1, r, rg, g_, b_, a=255):
for y in range(int(y0), int(y1)):
for x in range(int(x0), int(x1)):
if in_rrect(x, y, x0, y0, x1, y1, r):
set_px(x, y, rg, g_, b_, a)
# ── Fundo: gradiente vertical escuro + cantos arredondados (squircle liso) ──
m = size * 0.03
corner = size * 0.22
for y in range(size):
t = y / size
br = lerp(0x2b, 0x12, t)
bgc = lerp(0x2b, 0x12, t)
bb = lerp(0x33, 0x16, t)
for x in range(size):
if in_rrect(x, y, m, m, size - m - 1, size - m - 1, corner):
set_px(x, y, br, bgc, bb)
# ── Letra "T" (barra + haste) em laranja com gradiente ──
t_x0, t_x1 = size * 0.16, size * 0.84
bar_y0, bar_y1 = size * 0.28, size * 0.47
stem_x0, stem_x1 = size * 0.42, size * 0.58
stem_y0, stem_y1 = size * 0.47, size * 0.78
lr = size * 0.04
for y in range(size):
t = y / size
or_ = lerp(0xff, 0xee, t)
og = lerp(0xa2, 0x5c, t)
ob = lerp(0x38, 0x0d, t)
# barra
for x in range(size):
if in_rrect(x, y, t_x0, bar_y0, t_x1, bar_y1, lr):
set_px(x, y, or_, og, ob)
# haste
for x in range(size):
if in_rrect(x, y, stem_x0, stem_y0, stem_x1, stem_y1, lr):
if x < stem_x0 + lr or x > stem_x1 - lr or y > stem_y1 - lr:
if in_rrect(x, y, stem_x0, stem_y0, stem_x1, stem_y1, lr):
set_px(x, y, or_, og, ob)
else:
set_px(x, y, or_, og, ob)
# ── Listras de tigre (faixas diagonais escuras) ──
stripes = [
(0.20, 0.36, 0.58, 0.76), # haste (diagonal)
(0.34, 0.50, 0.26, 0.42),
(0.50, 0.66, 0.22, 0.40),
(0.22, 0.40, 0.62, 0.82),
]
# Converte faixa reta em diagonal: x' = x + (y - bar_y0) * slant
slant = 0.35
for (x0f, x1f, y0f, y1f) in stripes:
x0, x1 = size * x0f, size * x1f
y0, y1 = size * y0f, size * y1f
for y in range(int(y0), int(y1)):
shift = (y - y0) * slant
if shift < 0:
continue
sx0, sx1 = x0 + shift, x1 + shift
for x in range(int(sx0), int(sx1)):
if x < 0 or x >= size:
continue
i = (y * size + x) * 4
# cor escura translúcida (mistura manual p/ lerp com canal alpha)
af = 0.78
px[i] = lerp(px[i], 0x0c, af)
px[i+1] = lerp(px[i+1], 0x0a, af)
px[i+2] = lerp(px[i+2], 0x06, af)
px[i+3] = max(px[i+3], int(255 * 0.85))
return px
def main():
out = sys.argv[1] if len(sys.argv) > 1 else "/tmp/tigre_icon_1024.png"
px = draw_icon(SIZE)
with open(out, "wb") as f:
f.write(create_png(SIZE, SIZE, px))
print(f"OK: {out} ({SIZE}x{SIZE})")
if __name__ == "__main__":
main()
+82
View File
@@ -0,0 +1,82 @@
#!/usr/bin/env python3
"""Compara o pixel medio de dois PNGs (palette grossa, suficiente p/ conferir se o icns e o mesmo desenho)."""
import struct
import sys
import zlib
def read_png(path):
d = open(path, 'rb').read()
assert d[:8] == b'\x89PNG\r\n\x1a\n', f'nao e PNG: {path}'
pos, w, h = 8, None, None
idat = b''
while pos < len(d):
ln = struct.unpack('>I', d[pos:pos+4])[0]
typ = d[pos+4:pos+8]
data = d[pos+8:pos+8+ln]
if typ == b'IHDR':
w, h = struct.unpack('>II', data[:8])
elif typ == b'IDAT':
idat += data
pos += 12 + ln
if typ == b'IEND':
break
raw = zlib.decompress(idat)
assert w is not None
stride = w * 4 + 1
prev = bytearray(w * 4)
out = bytearray()
for y in range(h):
row = bytearray(raw[y*stride:(y+1)*stride])
f = row[0]
line = bytearray(row[1:])
for x in range(w):
for k in range(4):
i = x * 4 + k
a = line[i-4] if x > 0 and k < 3 else 0 # aprox: usa vizinho p/ filtros
b = prev[i]
c = line[i-4] if x > 0 else 0
if f == 1:
v = (line[i] + (line[i-4] if x > 0 else 0)) & 255
elif f == 2:
v = (line[i] + prev[i]) & 255
elif f == 3:
v = (line[i] + ((a + b) >> 1)) & 255
elif f == 4:
p = a + b - c
pa, pb, pc = abs(p-a), abs(p-b), abs(p-c)
pr = a if (pa <= pb and pa <= pc) else (b if pb <= pc else c)
v = (line[i] + pr) & 255
else:
v = line[i]
line[i] = v
out += line
prev = line
return w, h, out
def average(path):
w, h, px = read_png(path)
n = w * h
r = sum(px[i] for i in range(0, len(px), 4)) // n
g = sum(px[i] for i in range(1, len(px), 4)) // n
b = sum(px[i] for i in range(2, len(px), 4)) // n
opaque = sum(1 for i in range(3, len(px), 4) if px[i] > 200) * 100 // n
return w, h, r, g, b, f'{opaque}% opaco'
def main():
icns_png = sys.argv[1] # 1024 extraido do .icns
orig_png = sys.argv[2] # PNG original do usuario
a = average(icns_png)
b = average(orig_png)
print(f'icns 1024 -> {a}')
print(f'original -> {b}')
# Mesmo desenho se cores medias proximas e ambos coloridos/transparentes com padrao similar
close = abs(a[2]-b[2]) <= 24 and abs(a[3]-b[3]) <= 24 and abs(a[4]-b[4]) <= 24
print('MATCH (mesmo desenho)' if close else 'DIFF — verificar manualmente')
sys.exit(0 if close else 1)
if __name__ == '__main__':
main()
+112
View File
@@ -0,0 +1,112 @@
#!/bin/bash
# Tigre (codeclass) - App GUI SwiftUI: build + empacota .app + abre.
# Sobe um nivel: o script vive em admin/, o projeto e a pasta pai.
#
# Uso:
# admin/run-app.command # build + indexa RAG + abre app
# TIGRE_SKIP_RAG_INDEX=1 admin/run-app.command # pula a reindexação do RAG
# TIGRE_APP_CONFIG=release admin/run-app.command# build release (otimizado)
#
# O que faz:
# 1) build do TigreAppUI (via make-app.command) e monta o bundle Tigre.app
# em ~/Applications/Tigre.app — um .app no macOS é uma pasta; a cada run
# nós SOBRESCREVEMOS o bundle (sem "instalar/desinstalar" nada no sistema).
# 2) reindexa o RAG do codeclass (rag/index_tigre.sh) — o build acabou de
# atualizar Sources/; pode ser pulado com TIGRE_SKIP_RAG_INDEX=1
# 3) finaliza instancia anterior do app GUI, se houver
# 4) abre o Tigre.app com `open` → macOS registra no LaunchServices: o app
# aparece no Dock com ícone, Cmd+Tab, menu no topo e nome "Tigre".
#
# Nao conflita com deploy-codeclass.command (servidor web na porta 5050) —
# os dois podem rodar juntos e enxergam os mesmos projetos.
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
CLASSDIR="$PROJECT_DIR/codeclass"
APP_DIR="${TIGRE_APP_DIR:-$HOME/Applications/Tigre.app}"
APP_BIN="$APP_DIR/Contents/MacOS/Tigre"
LOG="/tmp/tigre-appui.log"
echo "============================================================"
echo " Tigre (codeclass) :: App GUI SwiftUI"
echo " Pasta: $PROJECT_DIR"
echo " App bundle: $APP_DIR"
echo "============================================================"
echo
# 1) Empacotar/atualizar o bundle .app (faz o swift build internamente)
echo "[1/3] Build + bundle .app (make-app.command)..."
"$SCRIPT_DIR/make-app.command" || exit 1
echo
# 2) Reindexar o RAG do codeclass (rag_tigre) — passo best effort: falha de
# indexação (ex.: túnel SSH fora) NÃO impede o app de subir.
RAG_INDEXER="$PROJECT_DIR/rag/index_tigre.sh"
RAG_LOG="/tmp/tigre-rag-index.log"
if [ "${TIGRE_SKIP_RAG_INDEX:-0}" = "1" ]; then
echo "[2/3] Reindexação do RAG pulada (TIGRE_SKIP_RAG_INDEX=1)."
elif [ ! -x "$RAG_INDEXER" ]; then
echo "[2/3] AVISO: rag/index_tigre.sh não encontrado — reindexação pulada."
else
echo "[2/3] Reindexando o RAG do codeclass (rag/index_tigre.sh)..."
if "$RAG_INDEXER" > "$RAG_LOG" 2>&1; then
grep -E 'OK:|gravado' "$RAG_LOG" | tail -2 | sed 's/^/ /'
echo " RAG indexado."
else
echo " AVISO: reindexação do RAG falhou (o app segue). Log: $RAG_LOG"
tail -3 "$RAG_LOG" | sed 's/^/ /'
fi
fi
echo
# 3) Encerrar instancia anterior do app GUI — tanto do bundle (.app) quanto do
# binario solto do .build (debug/release), senao sobram instancias antigas
# vivas e o `open -n` abre uma nova por cima.
echo "[3/3] Encerrando instâncias anteriores do Tigre (se houver)..."
pkill -f "$APP_BIN" 2>/dev/null || true # instancia do bundle .app
pkill -f "TigreAppUI" 2>/dev/null || true # binario solto do .build (debug/release)
pkill -x "Tigre" 2>/dev/null || true # qualquer processo "Tigre" restante
# Espera o processo encerrar de verdade (SIGTERM pode ser ignorado pelo app)
for _ in 1 2 3 4 5; do
pgrep -f "TigreAppUI|$APP_BIN" >/dev/null 2>&1 || break
sleep 1
done
# Forca a saida se ainda estiver vivo
pkill -9 -f "$APP_BIN" 2>/dev/null || true
pkill -9 -f "TigreAppUI" 2>/dev/null || true
pkill -9 -x "Tigre" 2>/dev/null || true
sleep 1
true
# 4) Abrir o app via LaunchServices (`open`) — não é nohup de binário solto.
# TIGRE_PROJECT_ROOT garante que o app ache o puente Python do legado.
echo " Abrindo o Tigre.app..."
TIGRE_PROJECT_ROOT="$PROJECT_DIR" open -n "$APP_DIR"
echo
# Confere se o processo do bundle subiu
sleep 3
if pgrep -f "$APP_BIN" >/dev/null 2>&1; then
echo "============================================================"
echo " Tigre no ar. Ele aparece no Dock com icon e nome 'Tigre'."
echo " Para encerrar: Cmd+Q no app | pkill -f '$APP_BIN'"
echo " Para remover: rm -rf '$APP_DIR'"
echo "============================================================"
else
echo "============================================================"
echo " AVISO: nao detectamos o processo do app. Log do ultimo launch:"
echo "------------------------------------------------------------"
tail -20 "$LOG" 2>/dev/null || true
echo "============================================================"
fi
# Fecha a janela do Terminal que rodou o .command (padrao G-ART run_app):
# o app ja esta desacoplado, o script so encerra antes do aviso de
# "finalizar processos nesta janela".
(
sleep 2
osascript -e 'tell application "Terminal" to close (every window whose name contains "run-app")' >/dev/null 2>&1
) &
exit 0
+67
View File
@@ -0,0 +1,67 @@
#!/bin/bash
# Doza Assist - Testes automatizados (macOS)
# Sobe um nivel: o script vive em admin/, o projeto e a pasta pai
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
APP_DIR="$PROJECT_DIR/code"
VENV_PY="$APP_DIR/.venv/bin/python3"
# Cores (so quando a saida e um terminal)
if [ -t 1 ]; then
C_CYAN=$'\033[36m'; C_GREEN=$'\033[32m'; C_RED=$'\033[31m'
C_YELLOW=$'\033[33m'; C_OFF=$'\033[0m'
else
C_CYAN=''; C_GREEN=''; C_RED=''; C_YELLOW=''; C_OFF=''
fi
echo
echo "${C_CYAN}============================================================${C_OFF}"
echo "${C_CYAN} DOZA ASSIST - TESTES AUTOMATIZADOS${C_OFF}"
echo "${C_CYAN}============================================================${C_OFF}"
echo
if [ ! -x "$VENV_PY" ]; then
echo "${C_RED}ERRO: ambiente Python nao encontrado:${C_OFF}"
echo "${C_YELLOW}$VENV_PY${C_OFF}"
echo
echo "Execute primeiro a instalacao do projeto para criar a pasta .venv:"
echo " admin/install.command"
echo
exit 1
fi
cd "$APP_DIR" || exit 1
export PYTHONUTF8=1
# pytest nao consta em requirements.txt; instala sob demanda no venv do projeto
if ! "$VENV_PY" -c "import pytest" >/dev/null 2>&1; then
echo "${C_YELLOW}pytest nao encontrado no venv. Instalando...${C_OFF}"
if ! "$VENV_PY" -m pip install -q pytest; then
echo "${C_RED}ERRO: falha ao instalar o pytest.${C_OFF}"
exit 1
fi
echo "${C_GREEN}pytest instalado.${C_OFF}"
echo
fi
echo "${C_CYAN}Cada teste aprovado aparecera abaixo como PASSED em verde.${C_OFF}"
echo "${C_CYAN}Falhas aparecerao como FAILED em vermelho, com o motivo resumido.${C_OFF}"
echo
"$VENV_PY" -m pytest -vv --tb=short -ra --color=yes "$@"
TEST_EXIT=$?
echo
echo "============================================================"
if [ "$TEST_EXIT" -eq 0 ]; then
echo "${C_GREEN} TODOS OS TESTES FORAM APROVADOS.${C_OFF}"
echo "============================================================"
echo
exit 0
fi
echo "${C_RED} EXISTEM TESTES COM FALHA. Veja os itens FAILED acima.${C_OFF}"
echo "============================================================"
echo
exit "$TEST_EXIT"