first commit

This commit is contained in:
neoricalex 2026-03-04 06:09:54 +01:00
commit 0bde6a4808
10 changed files with 381 additions and 0 deletions

View File

@ -0,0 +1,7 @@
runs:
using: composite
steps:
- name: "Install UV"
shell: bash
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh

View File

@ -0,0 +1,48 @@
name: Python Code Quality
on: [push]
jobs:
lock_file:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: uv lock --locked
linting:
runs-on: ubuntu-latest
needs: [lock_file]
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: uvx ruff check .
formatting:
runs-on: ubuntu-latest
needs: [lock_file]
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: uvx ruff format --check .
type_consistency:
runs-on: ubuntu-latest
needs: [lock_file]
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: uv run pyright .
tests:
runs-on: ubuntu-latest
needs: [lock_file]
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: uv run pytest -v --durations=0 --cov --cov-report=xml
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
build:
runs-on: [ubuntu-latest]
needs: [linting, formatting, type_consistency, tests]
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- run: uv build

60
.gitignore vendored Normal file
View File

@ -0,0 +1,60 @@
# === sub-módulos clonados ===
src/modules/
.cache/
# === Autotools build artefacts ===
Makefile
Makefile.in
aclocal.m4
autom4te.cache/
config.log
config.status
configure
depcomp
install-sh
missing
py-compile
stamp-h1
# === Build & dist directories ===
/build/
/dist/
!/dist/releases/
!/dist/releases/*
*.tar.gz
*.tar.bz2
*.zip
# === Python cache & venv ===
__pycache__/
*.pyc
*.pyo
*.pyd
*.egg-info/
.eggs/
venv/
.env/
.venv/
# === Editor / OS junk ===
*.swp
*.swo
*.bak
*.tmp
*~
.DS_Store
Thumbs.db
# === Logs ===
*.log
nohup.out
# === IDE / workspace ===
.vscode/
.idea/
*.iml
# === Backup copies ===
*.old
*.orig
*.rej

1
.python-version Normal file
View File

@ -0,0 +1 @@
3.12

125
Makefile.am Normal file
View File

@ -0,0 +1,125 @@
SUBDIRS = src
# ===========================
# Caminhos e artefactos
# ===========================
TOP_DIR = $(shell pwd)
DIST_DIR = $(TOP_DIR)/dist
BUILD_DIR = $(TOP_DIR)/build
GIT_VER = $(shell git describe --tags --always --dirty 2>/dev/null || echo "0.1-dev")
SRC_TAR = $(DIST_DIR)/myhomelab-$(GIT_VER)-src.tar.gz
# ===========================
# Configurações de Git
# ===========================
GIT_USER ?= "neo.webmaster.2@gmail.com"
GIT_EMAIL ?= "neo.webmaster.2@gmail.com"
GIT_REMOTE ?= "origin"
GIT_BRANCH ?= "main"
COMMIT_MSG ?= "Auto-commit via make git"
# ===========================
# Alvos principais
# ===========================
.PHONY: all tarball git release run clean-local check-remote
all: $(DIST_DIR)
$(DIST_DIR):
@mkdir -p $(DIST_DIR)
# ===========================
# Empacotamento do código-fonte
# ===========================
tarball: $(SRC_TAR)
$(SRC_TAR):
@echo "[TAR] Empacotando código-fonte (versão $(GIT_VER))..."
@mkdir -p "$(DIST_DIR)" "$(BUILD_DIR)"
cd "$(TOP_DIR)" && tar \
--exclude="$(notdir $(SRC_TAR))" \
--exclude="$(DIST_DIR)" \
--exclude="$(BUILD_DIR)" \
--exclude='*/__pycache__' \
--exclude='*/.venv' \
--exclude='*/venv' \
--exclude='*.pyc' \
--exclude='*.pyo' \
--exclude='*.o' \
--exclude='*.a' \
--exclude='*.so' \
-czf "$(SRC_TAR)" .
@echo "[✔] Tarball gerado em $(SRC_TAR)"
# ===========================
# Git (commit + push)
# ===========================
git: check-remote
@echo "📦 Commit automático → Gitea"
@git config user.name $(GIT_USER)
@git config user.email $(GIT_EMAIL)
@git rev-parse --abbrev-ref HEAD >/dev/null 2>&1 || true
@git add -A
@git commit -m "$$(echo '$(COMMIT_MSG)')" || echo "Nenhuma modificação para commitar."
@git push $(GIT_REMOTE) $(GIT_BRANCH)
# ===========================
# Release (Tarball + Tag)
# ===========================
release: tarball check-remote
@echo "🚀 Publicando build em dist/releases (versão: $(GIT_VER))"
@mkdir -p $(DIST_DIR)/releases
@cp $(SRC_TAR) $(DIST_DIR)/releases/ 2>/dev/null || echo "⚠️ Nenhum tarball encontrado. Execute 'make tarball' primeiro."
@echo "📦 Adicionando releases ignoradas (forçado)"
@git add -f $(DIST_DIR)/releases/* 2>/dev/null || echo "⚠️ Nenhum artefato novo para adicionar."
@git commit -m "Build automático: release $(GIT_VER)" || echo "Nenhum ficheiro novo para commitar."
@git push origin main
@TAG="$(GIT_VER)"; \
if git rev-parse "$$TAG" >/dev/null 2>&1; then \
echo "⚠️ Tag $$TAG já existente."; \
else \
echo "🏷 Criando tag $$TAG"; \
git tag -a "$$TAG" -m "Release automática $$TAG"; \
git push origin "$$TAG"; \
fi
# ===========================
# Git Remote (HTTPS → SSH Auto-Fix)
# ===========================
check-remote:
@REMOTE_URL=$$(git remote get-url $(GIT_REMOTE)); \
if echo $$REMOTE_URL | grep -q '^https://gitea\.neoricalex\.com'; then \
echo "⚠️ Repositório configurado com HTTPS:"; \
echo " $$REMOTE_URL"; \
echo "🔄 Convertendo para SSH (porta 2222)..."; \
SSH_URL=$$(echo $$REMOTE_URL | sed -E 's|https://gitea\.neoricalex\.com[:/]+|ssh://git@gitea.neoricalex.com:2222/|'); \
git remote set-url $(GIT_REMOTE) $$SSH_URL; \
echo "✅ Remote atualizado para:"; \
git remote -v; \
else \
echo "✅ Remote SSH já configurado:"; \
git remote -v | grep $(GIT_REMOTE); \
fi; \
echo "🔍 Testando conectividade SSH com Gitea..."; \
if ssh -T git@gitea.neoricalex.com -p 2222 2>&1 | grep -q "successfully authenticated"; then \
echo "✅ Conexão SSH funcional com Gitea."; \
else \
echo "❌ Falha na autenticação SSH com Gitea."; \
echo " Verifique a chave em ~/.ssh/id_ed25519.pub e nas SSH Keys do Gitea."; \
exit 1; \
fi
# ===========================
# Teste
# ===========================
run:
@python3 src/root/__main__.py
# ===========================
# Limpeza
# ===========================
clean-local:
@echo "[CLEAN] Removendo diretórios temporários..."
@rm -rf $(BUILD_DIR)
@find $(DIST_DIR) -maxdepth 1 -type f ! -path "$(DIST_DIR)/releases/*" -delete 2>/dev/null || true
@echo "[✔] Limpeza concluída (releases preservadas)"

50
README.md Normal file
View File

@ -0,0 +1,50 @@
```
myhomelab/
├─ configure.ac
├─ Makefile.am
├─ README.md
├─ pyproject.toml # uv + ruff + (pytest)
├─ uv.lock
├─ src/
│ └─ neuro/
│ ├─ __init__.py
│ ├─ cli.py # entrypoints (tui / bench / repl)
│ │
│ ├─ tui/
│ │ ├─ app.py # Textual App
│ │ ├─ screens.py # screens/modals
│ │ ├─ widgets.py # componentes reutilizáveis
│ │ └─ state.py # estado e store (sem IA aqui)
│ │
│ ├─ engine/
│ │ ├─ __init__.py
│ │ ├─ session.py # Session, Chat/Prompt state
│ │ └─ runtime.py # “orquestração” do loop (streaming, cancel)
│ │
│ ├─ ai/
│ │ ├─ __init__.py
│ │ ├─ config.py # dataclasses: dims, vocab, layers, seed
│ │ ├─ tokenizer.py # tokenize/detokenize
│ │ ├─ embeddings.py # tok->vec, pos enc
│ │ ├─ transformer.py # forward() (minimo)
│ │ ├─ head.py # logits/probs
│ │ ├─ sampling.py # greedy, top-k, top-p, temp
│ │ └─ model.py # Model = cola tudo (tokenize->sample)
│ │
│ ├─ utils/
│ │ ├─ logging.py
│ │ ├─ rng.py
│ │ └─ perf.py
│ │
│ └─ data/
│ ├─ vocab.json # opcional no MVP
│ └─ tiny_weights.npz # opcional (se quiseres pesos fixos)
├─ tests/
│ ├─ test_tokenizer.py
│ ├─ test_sampling.py
│ └─ test_transformer_shapes.py
└─ tools/
├─ bench.py # microbench do forward/sampling
└─ export_vocab.py
```

37
configure.ac Normal file
View File

@ -0,0 +1,37 @@
AC_INIT([MYHOMELAB], [NEO_VERSION], [https://gitea.neoricalex.com/neo/myhomelab.git])
# ===========================
# Diretórios base
# ===========================
AC_CONFIG_AUX_DIR([.])
AC_SUBST([TOP_DIR], ['$(CURDIR)'])
AC_SUBST([BUILD_DIR], ['$(CURDIR)/build'])
AC_SUBST([DIST_DIR], ['$(CURDIR)/dist'])
# ===========================
# Versão dinâmica (Git)
# ===========================
m4_define([NEO_VERSION],
m4_esyscmd_s([git describe --tags --always --dirty 2>/dev/null || echo "0.1-dev"]))
AC_SUBST([NEO_VERSION])
# Caminho do tarball dinâmico (protegido contra M4 expansion)
AC_SUBST([SRC_TAR],
['$(CURDIR)/dist/myhomelab-@NEO_VERSION@-src.tar.gz'])
# ===========================
# Automake + Python
# ===========================
AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip])
AM_PATH_PYTHON([3.0])
# ===========================
# Arquivos Makefile
# ===========================
AC_CONFIG_FILES([
Makefile
src/Makefile
src/neuro/Makefile
])
AC_OUTPUT

24
pyproject.toml Normal file
View File

@ -0,0 +1,24 @@
[project]
name = "neuro"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
authors = [
{ name = "neoricalex", email = "neo.webmaster.2@gmail.com" }
]
requires-python = ">=3.12"
dependencies = []
[project.scripts]
neuro = "neuro:main"
[build-system]
requires = ["uv_build>=0.10.8,<0.11.0"]
build-backend = "uv_build"
[dependency-groups]
dev = [
"pyright>=1.1.408",
"pytest>=9.0.2",
"pytest-cov>=7.0.0",
]

18
src/Makefile.am Normal file
View File

@ -0,0 +1,18 @@
SUBDIRS = root
bin_SCRIPTS = neuro
CLEANFILES = $(bin_SCRIPTS)
EXTRA_DIST = neuro.in
# ===========================
# Substituição dinâmica
# ===========================
neuro: neuro.in Makefile
@which git >/dev/null || { echo "⚠️ Git não encontrado — instale-o manualmente."; exit 1; }
sed \
-e 's,[@]pythondir[@],$(pythondir),g' \
-e 's,[@]PACKAGE[@],$(PACKAGE),g' \
-e 's,[@]VERSION[@],$(VERSION),g' \
< $(srcdir)/neuro.in > neuro
chmod +x neuro

11
src/neuro.in Normal file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env python
import sys
sys.path.insert(1, '@pythondir@')
from bootstrap import Application
if __name__ == "__main__":
app = Application(package="@PACKAGE@", version="@VERSION@")
app.run()